Merge branch cairo:master into fix-vs

This commit is contained in:
Dan Rosser 2025-07-18 00:54:37 +10:00
commit b6b1c535f1
337 changed files with 4015 additions and 4819 deletions

View file

@ -2,7 +2,7 @@
include:
- template: 'Workflows/Branch-Pipelines.gitlab-ci.yml'
- project: 'freedesktop/ci-templates'
ref: '7811ba9814a3bad379377241c6c6b62d78b20eac'
ref: '98b1218f146a1ec96d65e3ce0041f9a6ec5cb5e6'
file: '/templates/fedora.yml'
# From https://gitlab.freedesktop.org/freedesktop/ci-templates/-/blob/master/src/gitlab-ci.tmpl
@ -15,20 +15,29 @@ workflow:
variables:
FDO_UPSTREAM_REPO: 'cairo/cairo'
FDO_DISTRIBUTION_VERSION: '38'
FDO_DISTRIBUTION_TAG: '2023-04-29.1'
FDO_DISTRIBUTION_VERSION: '40'
FDO_DISTRIBUTION_TAG: '2025-03-12-android.0'
# TODO: should probably get its own image at some point instead of reusing the GStreamer one
# See https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/.gitlab-image-tags.yml for latest
WINDOWS_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2023-04-21.0-main"
# (This one is from the lastest stable branch since it's likely to stay around unchanged for longer)
WINDOWS_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer/amd64/windows:2025-03-12.0-1.26"
DEFAULT_MESON_ARGS: >
--default-library=both
RUST_STABLE: "1.85.0"
RUSTUP_VERSION: "1.28.1"
ANDROID_HOME: "/android/sdk"
ANDROID_NDK_HOME: "/android/ndk"
stages:
- prep
- build
- test
- analysis
- deploy
# Global CI policy: This can be used to configure global behaviour our our jobs
default:
@ -60,13 +69,17 @@ fedora image:
extends:
- '.fdo.container-build@fedora'
stage: 'prep'
tags:
- kvm
variables:
FDO_DISTRIBUTION_PACKAGES: >
binutils-gold
meson
ninja-build
ccache
gcc
g++
gperf
zlib-devel
expat-devel
libpng-devel
@ -84,25 +97,92 @@ fedora image:
systemd-devel
systemd-udev
expat-devel
autoconf
automake
make
which
libtool
diffutils
xorg-x11-server-Xvfb
dejavu-sans-fonts
dejavu-sans-mono-fonts
dejavu-serif-fonts
google-noto-emoji-color-fonts
google-noto-sans-vf-fonts
fonttools
unzip
util-linux
poppler-utils
python3-pip
clang
clang-analyzer
clang-tools-extra
compiler-rt
libasan
libubsan
llvm
wget
FDO_DISTRIBUTION_EXEC: >-
bash .gitlab-ci/install-rust.sh --rustup-version ${RUSTUP_VERSION} \
--stable ${RUST_STABLE} \
--arch x86_64-unknown-linux-gnu &&
bash .gitlab-ci/install-rust-tools.sh &&
bash .gitlab-ci/install-grcov.sh &&
bash .gitlab-ci/install-android-toolchain.sh $ANDROID_HOME $ANDROID_NDK_HOME &&
rm -rf /root/.cargo /root/.cache # cleanup compilation dirs; binaries are installed now
.test fedora meson:
.build fedora:
extends:
- '.fdo.distribution-image@fedora'
- '.ccache_setup'
stage: 'build'
variables:
MESON_ARGS: >
${DEFAULT_MESON_ARGS}
${EXTRA_MESON_ARGS}
--werror
CFLAGS: '-Wno-error=deprecated-declarations'
script:
- meson setup ${MESON_ARGS} builddir
- meson compile -C builddir
# Run test scripts
- mkdir builddir/src/.libs
- touch builddir/src/.libs/libfoo.so
# Run all the tests, except for the big test executable which
# gets run separately
- meson test -C builddir --no-suite=slow --print-errorlogs
- meson install -C builddir
artifacts:
expire_in: "7 days"
when: "always"
paths:
- "*"
fedora build shared:
extends:
- '.build fedora'
variables:
EXTRA_MESON_ARGS: '--default-library=shared'
fedora build static:
extends:
- '.build fedora'
variables:
EXTRA_MESON_ARGS: '--default-library=static'
fedora build clang:
extends:
- '.build fedora'
variables:
EXTRA_MESON_ARGS: '--default-library=shared'
script:
- export CC=clang
- meson setup ${MESON_ARGS} builddir
- meson compile -C builddir
.test fedora:
dependencies:
- 'fedora meson build'
- 'fedora build shared'
needs:
- 'fedora meson build'
- 'fedora build shared'
extends:
- '.fdo.distribution-image@fedora'
- '.ccache_setup'
@ -119,14 +199,14 @@ fedora image:
- "builddir/test/**/*.cs"
- "builddir/test/**/*.trace"
fedora meson build check-refs.sh:
extends: '.test fedora meson'
fedora build check-refs.sh:
extends: '.test fedora'
script:
# Check for duplicate reference images
- ./test/check-refs.sh "$(pwd)/builddir/test/pdiff/perceptualdiff"
test fedora meson pdf:
extends: '.test fedora meson'
test fedora pdf:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_pdf_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-pdf-argb32.txt)
- export CAIRO_TEST_IGNORE_pdf_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-pdf-rgb24.txt)
@ -134,8 +214,8 @@ test fedora meson pdf:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson ps2:
extends: '.test fedora meson'
test fedora ps2:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_ps2_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-ps2-argb32.txt)
- export CAIRO_TEST_IGNORE_ps2_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-ps2-rgb24.txt)
@ -144,8 +224,8 @@ test fedora meson ps2:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson ps3:
extends: '.test fedora meson'
test fedora ps3:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_ps3_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-ps3-argb32.txt)
- export CAIRO_TEST_IGNORE_ps3_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-ps3-rgb24.txt)
@ -154,8 +234,8 @@ test fedora meson ps3:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson script:
extends: '.test fedora meson'
test fedora script:
extends: '.test fedora'
script:
- export CAIRO_TEST_UGLY_HACK_TO_SOMETIMES_IGNORE_SCRIPT_XCB_HUGE_IMAGE_SHM=1
- export CAIRO_TEST_IGNORE_script_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-script-argb32.txt)
@ -163,8 +243,8 @@ test fedora meson script:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson image:
extends: '.test fedora meson'
test fedora image:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_image_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-image-argb32.txt)
- export CAIRO_TEST_IGNORE_image_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-image-rgb24.txt)
@ -173,8 +253,8 @@ test fedora meson image:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson recording:
extends: '.test fedora meson'
test fedora recording:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_recording_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-recording-argb32.txt)
- export CAIRO_TEST_IGNORE_recording_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-recording-rgb24.txt)
@ -182,8 +262,8 @@ test fedora meson recording:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson svg:
extends: '.test fedora meson'
test fedora svg:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_svg11_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-svg11-argb32.txt)
- export CAIRO_TEST_IGNORE_svg11_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-svg11-rgb24.txt)
@ -195,8 +275,8 @@ test fedora meson svg:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson xcb:
extends: '.test fedora meson'
test fedora xcb:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_xcb_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-xcb-argb32.txt)
- export CAIRO_TEST_IGNORE_xcb_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-xcb-rgb24.txt)
@ -209,8 +289,8 @@ test fedora meson xcb:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
test fedora meson xlib:
extends: '.test fedora meson'
test fedora xlib:
extends: '.test fedora'
script:
- export CAIRO_TEST_IGNORE_xlib_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-xlib-argb32.txt)
- export CAIRO_TEST_IGNORE_xlib_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-xlib-rgb24.txt)
@ -221,39 +301,7 @@ test fedora meson xlib:
- export srcdir=../../test
- (cd builddir/test && xvfb-run ./cairo-test-suite)
fedora meson build:
extends:
- '.fdo.distribution-image@fedora'
- '.ccache_setup'
stage: 'build'
variables:
MESON_ARGS: >
${DEFAULT_MESON_ARGS}
script:
- export CFLAGS="-Werror -Wno-error=deprecated-declarations"
- meson builddir ${MESON_ARGS}
- ninja -C builddir
# Run test scripts
- mkdir builddir/src/.libs
- touch builddir/src/.libs/libfoo.so
# Run all the tests, except for the big test executable which
# gets run separately
- meson test -C builddir --no-suite=slow --print-errorlogs
# TODO: These aren't set up as Meson tests yet
- (cd doc/public && bash "check-doc-syntax.sh")
# FIXME: The following line really needs gtk-doc to run first
- (cd doc/public && DOC_MODULE=cairo bash "check-doc-coverage.sh")
- ninja -C builddir install
artifacts:
expire_in: "7 days"
when: "always"
paths:
- "*"
meson mingw-32 build:
mingw-32 build:
extends:
- '.fdo.distribution-image@fedora'
stage: 'build'
@ -264,7 +312,8 @@ meson mingw-32 build:
script:
- mkdir builddir
- cd builddir
- mingw32-meson --default-library=both
# Test building with FreeType enabled and Fontconfig disabled
- mingw32-meson --default-library=both -Dfontconfig=disabled
- ninja install
artifacts:
expire_in: "7 days"
@ -272,7 +321,7 @@ meson mingw-32 build:
paths:
- 'builddir/meson-logs/'
meson mingw-64 build:
mingw-64 build:
extends:
- '.fdo.distribution-image@fedora'
stage: 'build'
@ -292,7 +341,7 @@ meson mingw-64 build:
- 'builddir/meson-logs/'
# Based on https://gitlab.freedesktop.org/gstreamer/gstreamer/-/blob/main/.gitlab-ci.yml (.build windows)
.build meson windows:
.build windows:
image: $WINDOWS_IMAGE
stage: 'build'
tags:
@ -309,11 +358,8 @@ meson mingw-64 build:
-Dzlib=enabled
${EXTRA_MESON_ARGS}
before_script:
# Make sure meson is up to date, so we don't need to rebuild the image with each release
# FIXME: don't update meson version for now, since there seems to be a bug
# in newer meson versions (0.63.3 at the time of writing) where it can't
# find some hash file and then meson subprojects update fails)
# - pip3 install -U meson
# Make sure meson is up to date, latest fontconfig requires a newer Meson than what's on the image
- pip3 install -U meson
script:
# Make sure powershell exists on errors
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-6
@ -335,29 +381,35 @@ meson mingw-64 build:
meson subprojects update --reset &&
meson build $env:MESON_ARGS &&
ninja -C build"
artifacts:
expire_in: "7 days"
when: "always"
paths:
- 'build/meson-logs/'
meson vs2019 shared amd64:
extends: '.build meson windows'
vs2019 shared amd64:
extends: '.build windows'
variables:
ARCH: 'amd64'
EXTRA_MESON_ARGS: '--default-library=shared'
meson vs2019 static amd64:
extends: '.build meson windows'
vs2019 static amd64:
extends: '.build windows'
variables:
ARCH: 'amd64'
EXTRA_MESON_ARGS: '--default-library=static'
meson vs2019 shared x86:
extends: '.build meson windows'
vs2019 shared x86:
extends: '.build windows'
variables:
ARCH: 'x86'
EXTRA_MESON_ARGS: '--default-library=shared'
meson android arm64 fedora:
android arm64 fedora:
# TODO: should probably build our own image here some day
# See https://gitlab.freedesktop.org/gstreamer/gstreamer/container_registry/7689 for current images
image: 'registry.freedesktop.org/gstreamer/gstreamer/amd64/android-fedora:2020-10-22.0-master'
extends:
- '.fdo.distribution-image@fedora'
stage: 'build'
artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_SHA}"
@ -365,41 +417,14 @@ meson android arm64 fedora:
when: 'always'
paths:
- "build/meson-logs/*.txt"
before_script:
- dnf install -y python3-pip gcc ninja-build gperf
- pip3 install --user meson
script:
- export PATH="$HOME/.local/bin:$PATH"
- |
cat > android-cross-file.txt <<EOF
[constants]
ndk_path = '/android/ndk'
toolchain = ndk_path + '/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android'
api = '28'
[host_machine]
system = 'android'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
[properties]
sys_root = ndk_path + '/sysroot'
c_link_args = ['-fuse-ld=gold']
cpp_link_args = ['-fuse-ld=gold']
[binaries]
c = toolchain + api + '-clang'
cpp = toolchain + api + '-clang++'
ar = toolchain + '-ar'
strip = toolchain + '-strip'
EOF
- meson setup --cross-file android-cross-file.txt -Dpixman:a64-neon=disabled build
- meson setup --cross-file .gitlab-ci/android-cross-file.txt -Dpixman:a64-neon=disabled build
- meson compile --verbose -C build
meson macOS:
macOS arm64:
image: "registry.freedesktop.org/gstreamer/cerbero/macos-arm64/15-sequoia:2024-10-28.2"
tags:
- gst-macos-12.3
- gst-mac-arm
stage: 'build'
artifacts:
when: 'always'
@ -420,15 +445,19 @@ meson macOS:
- cp dejavu-fonts-ttf-2.37/ttf/*.ttf /Library/Fonts
# Update pip
- pip3 install --upgrade pip
# FIXME
- export PATH=${PATH}:/Users/gst-ci/Library/Python/3.9/bin
# Make sure meson is up to date
- pip3 install -U meson
# Need to install certificates for Python
- pip3 install --upgrade certifi
# Anther way to install certificates
- open /Applications/Python\ 3.8/Install\ Certificates.command
#### Another way to install certificates
####- open /Applications/Python\ 3.8/Install\ Certificates.command
# Get ninja
- pip3 install -U ninja
script:
# FIXME
- export PATH=${PATH}:/Users/gst-ci/Library/Python/3.9/bin
- CERT_PATH=$(python3 -m certifi) && export SSL_CERT_FILE=${CERT_PATH} && export REQUESTS_CA_BUNDLE=${CERT_PATH}
# pixman region-test fails to link on macOS
- meson setup -Dpixman:tests=disabled build
@ -438,3 +467,59 @@ meson macOS:
- export CAIRO_TEST_IGNORE_quartz_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-quartz-rgb24.txt)
- export CAIRO_TEST_TARGET=quartz
- (cd build/test && srcdir=../../test ./cairo-test-suite)
# Run static analysis.
static-scan:
stage: 'analysis'
extends:
- '.fdo.distribution-image@fedora'
variables:
MESON_ARGS: >
--buildtype=debug
script:
- meson setup ${MESON_ARGS} _scan_build .
- ninja -C _scan_build scan-build
artifacts:
name: "cairo-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
when: always
paths:
- "_scan_build/meson-logs/scanbuild"
coverage:
stage: 'analysis'
extends:
- '.fdo.distribution-image@fedora'
needs:
- job: 'fedora image'
artifacts: false
script:
- source ./.gitlab-ci/env.sh
- bash -x ./.gitlab-ci/build-with-coverage.sh
- bash -x ./.gitlab-ci/gen-coverage.sh
coverage: '/Coverage: \d+\.\d+/'
artifacts:
name: "cairo-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}"
expire_in: 2 days
when: always
reports:
coverage_report:
coverage_format: cobertura
path: public/coverage.xml
paths:
- "_build/meson-logs"
- public
pages:
stage: 'deploy'
needs:
- job: coverage
script:
- mkdir -p public
- cp .gitlab-ci/pages-index.html public/index.html
artifacts:
paths:
- public
expire_in: 1 day
rules:
# Restrict to the main branch so not every branch tries to deploy the web site
- if: ($CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH)

View file

@ -0,0 +1,22 @@
[constants]
ndk_path = '/android/ndk'
ndk_bindir = ndk_path + '/toolchains/llvm/prebuilt/linux-x86_64/bin/'
toolchain = ndk_bindir + 'aarch64-linux-android'
api = '28'
[host_machine]
system = 'android'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
[properties]
sys_root = ndk_path + '/sysroot'
c_ld = 'gold'
cpp_ld = 'gold'
[binaries]
c = toolchain + api + '-clang'
cpp = toolchain + api + '-clang++'
ar = ndk_bindir + 'llvm-ar'
strip = ndk_bindir + 'llvm-strip'

View file

@ -0,0 +1,17 @@
#!/bin/sh
set -eux -o pipefail
export CFLAGS="-coverage -ftest-coverage -fprofile-arcs"
export CAIRO_TEST_IGNORE_image_argb32=$(tr '\n' ',' < .gitlab-ci/ignore-image-argb32.txt)
export CAIRO_TEST_IGNORE_image_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-image-rgb24.txt)
export CAIRO_TEST_IGNORE_image16_rgb24=$(tr '\n' ',' < .gitlab-ci/ignore-image16-rgb24.txt)
export CAIRO_TEST_TARGET=image,image16
meson setup --buildtype=debug _build .
meson compile -C _build
export srcdir=../../test
cd _build/test
xvfb-run ./cairo-test-suite

2
.gitlab-ci/env.sh Normal file
View file

@ -0,0 +1,2 @@
export RUSTUP_HOME='/usr/local/rustup'
export PATH=$PATH:/usr/local/cargo/bin

View file

@ -0,0 +1,14 @@
#!/bin/sh
set -eux -o pipefail
mkdir -p public
grcov _build --source-dir ./ --prefix-dir ../ --output-type cobertura --branch --ignore-not-existing -o public/coverage.xml
grcov _build --source-dir ./ --prefix-dir ../ --output-type html --branch --ignore-not-existing -o public/coverage
# Print "Coverage: 42.42" so .gitlab-ci.yml will pick it up with a regex
#
# We scrape this from the HTML report, not the JSON summary, because coverage.json
# uses no decimal places, just something like "42%".
grep -Eo 'abbr title.* %' public/coverage/index.html | head -n 1 | grep -Eo '[0-9.]+ %' | grep -Eo '[0-9.]+' | awk '{ print "Coverage:", $1 }'

View file

@ -2,6 +2,7 @@ bug-361
bug-431
bug-image-compositor
clip-operator
coverage-column-triangles
coverage-rhombus
culled-glyphs
extended-blend-alpha

View file

@ -10,6 +10,7 @@ bug-image-compositor
bug-source-cu
clip-device-offset
clip-fill-rule-pixel-aligned
coverage-column-triangles
coverage-rhombus
culled-glyphs
device-offset

View file

@ -0,0 +1,33 @@
#! /bin/bash
# Copied from gstreamer/cerbero
# https://gitlab.freedesktop.org/gstreamer/cerbero/-/blob/2a0f5829aa1b56e8d36ef36f9675845345d54542/ci/docker_android_setup.sh
set -eux
export ANDROID_HOME=$1
export ANDROID_NDK_HOME=$2
mkdir -p /android/sources
curl -o /android/sources/android-ndk.zip https://dl.google.com/android/repository/android-ndk-r25c-linux.zip
unzip /android/sources/android-ndk.zip -d ${ANDROID_NDK_HOME}/
# remove the intermediate versioned directory
mv ${ANDROID_NDK_HOME}/*/* ${ANDROID_NDK_HOME}/
curl -o /android/sources/android-sdk-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip
unzip /android/sources/android-sdk-tools.zip -d ${ANDROID_HOME}/
mkdir -p ${ANDROID_HOME}/licenses
# Accept licenses. Values taken from:
# $ANDROID_HOME/tools/bin/sdkmanager --sdk_root=$ANDROID_HOME --licenses
# cd $ANDROID_HOME
# for f in licenses/*; do echo "echo \"$(cat $f | tr -d '\n')\" > \${ANDROID_HOME}/$f"; done
echo "601085b94cd77f0b54ff86406957099ebe79c4d6" > ${ANDROID_HOME}/licenses/android-googletv-license
echo "859f317696f67ef3d7f30a50a5560e7834b43903" > ${ANDROID_HOME}/licenses/android-sdk-arm-dbt-license
echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > ${ANDROID_HOME}/licenses/android-sdk-license
echo "84831b9409646a918e30573bab4c9c91346d8abd" > ${ANDROID_HOME}/licenses/android-sdk-preview-license
echo "33b6a2b64607f11b759f320ef9dff4ae5c47d97a" > ${ANDROID_HOME}/licenses/google-gdk-license
echo "e9acab5b5fbb560a72cfaecce8946896ff6aab9d" > ${ANDROID_HOME}/licenses/mips-android-sysimage-license
rm -rf /android/sources

View file

@ -0,0 +1,8 @@
source ./.gitlab-ci/env.sh
set -eu
export CARGO_HOME='/usr/local/cargo'
# Coverage tools
cargo install grcov
rustup component add llvm-tools-preview

View file

@ -0,0 +1,11 @@
source ./.gitlab-ci/env.sh
set -eu
export CARGO_HOME='/usr/local/cargo'
rustup component add clippy
rustup component add rustfmt
# cargo install --force cargo-c
cargo install --version ^1.0 gitlab_clippy
cargo install --force cargo-deny
# cargo install --force cargo-outdated

View file

@ -0,0 +1,92 @@
#!/bin/bash
set -o errexit -o pipefail -o noclobber -o nounset
source ./.gitlab-ci/env.sh
export CARGO_HOME='/usr/local/cargo'
PARSED=$(getopt --options '' --longoptions 'rustup-version:,stable:,minimum:,nightly,arch:' --name "$0" -- "$@")
if [ $? -ne 0 ]; then
echo 'Terminating...' >&2
exit 1
fi
eval set -- "$PARSED"
unset PARSED
RUSTUP_VERSION=
STABLE=
MINIMUM=
NIGHTLY=
ARCH=
while true; do
case "$1" in
'--rustup-version')
RUSTUP_VERSION=$2
shift 2
;;
'--stable')
STABLE=$2
shift 2
;;
'--minimum')
MINIMUM=$2
shift 2
;;
'--nightly')
NIGHTLY=1
shift 1
;;
'--arch')
ARCH=$2
shift 2
;;
'--')
shift
break
;;
*)
echo "Programming error"
exit 3
;;
esac
done
if [ -z "$RUSTUP_VERSION" ]; then
echo "missing --rustup-version argument"
exit 1
fi
if [ -z "$STABLE" ]; then
echo "missing --stable argument, please pass the stable version of rustc you want"
exit 1
fi
if [ -z "$ARCH" ]; then
echo "missing --arch argument, please pass an architecture triple like x86_64-unknown-linux-gnu"
exit 1
fi
RUSTUP_URL=https://static.rust-lang.org/rustup/archive/$RUSTUP_VERSION/$ARCH/rustup-init
wget $RUSTUP_URL
chmod +x rustup-init
./rustup-init -y --no-modify-path --profile minimal --default-toolchain $STABLE
rm rustup-init
chmod -R a+w $RUSTUP_HOME $CARGO_HOME
if [ -n "$MINIMUM" ]; then
rustup toolchain install $MINIMUM
fi
if [ -n "$NIGHTLY" ]; then
rustup toolchain install nightly
fi

View file

@ -0,0 +1,13 @@
<html>
<head>
<title>Cairo's development pages</title>
</head>
<body>
<h1>Cairo's development pages</h1>
<ul>
<li><a href="coverage/">Test coverage report</a></li>
</ul>
</body>
</html>

19
BUGS
View file

@ -6,22 +6,22 @@ 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:
1) Gitlab 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:
bugs:
https://bugs.freedesktop.org
https://gitlab.freedesktop.org/cairo/cairo/-/issues
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
new bugs in gitlab. 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
For people who cannot stand the gitlab 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:
@ -39,8 +39,8 @@ which you prefer:
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
than using the web-based forms on gitlab. Others greatly prefer the
ability to check back on a specific bug entry in gitlab 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
@ -48,9 +48,8 @@ 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
https://bugs.freedesktop.org bugzilla database. Another place to
look for known bugs is the cairo ROADMAP:
to run a search or two against the cairo product in the gitlab
database. Another place to look for known bugs is the cairo ROADMAP:
https://cairographics.org/ROADMAP

View file

@ -46,9 +46,9 @@ the -commit and -bugs lists.
Bug Tracking System
-------------------
We use a standard bugzilla bug tracking system available at:
We use a standard gitlab bug tracking system available at:
https://bugs.freedesktop.org/
https://gitlab.freedesktop.org/cairo/cairo/-/issues
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

97
NEWS
View file

@ -1,3 +1,96 @@
Release 1.18.4 (2025-03-08 Emmanuele Bassi <ebassi@gnome.org>)
==============================================================
A new stable release.
The dependency on LZO has been made optional through a build time
configuration toggle. [!580]
You can build Cairo against a Freetype installation that does not have the
FT_Color type. [#792]
Cairo tests now build on Solaris 11.4 with GCC 14. [!599]
The DirectWrite backend now builds on MINGW 11. [!600]
Thanks to Luca Bacci, the DirectWrite backend now supports font
variations and proper glyph coverage. [#877, !602]
Support for Windows 98 has been removed. The minimum requirement for
Windows is now Vista.
Release 1.18.2 (2024-09-01 Emmanuele Bassi <ebassi@gnome.org>)
==============================================================
A new stable release.
The malloc-stats code has been removed from the tests directory [#640]; the
canonical location for it is: https://github.com/behdad/malloc-stats
Cairo now requires a version of pixman equal to, or newer than, 0.40. [!522]
There have been multiple build fixes for newer versions of GCC [!525, !542];
for MSVC [#808]; for Solaris [!540]; and on macOS 10.7 [#810].
PNG errors caused by loading malformed data are correctly propagated to
callers, so they can handle the case. [!524]
Both stroke and fill colors are now set when showing glyphs on a PDF
surface. [#813]
All the font options are copied when creating a fallback font object. [#819]
When drawing text on macOS, Cairo now tries harder to select the appropriate
font name. [#811]
Cairo now prefers the COLRv1 table inside a font, if one is available. [!537]
Cairo requires a C11 toolchain when building. [!479]
Release 1.18.0 (2023-09-20 Emmanuele Bassi <ebassi@gnome.org>)
==============================================================
The first stable cairo release in five years should be cause for celebration.
All the API added in the 1.17 development cycle is now considered stable, and
will not change.
Many thanks to all the contributors for this release.
The cairo-sphinx tool has been removed; we could not find any instruction on
how to use it, and no user answered our call for help. If you were using
cairo-sphinx, please reach out to the cairo maintainers.
Cairo now implements Type 3 color fonts for PDF. Thanks to Adrian Johnson for
his work on this feature.
Khaled Hosny contributed multiple documentation fixes, to ensure that the
cairo API reference is up to date. Khaled also fixed multiple compiler
warnings generated when building cairo.
The XML surface has been removed; it was disabled by default when building
cairo, and we could not find any downstream distributor that would enable
it.
The Tee surface is now automatically enabled. Downstream distributors of
cairo have been enabling for years it in order to build Firefox.
Fujii Hironori and Adrian Johnson fixed multiple issues with the DWrite
font backend.
John Ralls improved the Quartz surface; mainly, Quartz surfaces now use
the main display ColorSpace, speeding up rendering operations.
Cairo now hides all private symbols by default on every platform; the old
"slim" symbols hack to alias internally used symbols has been dropped, in
favor of using `-Bsymbolic-functions` with toolchains that support it.
Uli Schlachter fixed multiple memory leaks in the code base and test suite,
and helped with many reviews and general maintenance.
Marc Jeanmougin added new API to expose the Pixman dithering filter to cairo
patterns; this is currently implemented only for image surfaces.
Release 1.17.8 (2023-01-30 Emmanuele Bassi <ebassi@gnome.org>)
==============================================================
@ -108,7 +201,7 @@ includes implementation of core functionality, performance
optimizations, and stabilization.
Subpixel positioning support allows improved glyph outlines with the
Freetype font backend.
FreeType font backend.
For a complete log of changes, please see
@ -8223,7 +8316,7 @@ 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
support using FreeType/fontconfig, (previous versions of cairo used
Xft and could only draw text when using an X backend).
2003-09

View file

@ -8,8 +8,7 @@ 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.
as well as PDF, PostScript, and SVG file output.
Cairo is designed to produce consistent output on all output media
while taking advantage of display hardware acceleration when available
@ -127,7 +126,7 @@ system pixman.
#### Windows backend
- Microsoft Windows 2000 or newer.
- Microsoft Windows Vista or newer.
#### XCB backend
@ -146,7 +145,7 @@ system pixman.
#### Windows GDI font backend
- Microsoft Windows 2000 or newer
- Microsoft Windows Vista or newer
#### Windows DirectWrite font backend

View file

@ -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.

View file

@ -28,6 +28,40 @@
#include <cairo-quartz-private.h>
#include <dlfcn.h>
#ifndef RTLD_DEFAULT
#define RTLD_DEFAULT ((void *) 0)
#endif
/*
* macOS Private functions
*/
typedef enum {
kCGContextTypeUnknown,
kCGContextTypePDF,
kCGContextTypePostScript,
kCGContextTypeWindow,
kCGContextTypeBitmap,
kCGContextTypeGL,
kCGContextTypeDisplayList,
kCGContextTypeKSeparation,
kCGContextTypeIOSurface,
kCGContextTypeCount
} CGContextType;
static unsigned int (*CGContextGetTypePtr) (CGContextRef) = NULL;
static void
quartz_ensure_symbols (void)
{
static cairo_bool_t symbol_lookup_done = FALSE;
if (!symbol_lookup_done) {
CGContextGetTypePtr = dlsym (RTLD_DEFAULT, "CGContextGetType");
symbol_lookup_done = TRUE;
}
}
static cairo_surface_t *
_cairo_boilerplate_quartz_create_surface (const char *name,
cairo_content_t content,
@ -47,6 +81,48 @@ _cairo_boilerplate_quartz_create_surface (const char *name,
return cairo_quartz_surface_create (format, width, height);
}
static bool
cg_context_is_bitmap (CGContextRef context)
{
quartz_ensure_symbols ();
if (likely (CGContextGetTypePtr)) {
return CGContextGetTypePtr (context) == kCGContextTypeBitmap;
}
return CGBitmapContextGetBitsPerPixel (context) != 0;
}
static cairo_status_t
_cairo_boilerplate_quartz_surface_to_png (cairo_surface_t *surface,
const char *dest)
{
CGContextRef context = cairo_quartz_surface_get_cg_context (surface);
if (!context || !cg_context_is_bitmap (context)) {
return CAIRO_STATUS_SURFACE_TYPE_MISMATCH;
}
CGImageRef image = CGBitmapContextCreateImage (context);
CFStringRef png_utti = CFSTR("public.png");
CFStringRef path;
CFURLRef url;
CGImageDestinationRef image_dest;
path = CFStringCreateWithCString (NULL, dest, kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, FALSE);
image_dest = CGImageDestinationCreateWithURL (url, png_utti, 1, NULL);
CGImageDestinationAddImage (image_dest, image, NULL);
CGImageDestinationFinalize (image_dest);
CFRelease (url);
CFRelease (path);
CGImageRelease (image);
return CAIRO_STATUS_SUCCESS;
}
static const cairo_boilerplate_target_t targets[] = {
{
"quartz", "quartz", NULL, NULL,
@ -56,7 +132,7 @@ static const cairo_boilerplate_target_t targets[] = {
cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
_cairo_quartz_surface_to_png,
_cairo_boilerplate_quartz_surface_to_png,
NULL, NULL, NULL,
TRUE, FALSE, FALSE
},
@ -68,7 +144,7 @@ static const cairo_boilerplate_target_t targets[] = {
cairo_surface_create_similar,
NULL, NULL,
_cairo_boilerplate_get_image_surface,
_cairo_quartz_surface_to_png,
_cairo_boilerplate_quartz_surface_to_png,
NULL, NULL, NULL,
FALSE, FALSE, FALSE
},

View file

@ -36,51 +36,6 @@
#include <windows.h>
#if !defined(POSTSCRIPT_IDENTIFY)
# define POSTSCRIPT_IDENTIFY 0x1015
#endif
#if !defined(PSIDENT_GDICENTRIC)
# define PSIDENT_GDICENTRIC 0x0000
#endif
#if !defined(GET_PS_FEATURESETTING)
# define GET_PS_FEATURESETTING 0x1019
#endif
#if !defined(FEATURESETTING_PSLEVEL)
# define FEATURESETTING_PSLEVEL 0x0002
#endif
static cairo_status_t
_cairo_win32_print_gdi_error (const char *context)
{
void *lpMsgBuf;
DWORD last_error = GetLastError ();
if (!FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
last_error,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR) &lpMsgBuf,
0, NULL)) {
fprintf (stderr, "%s: Unknown GDI error", context);
} else {
fprintf (stderr, "%s: %S", context, (wchar_t *)lpMsgBuf);
LocalFree (lpMsgBuf);
}
fflush (stderr);
/* We should switch off of last_status, but we'd either return
* CAIRO_STATUS_NO_MEMORY or CAIRO_STATUS_UNKNOWN_ERROR and there
* is no CAIRO_STATUS_UNKNOWN_ERROR.
*/
return CAIRO_STATUS_NO_MEMORY;
}
static cairo_user_data_key_t win32_closure_key;
typedef struct _win32_target_closure {
@ -174,7 +129,7 @@ create_printer_dc (win32_target_closure_t *ptc)
xform.eDx = 0;
xform.eDy = printable_height - ptc->height*y_dpi/72.0;
if (!SetWorldTransform (ptc->dc, &xform)) {
_cairo_win32_print_gdi_error ("cairo-boilerplate-win32-printing:SetWorldTransform");
fprintf (stderr, "%s:%s\n", "cairo-boilerplate-win32-printing", "SetWorldTransform");
return;
}

View file

@ -73,7 +73,7 @@
#define CAIRO_BOILERPLATE_DEBUG(x)
#endif
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#if defined (__GNUC__)
#ifdef __MINGW32__
#define CAIRO_BOILERPLATE_PRINTF_FORMAT(fmt_index, va_index) \
__attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index)))

View file

@ -1,17 +0,0 @@
#include <cairo-boilerplate.h>
#include <stdio.h>
int
main (void)
{
printf ("Check linking to the just built cairo boilerplate library\n");
if (cairo_boilerplate_version () == CAIRO_VERSION) {
return 0;
} else {
fprintf (stderr,
"Error: linked to cairo boilerplate version %s instead of %s\n",
cairo_boilerplate_version_string (),
CAIRO_VERSION_STRING);
return 1;
}
}

View file

@ -28,6 +28,7 @@ cairo_boilerplate_constructors = custom_target('cairo-boilerplate-constructors.c
libcairoboilerplate = static_library('cairoboilerplate', cairo_boilerplate_sources + [cairo_boilerplate_constructors],
include_directories: [incbase],
dependencies: deps + [libcairo_dep],
c_args: ['-DCAIRO_COMPILATION'],
install: false,
build_by_default: false,
)

View file

@ -48,6 +48,7 @@
<xi:include href="xml/cairo-xlib-xrender.xml"/>
<xi:include href="xml/cairo-script.xml"/>
<xi:include href="xml/cairo-surface-observer.xml"/>
<xi:include href="xml/cairo-tee.xml"/>
</chapter>
<chapter id="cairo-support">
<title>Utilities</title>
@ -56,53 +57,53 @@
<xi:include href="xml/cairo-version.xml"/>
<xi:include href="xml/cairo-types.xml"/>
</chapter>
<index id="api-index-all">
<chapter id="api-index-all">
<title>Index</title>
<xi:include href="xml/api-index-full.xml"/>
</index>
</chapter>
<!--index id="deprecated-api-index">
<title>Index of deprecated symbols</title>
<xi:include href="xml/api-index-deprecated.xml"/>
</index-->
<index id="api-index-1-0">
<chapter id="api-index-1-0">
<title>Index of new symbols in 1.0</title>
<xi:include href="xml/api-index-1.0.xml"/>
</index>
<index id="api-index-1-2">
</chapter>
<chapter id="api-index-1-2">
<title>Index of new symbols in 1.2</title>
<xi:include href="xml/api-index-1.2.xml"/>
</index>
<index id="api-index-1-4">
</chapter>
<chapter id="api-index-1-4">
<title>Index of new symbols in 1.4</title>
<xi:include href="xml/api-index-1.4.xml"/>
</index>
<index id="api-index-1-6">
</chapter>
<chapter id="api-index-1-6">
<title>Index of new symbols in 1.6</title>
<xi:include href="xml/api-index-1.6.xml"/>
</index>
<index id="api-index-1-8">
</chapter>
<chapter id="api-index-1-8">
<title>Index of new symbols in 1.8</title>
<xi:include href="xml/api-index-1.8.xml"/>
</index>
<index id="api-index-1-10">
</chapter>
<chapter id="api-index-1-10">
<title>Index of new symbols in 1.10</title>
<xi:include href="xml/api-index-1.10.xml"/>
</index>
<index id="api-index-1-12">
</chapter>
<chapter id="api-index-1-12">
<title>Index of new symbols in 1.12</title>
<xi:include href="xml/api-index-1.12.xml"/>
</index>
<index id="api-index-1-14">
</chapter>
<chapter id="api-index-1-14">
<title>Index of new symbols in 1.14</title>
<xi:include href="xml/api-index-1.14.xml"/>
</index>
<index id="api-index-1-16">
</chapter>
<chapter id="api-index-1-16">
<title>Index of new symbols in 1.16</title>
<xi:include href="xml/api-index-1.16.xml"/>
</index>
<index id="api-index-1-18">
</chapter>
<chapter id="api-index-1-18">
<title>Index of new symbols in 1.18</title>
<xi:include href="xml/api-index-1.18.xml"/>
</index>
<xi:include href="language-bindings.xml"/>
</chapter>
<xi:include href="xml/language-bindings.xml"/>
</book>

View file

@ -0,0 +1,124 @@
<MACRO>
<NAME>CAIRO_HAS_FT_FONT</NAME>
#define CAIRO_HAS_FT_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_FC_FONT</NAME>
#define CAIRO_HAS_FC_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_PNG_FUNCTIONS</NAME>
#define CAIRO_HAS_PNG_FUNCTIONS
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_SVG_SURFACE</NAME>
#define CAIRO_HAS_SVG_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_PDF_SURFACE</NAME>
#define CAIRO_HAS_PDF_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_PS_SURFACE</NAME>
#define CAIRO_HAS_PS_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_SCRIPT_SURFACE</NAME>
#define CAIRO_HAS_SCRIPT_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_XLIB_SURFACE</NAME>
#define CAIRO_HAS_XLIB_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_XLIB_XRENDER_SURFACE</NAME>
#define CAIRO_HAS_XLIB_XRENDER_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_XCB_SURFACE</NAME>
#define CAIRO_HAS_XCB_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_XLIB_XCB_FUNCTIONS</NAME>
#define CAIRO_HAS_XLIB_XCB_FUNCTIONS
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_XCB_SHM_FUNCTIONS</NAME>
#define CAIRO_HAS_XCB_SHM_FUNCTIONS
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_QUARTZ_SURFACE</NAME>
#define CAIRO_HAS_QUARTZ_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_QUARTZ_IMAGE_SURFACE</NAME>
#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_QUARTZ_FONT</NAME>
#define CAIRO_HAS_QUARTZ_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_WIN32_SURFACE</NAME>
#define CAIRO_HAS_WIN32_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_WIN32_FONT</NAME>
#define CAIRO_HAS_WIN32_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_DWRITE_FONT</NAME>
#define CAIRO_HAS_DWRITE_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_GOBJECT_FUNCTIONS</NAME>
#define CAIRO_HAS_GOBJECT_FUNCTIONS
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_IMAGE_SURFACE</NAME>
#define CAIRO_HAS_IMAGE_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_USER_FONT</NAME>
#define CAIRO_HAS_USER_FONT
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_MIME_SURFACE</NAME>
#define CAIRO_HAS_MIME_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_RECORDING_SURFACE</NAME>
#define CAIRO_HAS_RECORDING_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_OBSERVER_SURFACE</NAME>
#define CAIRO_HAS_OBSERVER_SURFACE
</MACRO>
<MACRO>
<NAME>CAIRO_HAS_TEE_SURFACE</NAME>
#define CAIRO_HAS_TEE_SURFACE
</MACRO>

View file

@ -163,6 +163,7 @@ to_win32_surface
<SECTION>
<FILE>cairo-quartz</FILE>
CAIRO_HAS_QUARTZ_SURFACE
CAIRO_HAS_QUARTZ_IMAGE_SURFACE
cairo_quartz_surface_create
cairo_quartz_surface_create_for_cg_context
cairo_quartz_surface_get_cg_context
@ -173,6 +174,7 @@ cairo_quartz_image_surface_get_image
<SECTION>
<FILE>cairo-xlib</FILE>
CAIRO_HAS_XLIB_SURFACE
CAIRO_HAS_XLIB_XCB_FUNCTIONS
cairo_xlib_surface_create
cairo_xlib_surface_create_for_bitmap
cairo_xlib_surface_set_size
@ -407,6 +409,9 @@ cairo_pattern_get_type
cairo_pattern_get_reference_count
cairo_pattern_set_user_data
cairo_pattern_get_user_data
cairo_dither_t
cairo_pattern_set_dither
cairo_pattern_get_dither
</SECTION>
<SECTION>
@ -433,6 +438,8 @@ cairo_raster_source_finish_func_t
<FILE>cairo-tag</FILE>
CAIRO_TAG_DEST
CAIRO_TAG_LINK
CAIRO_TAG_CONTENT
CAIRO_TAG_CONTENT_REF
cairo_tag_begin
cairo_tag_end
</SECTION>
@ -757,6 +764,7 @@ cairo_get_status_string
cairo_status_string
CAIRO_FONT_TYPE_ATSUI
cairo_atsui_font_face_create_for_atsu_font_id
CAIRO_HAS_GOBJECT_FUNCTIONS
</SECTION>
<SECTION>
@ -772,3 +780,12 @@ cairo_script_surface_create
cairo_script_surface_create_for_target
cairo_script_write_comment
</SECTION>
<SECTION>
<FILE>cairo-tee</FILE>
CAIRO_HAS_TEE_SURFACE
cairo_tee_surface_create
cairo_tee_surface_add
cairo_tee_surface_index
cairo_tee_surface_remove
</SECTION>

View file

@ -0,0 +1,12 @@
#include <assert.h>
#include <stdatomic.h>
/* We require lock free atomics for int and pointers as cairo assumes
* an int* can be cast to cairo_atomic_int_t*
*/
_Static_assert (ATOMIC_INT_LOCK_FREE == 2, "Lock free atomics not supported");
_Static_assert (ATOMIC_POINTER_LOCK_FREE == 2, "Lock free atomics not supported");
int atomic_add(atomic_int *i) { return atomic_fetch_add_explicit(i, 1, memory_order_seq_cst); }
int atomic_cmpxchg(atomic_int *i, int j, int k) { return atomic_compare_exchange_strong_explicit (i, &j, k, memory_order_seq_cst, memory_order_seq_cst); }
int main(void) { return 0; }

View file

@ -1,7 +0,0 @@
#include <ft2build.h>
#include FT_FREETYPE_H
int main(void) {
FT_Long has_color = FT_HAS_COLOR(((FT_Face)NULL));
return 0;
}

View file

@ -1,12 +1,15 @@
project('cairo', 'c', 'cpp',
meson_version: '>= 0.56.0',
project('cairo', 'c',
meson_version: '>= 1.3.0',
version: run_command(find_program('version.py'), check: true).stdout().strip(),
default_options: ['warning_level=2'],
default_options: ['c_std=gnu11,c11',
'cpp_std=gnu++11,c++11',
'warning_level=2'],
)
freetype_required_version = '>= 9.7.3'
freetype_colrv1_required_version = '>= 25.0.19'
fontconfig_required_version = '>= 2.2.95'
freetype_required_version = '>= 23.0.17' # Release version 2.10
freetype_colrv1_required_version = '>= 25.0.19' # Release version 2.13
fontconfig_required_version = '>= 2.13.0'
libpng_required_version = '>= 1.4.0'
xrender_required_version = '>= 0.6'
xcb_required_version = '>= 1.6'
xcb_render_required_version = '>= 1.6'
@ -73,7 +76,7 @@ if cc.get_id() != 'msvc'
endif
supported_cflags = cc.get_supported_arguments(cflags)
add_project_arguments(supported_cflags, language: 'c')
add_project_arguments(supported_cflags, language: ['c', 'cpp'])
# We only wish to enable attribute(warn_unused_result) if we can prevent
# gcc from generating thousands of warnings about the misapplication of the
@ -92,20 +95,13 @@ if cc.get_id() == 'msvc'
add_project_arguments('/wd4244', '/wd4146',
# Don't warn about double -> float truncation
'/wd4305',
language : 'c')
# Don't warn about _cairo_status -> _cairo_int_status conversion
'/wd5286',
language : ['c', 'cpp'])
add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language : ['c', 'cpp'])
endif
add_project_arguments('-D_GNU_SOURCE', language: 'c')
# Make sure source directory hasn't been configured with autotools
fs = import('fs')
if fs.exists('config.h') or fs.exists('src/cairo-features.h') or fs.exists('src/cairo-supported-features.h')
error('''
The source directory '@0@' appears to contain
autotools configuration artifacts. This can cause difficult to
debug build problems. Please clean it up and then re-run meson.
'''.format(meson.source_root()))
endif
add_project_arguments('-D_GNU_SOURCE', language: ['c', 'cpp'])
pkgmod = import('pkgconfig')
python3 = import('python').find_installation()
@ -145,6 +141,8 @@ check_headers = [
['xlocale.h'],
['sys/ioctl.h'],
['intsafe.h'],
['alloca.h'],
['termios.h'],
]
check_types = [
@ -185,6 +183,10 @@ test_deps = []
internal_deps = []
extra_link_args = []
extra_link_args += cc.get_supported_link_arguments([
'-Wl,-Bsymbolic-functions',
])
if host_machine.endian() == 'big'
conf.set('WORDS_BIGENDIAN', 1)
endif
@ -201,7 +203,7 @@ else
endif
endif
lzo_dep = dependency('lzo2', required: false)
lzo_dep = dependency('lzo2', required: get_option('lzo'))
if lzo_dep.found()
conf.set('HAVE_LZO', 1)
endif
@ -238,6 +240,7 @@ endif
png_dep = dependency('libpng',
required: get_option('png'),
version: libpng_required_version,
fallback: ['libpng', 'libpng_dep']
)
if png_dep.found()
@ -263,12 +266,10 @@ if png_dep.found()
endif
endif
# Don't build fontconfig as a subproject on Windows unless
# explicitly requested
# Disable fontconfig by default on platforms where it is optional
fontconfig_option = get_option('fontconfig')
if host_machine.system() == 'windows' and not fontconfig_option.enabled()
fontconfig_option = false
endif
fontconfig_required = host_machine.system() not in ['windows', 'darwin']
fontconfig_option = fontconfig_option.disable_auto_if(not fontconfig_required)
fontconfig_dep = dependency('fontconfig',
required: fontconfig_option,
@ -301,8 +302,13 @@ endif
ttx = find_program('ttx', required: false)
# Disable FreeType by default on platforms where it is optional
freetype_option = get_option('freetype')
freetype_required = host_machine.system() not in ['windows', 'darwin']
freetype_option = freetype_option.disable_auto_if(not freetype_required)
freetype_dep = dependency('freetype2',
required: get_option('freetype'),
required: freetype_option,
version: freetype_required_version,
fallback: ['freetype2', 'freetype_dep'],
)
@ -310,32 +316,20 @@ if freetype_dep.found()
feature_conf.set('CAIRO_HAS_FT_FONT', 1)
built_features += [{
'name': 'cairo-ft',
'description': 'Freetype font backend',
'description': 'FreeType font backend',
'deps': [freetype_dep],
# cairo-ft.h includes fontconfig.h so it needs its cflags
'compile-deps': [fontconfig_dep.partial_dependency(compile_args: true, includes: true)],
}]
ft_check_funcs = [
'FT_Get_X11_Font_Format',
'FT_GlyphSlot_Embolden',
'FT_GlyphSlot_Oblique',
'FT_Load_Sfnt_Table',
'FT_Library_SetLcdFilter',
'FT_Get_Var_Design_Coordinates',
'FT_Done_MM_Var',
'FT_Palette_Select',
]
if freetype_dep.type_name() == 'internal'
foreach func : ft_check_funcs
conf.set('HAVE_@0@'.format(func.to_upper()), 1)
endforeach
if freetype_dep.version().version_compare(freetype_colrv1_required_version)
conf.set('HAVE_FT_SVG_DOCUMENT', 1)
conf.set('HAVE_FT_LOAD_NO_SVG', 1)
conf.set('HAVE_FT_COLR_V1', 1)
endif
internal_deps += [freetype_dep]
else
if not cc.links(files('meson-cc-tests/ft_has_color.c'), dependencies: freetype_dep, name: 'FT has color')
conf.set('FT_HAS_COLOR', '(0)')
endif
if png_dep.found() and \
cc.has_type('FT_SVG_Document', dependencies: freetype_dep, prefix: '#include <freetype/otsvg.h>')
conf.set('HAVE_FT_SVG_DOCUMENT', 1)
@ -343,11 +337,13 @@ if freetype_dep.found()
conf.set('CAIRO_CAN_TEST_TTX_FONT', 1)
endif
endif
if cc.has_define('FT_LOAD_NO_SVG', dependencies: freetype_dep, prefix: '#include <freetype/freetype.h>')
conf.set('HAVE_FT_LOAD_NO_SVG', 1)
endif
if freetype_dep.version().version_compare(freetype_colrv1_required_version) and \
cc.has_function('FT_Get_Color_Glyph_Paint', dependencies: freetype_dep)
conf.set('HAVE_FT_COLR_V1', 1)
endif
check_funcs += ft_check_funcs
deps += [freetype_dep]
endif
endif
@ -372,7 +368,7 @@ if x11_dep.found() and xext_dep.found()
# Can skip the run check by providing the result in a cross file or
# native file as bool property value.
prop = meson.get_external_property('ipc_rmid_deferred_release', 'auto')
prop = meson.get_external_property('ipc_rmid_deferred_release', meson.is_cross_build() ? 'false' : 'auto')
# We don't know the type of prop (bool, string) but need to differentiate
# between a set value (bool) or the fallback value (string), so convert to
# a string and check the string value.
@ -492,6 +488,8 @@ if host_machine.system() == 'darwin' and not get_option('quartz').disabled()
endif
if host_machine.system() == 'windows'
add_languages('cpp', native: false)
add_project_arguments('-DWIN32_LEAN_AND_MEAN', '-DNOMINMAX', language: ['c', 'cpp'])
win32_extra_deps = [
@ -541,7 +539,7 @@ if host_machine.system() == 'windows'
add_project_arguments('-DWINVER=_WIN32_WINNT_WIN10', '-D_WIN32_WINNT=_WIN32_WINNT_WIN10', '-DNTDDI_VERSION=NTDDI_WIN10_RS3', language: ['c', 'cpp'])
else
add_project_arguments('-DWINVER=_WIN32_WINNT_WIN2K', '-D_WIN32_WINNT=_WIN32_WINNT_WIN2K', language: ['c', 'cpp'])
add_project_arguments('-DWINVER=_WIN32_WINNT_VISTA', '-D_WIN32_WINNT=_WIN32_WINNT_VISTA', language: ['c', 'cpp'])
endif
endif
@ -636,12 +634,15 @@ if feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1
endif
pixman_dep = dependency('pixman-1',
version: '>= 0.36.0',
version: '>= 0.40.0',
fallback: ['pixman', 'idep_pixman'],
)
if pixman_dep.found()
feature_conf.set('CAIRO_HAS_IMAGE_SURFACE', 1)
conf.set('HAS_PIXMAN_GLYPHS', 1)
if pixman_dep.version().version_compare('>= 0.42.3')
conf.set('HAS_PIXMAN_r8g8b8_sRGB', 1)
endif
if pixman_dep.type_name() == 'internal'
internal_deps += [pixman_dep]
else
@ -734,14 +735,22 @@ endforeach
extra_link_args += pthread_link_args
if cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
conf.set('HAVE_CXX11_ATOMIC_PRIMITIVES', 1)
elif cc.links(files('meson-cc-tests/atomic-ops-gcc-legacy.c'), name: 'Atomic ops: gcc legacy')
conf.set('HAVE_GCC_LEGACY_ATOMICS', 1)
elif cc.has_header('atomic_ops.h')
conf.set('HAVE_LIB_ATOMIC_OPS', 1)
elif cc.has_header('libkern/OSAtomic.h')
conf.set('HAVE_OS_ATOMIC_OPS', 1)
# Atomics are an optional feature in C11. Also need to check that C11 atomics are lock free.
# On Windows we use the Interlocked family of functions
if host_machine.system() != 'windows'
if cc.links(files('meson-cc-tests/atomic-ops-c11.c'), name: 'Atomic ops: c11')
conf.set('HAVE_C11_ATOMIC_PRIMITIVES', 1)
elif cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
conf.set('HAVE_CXX11_ATOMIC_PRIMITIVES', 1)
elif cc.links(files('meson-cc-tests/atomic-ops-gcc-legacy.c'), name: 'Atomic ops: gcc legacy')
conf.set('HAVE_GCC_LEGACY_ATOMICS', 1)
elif cc.has_header('atomic_ops.h')
conf.set('HAVE_LIB_ATOMIC_OPS', 1)
elif cc.has_header('libkern/OSAtomic.h')
conf.set('HAVE_OS_ATOMIC_OPS', 1)
else
warning('Atomic ops not supported.')
endif
endif
test_mkdir_c_args = []
@ -765,7 +774,7 @@ if not ['x86', 'x86_64'].contains(host_machine.cpu_family())
conf.set('ATOMIC_OP_NEEDS_MEMORY_BARRIER', 1)
endif
have_ld_preload = ['linux', 'freebsd', 'darwin', 'dragonfly'].contains(host_machine.system())
have_ld_preload = ['linux', 'freebsd', 'darwin', 'dragonfly', 'sunos'].contains(host_machine.system())
if have_ld_preload and zlib_dep.found() and conf.get('CAIRO_HAS_REAL_PTHREAD', 0) == 1 and conf.get('CAIRO_HAS_DLSYM', 0) == 1
conf.set('CAIRO_HAS_TRACE', 1)

View file

@ -6,7 +6,7 @@ option('freetype', type : 'feature', value : 'auto')
# Cairo surface backends
option('png', type : 'feature', value : 'auto') # png and svg surfaces
option('quartz', type : 'feature', value : 'auto')
option('tee', type : 'feature', value : 'disabled')
option('tee', type : 'feature', value : 'auto')
option('xcb', type : 'feature', value : 'auto')
option('xlib', type : 'feature', value : 'auto')
option('xlib-xcb', type : 'feature', value : 'disabled')
@ -16,6 +16,7 @@ option('zlib', type : 'feature', value : 'auto') # script, ps, pdf, xml surfaces
option('tests', type : 'feature', value : 'auto')
# Util deps
option('lzo', type : 'feature', value : 'auto')
option('gtk2-utils', type : 'feature', value : 'disabled')
# Misc deps

View file

@ -43,6 +43,9 @@
#if USE_TERMINAL_SIZE
#include <unistd.h>
#include <sys/ioctl.h>
#if HAVE_TERMIOS_H
#include <termios.h>
#endif
#endif
static void

View file

@ -123,7 +123,7 @@ attach_proxy (cairo_surface_t *source,
{
struct proxy *proxy;
proxy = _cairo_malloc (sizeof (*proxy));
proxy = _cairo_calloc (sizeof (*proxy));
if (unlikely (proxy == NULL))
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
@ -953,7 +953,7 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
if (unlikely (status))
return _cairo_surface_create_in_error (status);
surface = _cairo_malloc (sizeof (cairo_analysis_surface_t));
surface = _cairo_calloc (sizeof (cairo_analysis_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -1213,7 +1213,7 @@ _cairo_null_surface_create (cairo_content_t content)
{
cairo_surface_t *surface;
surface = _cairo_malloc (sizeof (cairo_surface_t));
surface = _cairo_calloc (sizeof (cairo_surface_t));
if (unlikely (surface == NULL)) {
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}

View file

@ -188,6 +188,9 @@ _cairo_arc_in_direction (cairo_t *cr,
if (cairo_status (cr))
return;
if (! ISFINITE (angle_max) || ! ISFINITE (angle_min))
return;
assert (angle_max >= angle_min);
if (angle_max - angle_min > 2 * M_PI * MAX_FULL_CIRCLES) {

View file

@ -40,7 +40,7 @@
#include "cairo-array-private.h"
#include "cairo-error-private.h"
/**
/*< private >
* _cairo_array_init:
*
* Initialize a new #cairo_array_t object to store objects each of size
@ -63,7 +63,7 @@ _cairo_array_init (cairo_array_t *array, unsigned int element_size)
array->elements = NULL;
}
/**
/*< private >
* _cairo_array_fini:
* @array: A #cairo_array_t
*
@ -77,7 +77,7 @@ _cairo_array_fini (cairo_array_t *array)
free (array->elements);
}
/**
/*< private >
* _cairo_array_grow_by:
* @array: a #cairo_array_t
*
@ -125,7 +125,7 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
return CAIRO_STATUS_SUCCESS;
}
/**
/*< private >
* _cairo_array_truncate:
* @array: a #cairo_array_t
*
@ -140,7 +140,7 @@ _cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
array->num_elements = num_elements;
}
/**
/*< private >
* _cairo_array_index:
* @array: a #cairo_array_t
*
@ -149,7 +149,7 @@ _cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
* pointer may be used for further direct indexing with []. For
* example:
*
* <informalexample><programlisting>
* |[<!-- language="C" -->
* cairo_array_t array;
* double *values;
*
@ -159,7 +159,7 @@ _cairo_array_truncate (cairo_array_t *array, unsigned int num_elements)
* values = _cairo_array_index (&array, 0);
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
* ... use values[i] here ...
* </programlisting></informalexample>
* ]|
*
* Returns: A pointer to the object stored at @index.
**/
@ -185,7 +185,7 @@ _cairo_array_index (cairo_array_t *array, unsigned int index)
return array->elements + (size_t)index * array->element_size;
}
/**
/*< private >
* _cairo_array_index_const:
* @array: a #cairo_array_t
*
@ -194,7 +194,7 @@ _cairo_array_index (cairo_array_t *array, unsigned int index)
* pointer may be used for further direct indexing with []. For
* example:
*
* <informalexample><programlisting>
* |[<!-- language="C" --.
* cairo_array_t array;
* const double *values;
*
@ -204,7 +204,7 @@ _cairo_array_index (cairo_array_t *array, unsigned int index)
* values = _cairo_array_index_const (&array, 0);
* for (i = 0; i < _cairo_array_num_elements (&array); i++)
* ... read values[i] here ...
* </programlisting></informalexample>
* ]|
*
* Returns: A pointer to the object stored at @index.
**/
@ -230,7 +230,7 @@ _cairo_array_index_const (const cairo_array_t *array, unsigned int index)
return array->elements + (size_t)index * array->element_size;
}
/**
/*< private >
* _cairo_array_copy_element:
* @array: a #cairo_array_t
*
@ -245,7 +245,7 @@ _cairo_array_copy_element (const cairo_array_t *array,
memcpy (dst, _cairo_array_index_const (array, index), array->element_size);
}
/**
/*< private >
* _cairo_array_append:
* @array: a #cairo_array_t
*
@ -267,7 +267,7 @@ _cairo_array_append (cairo_array_t *array,
return _cairo_array_append_multiple (array, element, 1);
}
/**
/*< private >
* _cairo_array_append_multiple:
* @array: a #cairo_array_t
*
@ -296,7 +296,7 @@ _cairo_array_append_multiple (cairo_array_t *array,
return CAIRO_STATUS_SUCCESS;
}
/**
/*< private >
* _cairo_array_allocate:
* @array: a #cairo_array_t
*
@ -329,7 +329,7 @@ _cairo_array_allocate (cairo_array_t *array,
return CAIRO_STATUS_SUCCESS;
}
/**
/*< private >
* _cairo_array_num_elements:
* @array: a #cairo_array_t
*
@ -343,7 +343,7 @@ _cairo_array_num_elements (const cairo_array_t *array)
return array->num_elements;
}
/**
/*< private >
* _cairo_array_size:
* @array: a #cairo_array_t
*
@ -358,7 +358,7 @@ _cairo_array_size (const cairo_array_t *array)
return array->size;
}
/**
/*< private >
* _cairo_user_data_array_init:
* @array: a #cairo_user_data_array_t
*
@ -373,7 +373,7 @@ _cairo_user_data_array_init (cairo_user_data_array_t *array)
_cairo_array_init (array, sizeof (cairo_user_data_slot_t));
}
/**
/*< private >
* _cairo_user_data_array_fini:
* @array: a #cairo_user_data_array_t
*
@ -400,7 +400,7 @@ _cairo_user_data_array_fini (cairo_user_data_array_t *array)
_cairo_array_fini (array);
}
/**
/*< private >
* _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
@ -433,7 +433,7 @@ _cairo_user_data_array_get_data (cairo_user_data_array_t *array,
return NULL;
}
/**
/*< private >
* _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
@ -543,7 +543,7 @@ _cairo_array_sort (const cairo_array_t *array, int (*compar)(const void *, const
qsort (array->elements, array->num_elements, array->element_size, compar);
}
/**
/*< private >
* _cairo_array_pop_element:
* @array: a #cairo_array_t
* Returns: A TRUE if element successfully popped, FALSE if the array is empty.
@ -563,7 +563,7 @@ _cairo_array_pop_element (cairo_array_t *array, void *dst)
return FALSE;
}
/**
/*< private >
* _cairo_array_top_element:
* @array: a #cairo_array_t
* Returns: A pointer to the last of object or NULL if array is empty.

View file

@ -45,14 +45,94 @@
#include <assert.h>
/* 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
#if HAVE_C11_ATOMIC_PRIMITIVES
#include <stdatomic.h>
#define HAS_ATOMIC_OPS 1
typedef atomic_int cairo_atomic_int_t;
typedef _Atomic(void *) cairo_atomic_intptr_t;
static cairo_always_inline int
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
return atomic_load_explicit (x, memory_order_seq_cst);
}
static cairo_always_inline int
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
{
return atomic_load_explicit (x, memory_order_relaxed);
}
static cairo_always_inline void
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
{
atomic_store_explicit (x, val, memory_order_relaxed);
}
static cairo_always_inline void *
_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
{
return atomic_load_explicit (x, memory_order_seq_cst);
}
# define _cairo_atomic_int_inc(x) ((void) atomic_fetch_add_explicit(x, 1, memory_order_seq_cst))
# define _cairo_atomic_int_dec(x) ((void) atomic_fetch_sub_explicit(x, 1, memory_order_seq_cst))
# define _cairo_atomic_int_dec_and_test(x) (atomic_fetch_sub_explicit(x, 1, memory_order_seq_cst) == 1)
static cairo_always_inline cairo_bool_t
_cairo_atomic_int_cmpxchg_impl(cairo_atomic_int_t *x,
int oldv,
int newv)
{
int expected = oldv;
return atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_seq_cst);
}
#define _cairo_atomic_int_cmpxchg(x, oldv, newv) \
_cairo_atomic_int_cmpxchg_impl(x, oldv, newv)
static cairo_always_inline int
_cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
int oldv,
int newv)
{
int expected = oldv;
(void) atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_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(cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
void *expected = oldv;
return atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_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(cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
void *expected = oldv;
(void) atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_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 /* HAVE_C11_ATOMIC_PRIMITIVES */
/* 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
@ -68,63 +148,54 @@ CAIRO_BEGIN_DECLS
#define HAS_ATOMIC_OPS 1
typedef int cairo_atomic_int_t;
typedef intptr_t cairo_atomic_intptr_t;
static cairo_always_inline cairo_atomic_int_t
static cairo_always_inline int
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
return __atomic_load_n(x, __ATOMIC_SEQ_CST);
}
static cairo_always_inline cairo_atomic_int_t
static cairo_always_inline int
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
{
return __atomic_load_n(x, __ATOMIC_RELAXED);
}
static cairo_always_inline void
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
{
__atomic_store_n(x, val, __ATOMIC_RELAXED);
}
static cairo_always_inline void *
_cairo_atomic_ptr_get (void **x)
_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
{
return __atomic_load_n(x, __ATOMIC_SEQ_CST);
return (void*)__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)
int oldv,
int newv)
{
cairo_atomic_int_t expected = oldv;
int 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
static cairo_always_inline int
_cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
cairo_atomic_int_t oldv,
cairo_atomic_int_t newv)
int oldv,
int newv)
{
cairo_atomic_int_t expected = oldv;
int expected = oldv;
(void) __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return expected;
}
@ -133,58 +204,59 @@ _cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
_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)
_cairo_atomic_ptr_cmpxchg_impl(cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
void *expected = oldv;
return __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
intptr_t expected = (intptr_t)oldv;
return __atomic_compare_exchange_n(x, &expected, (intptr_t)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)
_cairo_atomic_ptr_cmpxchg_return_old_impl(cairo_atomic_intptr_t *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;
intptr_t expected = (intptr_t)oldv;
(void) __atomic_compare_exchange_n(x, &expected, (intptr_t)newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return (void*)expected;
}
#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
_cairo_atomic_ptr_cmpxchg_return_old_impl(x, oldv, newv)
#endif
#endif /* HAVE_CXX11_ATOMIC_PRIMITIVES */
#if HAVE_GCC_LEGACY_ATOMICS
#define HAS_ATOMIC_OPS 1
typedef int cairo_atomic_int_t;
typedef intptr_t cairo_atomic_intptr_t;
static cairo_always_inline cairo_atomic_int_t
static cairo_always_inline int
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
__sync_synchronize ();
return *x;
}
static cairo_always_inline cairo_atomic_int_t
static cairo_always_inline int
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
{
return *x;
}
static cairo_always_inline void
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
{
*x = val;
}
static cairo_always_inline void *
_cairo_atomic_ptr_get (void **x)
_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
{
__sync_synchronize ();
return *x;
return (void*)*x;
}
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
@ -193,23 +265,13 @@ _cairo_atomic_ptr_get (void **x)
# 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
#endif /* HAVE_GCC_LEGACY_ATOMICS */
#if HAVE_LIB_ATOMIC_OPS
#include <atomic_ops.h>
@ -227,15 +289,7 @@ typedef AO_t cairo_atomic_int_t;
# 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
typedef intptr_t cairo_atomic_intptr_t;
# define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x))
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
@ -249,6 +303,7 @@ typedef unsigned long long cairo_atomic_intptr_t;
#define HAS_ATOMIC_OPS 1
typedef int32_t cairo_atomic_int_t;
typedef intptr_t cairo_atomic_intptr_t;
# define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
# define _cairo_atomic_int_get_relaxed(x) *(x)
@ -260,12 +315,10 @@ typedef int32_t cairo_atomic_int_t;
# 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)
@ -275,26 +328,17 @@ typedef int64_t cairo_atomic_intptr_t;
# define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x))
#endif
#endif /* HAVE_OS_ATOMIC_OPS */
#if !defined(HAS_ATOMIC_OPS) && defined(_WIN32)
#include <windows.h>
#define HAS_ATOMIC_OPS 1
typedef int32_t cairo_atomic_int_t;
typedef LONG cairo_atomic_int_t;
typedef PVOID cairo_atomic_intptr_t;
#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
static cairo_always_inline cairo_atomic_int_t
static cairo_always_inline int
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
MemoryBarrier ();
@ -304,33 +348,33 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
# define _cairo_atomic_int_get_relaxed(x) *(x)
# define _cairo_atomic_int_set_relaxed(x, val) *(x) = (val)
# define _cairo_atomic_int_inc(x) ((void) InterlockedIncrement ((LONG*)x))
# define _cairo_atomic_int_dec(x) ((void) InterlockedDecrement ((LONG*)x))
# define _cairo_atomic_int_dec_and_test(x) (InterlockedDecrement ((LONG*)x) == 0)
# define _cairo_atomic_int_inc(x) ((void) InterlockedIncrement (x))
# define _cairo_atomic_int_dec(x) ((void) InterlockedDecrement (x))
# define _cairo_atomic_int_dec_and_test(x) (InterlockedDecrement (x) == 0)
static cairo_always_inline cairo_bool_t
_cairo_atomic_int_cmpxchg (cairo_atomic_int_t *x,
cairo_atomic_int_t oldv,
cairo_atomic_int_t newv)
int oldv,
int newv)
{
return InterlockedCompareExchange ((LONG*)x, (LONG)newv, (LONG)oldv) == oldv;
return InterlockedCompareExchange (x, (LONG)newv, (LONG)oldv) == oldv;
}
static cairo_always_inline void *
_cairo_atomic_ptr_get (void **x)
_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
{
MemoryBarrier ();
return *x;
return (void *) *x;
}
static cairo_always_inline cairo_bool_t
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
_cairo_atomic_ptr_cmpxchg (cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
return InterlockedCompareExchangePointer (x, newv, oldv) == oldv;
}
static cairo_always_inline void *
_cairo_atomic_ptr_cmpxchg_return_old (void **x, void *oldv, void *newv)
_cairo_atomic_ptr_cmpxchg_return_old (cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
return InterlockedCompareExchangePointer (x, newv, oldv);
}
@ -341,16 +385,7 @@ _cairo_atomic_ptr_cmpxchg_return_old (void **x, void *oldv, void *newv)
#ifndef HAS_ATOMIC_OPS
typedef int cairo_atomic_int_t;
#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 intptr_t cairo_atomic_intptr_t;
cairo_private void
_cairo_atomic_int_inc (cairo_atomic_int_t *x);
@ -360,24 +395,24 @@ _cairo_atomic_int_inc (cairo_atomic_int_t *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 int
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, int oldv, int newv);
cairo_private void *
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
_cairo_atomic_ptr_cmpxchg_return_old_impl (cairo_atomic_intptr_t *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_private int
_cairo_atomic_int_get (cairo_atomic_int_t *x);
cairo_private cairo_atomic_int_t
cairo_private int
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x);
void
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val);
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val);
cairo_private void*
_cairo_atomic_ptr_get(void **x);
_cairo_atomic_ptr_get(cairo_atomic_intptr_t *x);
#else
# define _cairo_atomic_int_get(x) (*x)
# define _cairo_atomic_int_get_relaxed(x) (*x)
@ -394,10 +429,10 @@ _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)
static cairo_always_inline int
_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, int oldv, int newv)
{
cairo_atomic_int_t curr;
int curr;
do {
curr = _cairo_atomic_int_get (x);
@ -407,7 +442,7 @@ _cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomi
}
static cairo_always_inline void *
_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
_cairo_atomic_ptr_cmpxchg_return_old_fallback(cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
void *curr;
@ -449,6 +484,38 @@ _cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
(void) ret__; \
} while (0)
#if defined (_WIN32)
#include <windows.h>
typedef INIT_ONCE cairo_atomic_once_t;
#define CAIRO_ATOMIC_ONCE_INIT INIT_ONCE_STATIC_INIT
static cairo_always_inline cairo_bool_t
_cairo_atomic_init_once_enter(cairo_atomic_once_t *once)
{
BOOL pending;
if (unlikely (!InitOnceBeginInitialize (once, 0, &pending, NULL))) {
assert (0 && "InitOnceBeginInitialize failed");
}
if (likely (!pending))
return 0;
return 1;
}
static cairo_always_inline void
_cairo_atomic_init_once_leave(cairo_atomic_once_t *once)
{
if (unlikely (!InitOnceComplete (once, 0, NULL))) {
assert (0 && "InitOnceComplete failed");
}
}
#else
typedef cairo_atomic_int_t cairo_atomic_once_t;
#define CAIRO_ATOMIC_ONCE_UNINITIALIZED (0)
@ -480,6 +547,8 @@ _cairo_atomic_init_once_leave(cairo_atomic_once_t *once)
assert (0 && "incorrect use of _cairo_atomic_init_once API (once != CAIRO_ATOMIC_ONCE_INITIALIZING)");
}
#endif /* !_WIN32 */
CAIRO_END_DECLS
#endif

View file

@ -61,10 +61,10 @@ _cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x)
return ret;
}
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)
int
_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, int oldv, int newv)
{
cairo_atomic_int_t ret;
int ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
@ -76,24 +76,24 @@ _cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_i
}
void *
_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv)
_cairo_atomic_ptr_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, void *oldv, void *newv)
{
void *ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
ret = (void *) *x;
if (ret == oldv)
*x = newv;
*x = (cairo_atomic_intptr_t) newv;
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
return ret;
}
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
cairo_atomic_int_t
int
_cairo_atomic_int_get (cairo_atomic_int_t *x)
{
cairo_atomic_int_t ret;
int ret;
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
ret = *x;
@ -102,14 +102,14 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
return ret;
}
cairo_atomic_int_t
int
_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
{
return _cairo_atomic_int_get (x);
}
void
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
{
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
*x = val;

View file

@ -126,7 +126,7 @@ _cairo_base64_stream_create (cairo_output_stream_t *output)
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = _cairo_malloc (sizeof (cairo_base64_stream_t));
stream = _cairo_calloc (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;

View file

@ -114,7 +114,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output)
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = _cairo_malloc (sizeof (cairo_base85_stream_t));
stream = _cairo_calloc (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;

View file

@ -616,7 +616,7 @@ cff_dict_create_operator (int operator,
{
cff_dict_operator_t *op;
op = _cairo_malloc (sizeof (cff_dict_operator_t));
op = _cairo_calloc (sizeof (cff_dict_operator_t));
if (unlikely (op == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -952,9 +952,13 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font,
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 > 0) {
*local_subs_used = _cairo_calloc_ab (num_subs, sizeof (cairo_bool_t));
if (unlikely (*local_subs_used == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
*local_subs_used = NULL;
}
if (num_subs < 1240)
*local_sub_bias = 107;
@ -971,7 +975,7 @@ 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));
font->fdselect = _cairo_calloc_ab (font->num_glyphs, sizeof (int));
if (unlikely (font->fdselect == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1021,43 +1025,43 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
font->num_fontdicts = _cairo_array_num_elements (&index);
font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
font->fd_dict = _cairo_calloc_ab (font->num_fontdicts, sizeof (cairo_hash_table_t *));
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);
font->fd_private_dict = _cairo_calloc_ab (font->num_fontdicts, sizeof (cairo_hash_table_t *));
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);
font->fd_local_sub_index = _cairo_calloc_ab (font->num_fontdicts, sizeof (cairo_array_t));
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);
font->fd_local_sub_bias = _cairo_calloc_ab (font->num_fontdicts, sizeof (int));
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);
font->fd_local_subs_used = _cairo_calloc_ab (font->num_fontdicts, sizeof (cairo_bool_t *));
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));
font->fd_default_width = _cairo_calloc_ab (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));
font->fd_nominal_width = _cairo_calloc_ab (font->num_fontdicts, sizeof (double));
if (unlikely (font->fd_nominal_width == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;
@ -1162,7 +1166,7 @@ cairo_cff_font_read_font_metrics (cairo_cff_font_t *font, cairo_hash_table_t *t
if (p < end)
p = decode_number (p, &yy);
}
/* Freetype uses 1/abs(yy) to get units per EM */
/* FreeType uses 1/abs(yy) to get units per EM */
font->units_per_em = _cairo_round(1.0/fabs(yy));
}
@ -1185,6 +1189,8 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
goto fail;
element = _cairo_array_index (&index, 0);
if (element == NULL)
return CAIRO_STATUS_NO_MEMORY;
status = cff_dict_read (font->top_dict, element->data, element->length);
if (unlikely (status))
goto fail;
@ -1312,9 +1318,13 @@ cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
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 > 0) {
font->global_subs_used = _cairo_calloc_ab (num_subs, sizeof(cairo_bool_t));
if (unlikely (font->global_subs_used == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else {
font->global_subs_used = NULL;
}
if (num_subs < 1240)
font->global_sub_bias = 107;
@ -1830,20 +1840,20 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font)
unsigned long cid, gid;
cairo_int_status_t status;
font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
font->fdselect_subset = _cairo_calloc_ab (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));
font->fd_subset_map = _cairo_calloc_ab (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));
font->private_dict_offset = _cairo_calloc_ab (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));
reverse_map = _cairo_calloc_ab (font->num_fontdicts, sizeof (int));
if (unlikely (reverse_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2808,7 +2818,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
return CAIRO_INT_STATUS_UNSUPPORTED;
}
font = calloc (1, sizeof (cairo_cff_font_t));
font = _cairo_calloc (sizeof (cairo_cff_font_t));
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2833,7 +2843,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset,
goto fail2;
}
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
font->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs, sizeof (int));
if (unlikely (font->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
@ -2992,7 +3002,8 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset,
cff_subset->family_name_utf8 = NULL;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
cff_subset->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs,
sizeof (double));
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
@ -3128,6 +3139,8 @@ _cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
goto fail2;
element = _cairo_array_index (&index, 0);
if (element == NULL)
goto fail3;
status = cff_dict_read (top_dict, element->data, element->length);
if (unlikely (status))
goto fail3;
@ -3156,7 +3169,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
cairo_status_t status;
cairo_cff_font_t *font;
font = _cairo_malloc (sizeof (cairo_cff_font_t));
font = _cairo_calloc (sizeof (cairo_cff_font_t));
if (unlikely (font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3188,7 +3201,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset
font->ascent = 0;
font->descent = 0;
font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
font->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs, sizeof (int));
if (unlikely (font->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;
@ -3403,7 +3416,7 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset,
goto fail2;
}
cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
cff_subset->widths = _cairo_calloc_ab (font->scaled_font_subset->num_glyphs, sizeof (double));
if (unlikely (cff_subset->widths == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail3;

View file

@ -318,7 +318,10 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
goto out;
}
_cairo_boxes_copy_to_clip (boxes, clip);
if (!_cairo_boxes_copy_to_clip (boxes, clip)) {
clip = _cairo_clip_set_all_clipped (clip);
goto out;
}
_cairo_boxes_extents (boxes, &limits);

View file

@ -1794,7 +1794,7 @@ _cairo_clip_tor_scan_converter_create (cairo_clip_t *clip,
cairo_status_t status;
int i;
self = calloc (1, sizeof(struct _cairo_clip_tor_scan_converter));
self = _cairo_calloc (sizeof(struct _cairo_clip_tor_scan_converter));
if (unlikely (self == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto bail_nomem;

View file

@ -62,7 +62,7 @@ _cairo_clip_path_create (cairo_clip_t *clip)
clip_path = _freed_pool_get (&clip_path_pool);
if (unlikely (clip_path == NULL)) {
clip_path = _cairo_malloc (sizeof (cairo_clip_path_t));
clip_path = _cairo_calloc (sizeof (cairo_clip_path_t));
if (unlikely (clip_path == NULL))
return NULL;
}
@ -108,7 +108,7 @@ _cairo_clip_create (void)
clip = _freed_pool_get (&clip_pool);
if (unlikely (clip == NULL)) {
clip = _cairo_malloc (sizeof (cairo_clip_t));
clip = _cairo_calloc (sizeof (cairo_clip_t));
if (unlikely (clip == NULL))
return NULL;
}
@ -337,13 +337,13 @@ _cairo_clip_intersect_clip (cairo_clip_t *clip,
else
clip = _cairo_clip_intersect_clip_path (clip, other->path);
}
}
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
if (clip->region) {
cairo_region_destroy (clip->region);
clip->region = NULL;
}
clip->is_region = FALSE;
}
clip->is_region = FALSE;
return clip;
}
@ -735,7 +735,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
if (status == CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
list = _cairo_malloc (sizeof (*list));
list = _cairo_calloc (sizeof (*list));
if (unlikely (list == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
@ -774,7 +774,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
n_rects = cairo_region_num_rectangles (region);
if (n_rects) {
rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
rectangles = _cairo_calloc_ab (n_rects, sizeof (cairo_rectangle_t));
if (unlikely (rectangles == NULL)) {
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
}
@ -795,7 +795,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
}
DONE:
list = _cairo_malloc (sizeof (cairo_rectangle_list_t));
list = _cairo_calloc (sizeof (cairo_rectangle_list_t));
if (unlikely (list == NULL)) {
free (rectangles);
return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);

View file

@ -43,6 +43,14 @@
#include <stdio.h>
#include <string.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if HAVE_FT_COLR_V1
#include <ft2build.h>
@ -319,12 +327,12 @@ read_colorline (cairo_colr_glyph_render_t *render,
double colr_alpha;
cairo_bool_t is_foreground_color;
cl = calloc (1, sizeof (cairo_colr_color_line_t));
cl = _cairo_calloc (sizeof (cairo_colr_color_line_t));
if (unlikely (cl == NULL))
return NULL;
cl->n_stops = colorline->color_stop_iterator.num_color_stops;
cl->stops = calloc (cl->n_stops, sizeof (cairo_colr_color_stop_t));
cl->stops = _cairo_calloc_ab (cl->n_stops, sizeof (cairo_colr_color_stop_t));
if (unlikely (cl->stops == NULL)) {
free (cl);
return NULL;

View file

@ -54,59 +54,7 @@
#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 procedure linkage table (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)
#if defined (__GNUC__)
#ifdef __MINGW32__
#define CAIRO_PRINTF_FORMAT(fmt_index, va_index) \
__attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt_index, va_index)))
@ -118,10 +66,9 @@
#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__)) && \
#if defined(__GNUC__) && \
(defined(__ELF__) || defined(__APPLE__)) && \
!defined(__sun)
#define cairo_private_no_warn __attribute__((__visibility__("hidden")))
#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
@ -134,6 +81,7 @@
#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
@ -149,7 +97,7 @@
indicating that the old function has been deprecated by the new
function.
*/
#if __GNUC__ >= 2 && defined(__ELF__)
#if defined (__GNUC__) && defined(__ELF__)
# define CAIRO_FUNCTION_ALIAS(old, new) \
extern __typeof (new) old \
__asm__ ("" #old) \
@ -178,17 +126,21 @@
* constant-folding, with 'cairo_const 'also guaranteeing that pointer contents
* do not change across the function call.
*/
#if __GNUC__ >= 3
#if defined (__GNUC__)
#define cairo_pure __attribute__((pure))
#define cairo_const __attribute__((const))
#define cairo_always_inline inline __attribute__((always_inline))
#elif defined (_MSC_VER)
#define cairo_pure
#define cairo_const
#define cairo_always_inline __forceinline
#else
#define cairo_pure
#define cairo_const
#define cairo_always_inline inline
#endif
#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
#if defined(__GNUC__) && defined(__OPTIMIZE__)
#define likely(expr) (__builtin_expect (!!(expr), 1))
#define unlikely(expr) (__builtin_expect (!!(expr), 0))
#else
@ -196,7 +148,7 @@
#define unlikely(expr) (expr)
#endif
#ifndef __GNUC__
#if !defined(__GNUC__) && !defined (__clang__)
#undef __attribute__
#define __attribute__(x)
#endif
@ -212,19 +164,12 @@
#define popen _popen
#define strdup _strdup
#define unlink _unlink
#if _MSC_VER < 1900
#if defined (_MSC_VER) && _MSC_VER < 1900
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#endif
#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

View file

@ -51,7 +51,7 @@ _cairo_damage_create (void)
{
cairo_damage_t *damage;
damage = _cairo_malloc (sizeof (*damage));
damage = _cairo_calloc (sizeof (*damage));
if (unlikely (damage == NULL)) {
_cairo_error_throw(CAIRO_STATUS_NO_MEMORY);
return (cairo_damage_t *) &__cairo_damage__nil;

View file

@ -1508,7 +1508,7 @@ _cairo_default_context_create (void *target)
cr = _freed_pool_get (&context_pool);
if (unlikely (cr == NULL)) {
cr = _cairo_malloc (sizeof (cairo_default_context_t));
cr = _cairo_calloc (sizeof (cairo_default_context_t));
if (unlikely (cr == NULL))
return _cairo_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}

View file

@ -124,7 +124,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output)
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = _cairo_malloc (sizeof (cairo_deflate_stream_t));
stream = _cairo_calloc (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;

View file

@ -76,11 +76,4 @@ 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_ */

View file

@ -217,7 +217,6 @@ cairo_device_reference (cairo_device_t *device)
return device;
}
slim_hidden_def (cairo_device_reference);
/**
* cairo_device_status:
@ -272,7 +271,6 @@ cairo_device_flush (cairo_device_t *device)
status = _cairo_device_set_error (device, status);
}
}
slim_hidden_def (cairo_device_flush);
/**
* cairo_device_finish:
@ -316,7 +314,6 @@ cairo_device_finish (cairo_device_t *device)
*/
device->finished = TRUE;
}
slim_hidden_def (cairo_device_finish);
/**
* cairo_device_destroy:
@ -357,7 +354,6 @@ cairo_device_destroy (cairo_device_t *device)
_cairo_user_data_array_fini (&user_data);
}
slim_hidden_def (cairo_device_destroy);
/**
* cairo_device_get_type:
@ -432,7 +428,6 @@ cairo_device_acquire (cairo_device_t *device)
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_device_acquire);
/**
* cairo_device_release:
@ -458,7 +453,6 @@ cairo_device_release (cairo_device_t *device)
CAIRO_MUTEX_UNLOCK (device->mutex);
}
slim_hidden_def (cairo_device_release);
cairo_status_t
_cairo_device_set_error (cairo_device_t *device,

View file

@ -44,7 +44,7 @@
#include <assert.h>
/**
/*< private >
* _cairo_error:
* @status: a status value indicating an error, (eg. not
* %CAIRO_STATUS_SUCCESS)

View file

@ -288,7 +288,7 @@ twin_font_face_create_properties (cairo_font_face_t *twin_face)
{
twin_face_properties_t *props;
props = _cairo_malloc (sizeof (twin_face_properties_t));
props = _cairo_calloc (sizeof (twin_face_properties_t));
if (unlikely (props == NULL))
return NULL;
@ -412,7 +412,7 @@ twin_scaled_font_compute_properties (cairo_scaled_font_t *scaled_font,
cairo_status_t status;
twin_scaled_properties_t *props;
props = _cairo_malloc (sizeof (twin_scaled_properties_t));
props = _cairo_calloc (sizeof (twin_scaled_properties_t));
if (unlikely (props == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -133,7 +133,6 @@ cairo_font_face_reference (cairo_font_face_t *font_face)
return font_face;
}
slim_hidden_def (cairo_font_face_reference);
static inline cairo_bool_t
__put(cairo_reference_count_t *v)
@ -190,7 +189,6 @@ cairo_font_face_destroy (cairo_font_face_t *font_face)
free (font_face);
}
slim_hidden_def (cairo_font_face_destroy);
/**
* cairo_font_face_get_type:
@ -272,7 +270,6 @@ cairo_font_face_get_user_data (cairo_font_face_t *font_face,
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:
@ -304,7 +301,6 @@ cairo_font_face_set_user_data (cairo_font_face_t *font_face,
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,

View file

@ -159,7 +159,7 @@ cairo_font_options_create (void)
{
cairo_font_options_t *options;
options = _cairo_malloc (sizeof (cairo_font_options_t));
options = _cairo_calloc (sizeof (cairo_font_options_t));
if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_options_t *) &_cairo_font_options_nil;
@ -193,7 +193,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
if (cairo_font_options_status ((cairo_font_options_t *) original))
return (cairo_font_options_t *) &_cairo_font_options_nil;
options = _cairo_malloc (sizeof (cairo_font_options_t));
options = _cairo_calloc (sizeof (cairo_font_options_t));
if (!options) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_options_t *) &_cairo_font_options_nil;
@ -252,7 +252,6 @@ cairo_font_options_status (cairo_font_options_t *options)
else
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_font_options_status);
/**
* cairo_font_options_merge:
@ -318,7 +317,6 @@ cairo_font_options_merge (cairo_font_options_t *options,
memcpy (options->custom_palette, other->custom_palette, sizeof (cairo_palette_color_t) * options->custom_palette_size);
}
}
slim_hidden_def (cairo_font_options_merge);
/**
* cairo_font_options_equal:
@ -362,7 +360,6 @@ cairo_font_options_equal (const cairo_font_options_t *options,
memcmp (options->custom_palette, other->custom_palette,
sizeof (cairo_palette_color_t) * options->custom_palette_size) == 0)));
}
slim_hidden_def (cairo_font_options_equal);
/**
* cairo_font_options_hash:
@ -398,7 +395,6 @@ cairo_font_options_hash (const cairo_font_options_t *options)
(options->hint_metrics << 16) |
(options->color_mode << 20)) ^ hash;
}
slim_hidden_def (cairo_font_options_hash);
/**
* cairo_font_options_set_antialias:
@ -419,7 +415,6 @@ cairo_font_options_set_antialias (cairo_font_options_t *options,
options->antialias = antialias;
}
slim_hidden_def (cairo_font_options_set_antialias);
/**
* cairo_font_options_get_antialias:
@ -462,7 +457,6 @@ cairo_font_options_set_subpixel_order (cairo_font_options_t *options,
options->subpixel_order = subpixel_order;
}
slim_hidden_def (cairo_font_options_set_subpixel_order);
/**
* cairo_font_options_get_subpixel_order:
@ -578,7 +572,6 @@ cairo_font_options_set_hint_style (cairo_font_options_t *options,
options->hint_style = hint_style;
}
slim_hidden_def (cairo_font_options_set_hint_style);
/**
* cairo_font_options_get_hint_style:
@ -621,7 +614,6 @@ cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
options->hint_metrics = hint_metrics;
}
slim_hidden_def (cairo_font_options_set_hint_metrics);
/**
* cairo_font_options_get_hint_metrics:
@ -877,4 +869,3 @@ cairo_font_options_get_custom_palette_color (cairo_font_options_t *options,
return CAIRO_STATUS_INVALID_INDEX;
}
slim_hidden_def (cairo_font_options_get_custom_palette_color);

View file

@ -49,30 +49,4 @@
#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 */

View file

@ -50,12 +50,12 @@ CAIRO_BEGIN_DECLS
*/
#define MAX_FREED_POOL_SIZE 16
typedef struct {
void *pool[MAX_FREED_POOL_SIZE];
cairo_atomic_intptr_t pool[MAX_FREED_POOL_SIZE];
cairo_atomic_int_t top;
} freed_pool_t;
static cairo_always_inline void *
_atomic_fetch (void **slot)
_atomic_fetch (cairo_atomic_intptr_t *slot)
{
void *ptr;
@ -67,7 +67,7 @@ _atomic_fetch (void **slot)
}
static cairo_always_inline cairo_bool_t
_atomic_store (void **slot, void *ptr)
_atomic_store (cairo_atomic_intptr_t *slot, void *ptr)
{
return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr);
}

View file

@ -83,8 +83,7 @@ _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;
free (_atomic_fetch (&pool->pool[i]));
}
_cairo_atomic_int_set_relaxed (&pool->top, 0);

View file

@ -60,15 +60,10 @@
#include FT_IMAGE_H
#include FT_BITMAP_H
#include FT_TRUETYPE_TABLES_H
#include FT_XFREE86_H
#include FT_FONT_FORMATS_H
#include FT_MULTIPLE_MASTERS_H
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
#include FT_SYNTHESIS_H
#endif
#if HAVE_FT_LIBRARY_SETLCDFILTER
#include FT_LCD_FILTER_H
#endif
#if HAVE_FT_SVG_DOCUMENT
#include FT_OTSVG_H
@ -80,26 +75,6 @@
#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
/* FreeType version older than 2.11 does not have the FT_RENDER_MODE_SDF enum value in FT_Render_Mode */
#if FREETYPE_MAJOR > 2 || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 11)
#define HAVE_FT_RENDER_MODE_SDF 1
@ -109,6 +84,32 @@
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
#define DOUBLE_FROM_16_16(t) ((double)(t) / 65536.0)
/* SCALE() mimics code from commit 399b00a99b2bbc1c56a05974c936aa69a08021f5
* concerning a potential division by 0, but instead of doing a * (1/b), it
* does a/b, thus improving the accuracy. With a * (1/b), for a bitmap font
* of size 13, the computed -y_bearing was 0x1.6000000000001p+3 instead of
* 0x1.6p+3 (= 11). This triggered a bug in GNU Emacs (when built against
* cairo), which rounded the value to an integer with ceil().
* Details:
* https://gitlab.freedesktop.org/cairo/cairo/-/issues/503
* https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44284
*
* Note that rounding errors are not necessarily expected by applications
* in simple cases like the GNU Emacs one (an identity transformation,
* which should normally leave the inputs unchanged). However, with the
* current cairo code, due to the scaling, there is no guarantee that
* rounding errors will always be avoided at the end. For instance,
* (a/b)*b may be different from a, but this is still better than doing
* (a*(1/b))*b.
*
* According to the commit mentioned above, avoiding a division by zero
* was an attempt to fix
* https://bugzilla.gnome.org/show_bug.cgi?id=311299
* but this did not actually solve the problem. So it might be possible
* to change SCALE() to just do (a) / (b).
*/
#define SCALE(a,b) ((b) == 0 ? 0.0 : (a) / (b))
/* This is the max number of FT_face objects we keep open at once
*/
#define MAX_OPEN_FACES 10
@ -315,7 +316,7 @@ _cairo_ft_unscaled_font_map_create (void)
* detect some other call path. */
assert (cairo_ft_unscaled_font_map == NULL);
font_map = _cairo_malloc (sizeof (cairo_ft_unscaled_font_map_t));
font_map = _cairo_calloc (sizeof (cairo_ft_unscaled_font_map_t));
if (unlikely (font_map == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -461,29 +462,19 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled,
unscaled->variations = NULL;
if (from_face) {
FT_MM_Var *ft_mm_var;
unscaled->from_face = TRUE;
_cairo_ft_unscaled_font_init_key (unscaled, TRUE, NULL, id, face);
unscaled->have_color = FT_HAS_COLOR (face) != 0;
unscaled->have_color_set = TRUE;
#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
{
FT_MM_Var *ft_mm_var;
if (0 == FT_Get_MM_Var (face, &ft_mm_var))
{
unscaled->variations = calloc (ft_mm_var->num_axis, sizeof (FT_Fixed));
if (unscaled->variations)
FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, unscaled->variations);
#if HAVE_FT_DONE_MM_VAR
FT_Done_MM_Var (face->glyph->library, ft_mm_var);
#else
free (ft_mm_var);
#endif
}
if (FT_Get_MM_Var (face, &ft_mm_var) == 0) {
unscaled->variations = _cairo_calloc_ab (ft_mm_var->num_axis, sizeof (FT_Fixed));
if (unscaled->variations)
FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, unscaled->variations);
FT_Done_MM_Var (face->glyph->library, ft_mm_var);
}
#endif
} else {
char *filename_copy;
@ -585,7 +576,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
}
/* Otherwise create it and insert into hash table. */
unscaled = _cairo_malloc (sizeof (cairo_ft_unscaled_font_t));
unscaled = _cairo_calloc (sizeof (cairo_ft_unscaled_font_t));
if (unlikely (unscaled == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto UNWIND_FONT_MAP_LOCK;
@ -998,12 +989,10 @@ _compute_xrender_bitmap_size(FT_Bitmap *target,
pitch = width * 4;
break;
#ifdef FT_LOAD_COLOR
case FT_PIXEL_MODE_BGRA:
/* each pixel is replicated into a 32-bit ARGB value */
pitch = width * 4;
break;
#endif
default: /* unsupported source format */
return -1;
@ -1201,12 +1190,10 @@ _fill_xrender_bitmap(FT_Bitmap *target,
}
break;
#ifdef FT_LOAD_COLOR
case FT_PIXEL_MODE_BGRA:
for (h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch)
memcpy (dstLine, srcLine, (size_t)width * 4);
break;
#endif
default:
assert (0);
@ -1315,7 +1302,6 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
component_alpha = TRUE;
}
break;
#ifdef FT_LOAD_COLOR
case FT_PIXEL_MODE_BGRA:
stride = width * 4;
if (own_buffer) {
@ -1334,11 +1320,10 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
unsigned int i, count = height * width;
uint32_t *p = (uint32_t *) data;
for (i = 0; i < count; i++)
p[i] = be32_to_cpu (p[i]);
p[i] = bswap_32 (p[i]);
}
format = CAIRO_FORMAT_ARGB32;
break;
#endif
case FT_PIXEL_MODE_GRAY2:
case FT_PIXEL_MODE_GRAY4:
convert:
@ -1432,7 +1417,7 @@ _render_glyph_outline (FT_Face face,
cairo_font_options_t *font_options,
cairo_image_surface_t **surface)
{
int rgba = FC_RGBA_UNKNOWN;
cairo_subpixel_order_t rgba = CAIRO_SUBPIXEL_ORDER_DEFAULT;
int lcd_filter = FT_LCD_FILTER_DEFAULT;
FT_GlyphSlot glyphslot = face->glyph;
FT_Outline *outline = &glyphslot->outline;
@ -1533,16 +1518,16 @@ _render_glyph_outline (FT_Face face,
switch (render_mode) {
case FT_RENDER_MODE_LCD:
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR)
rgba = FC_RGBA_BGR;
rgba = CAIRO_SUBPIXEL_ORDER_BGR;
else
rgba = FC_RGBA_RGB;
rgba = CAIRO_SUBPIXEL_ORDER_RGB;
break;
case FT_RENDER_MODE_LCD_V:
if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR)
rgba = FC_RGBA_VBGR;
rgba = CAIRO_SUBPIXEL_ORDER_VBGR;
else
rgba = FC_RGBA_VRGB;
rgba = CAIRO_SUBPIXEL_ORDER_VRGB;
break;
case FT_RENDER_MODE_MONO:
@ -1556,16 +1541,10 @@ _render_glyph_outline (FT_Face face,
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 (_cairo_ft_to_cairo_error (error));
@ -1575,12 +1554,12 @@ _render_glyph_outline (FT_Face face,
if (bitmap_size < 0)
return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
bitmap.buffer = calloc (1, bitmap_size);
bitmap.buffer = _cairo_calloc (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));
(rgba == CAIRO_SUBPIXEL_ORDER_BGR || rgba == CAIRO_SUBPIXEL_ORDER_VBGR));
/* Note:
* _get_bitmap_surface will free bitmap.buffer if there is an error
@ -1790,19 +1769,13 @@ _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
char *variations;
_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)
@ -1812,7 +1785,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
if (FcPatternGetBool (pattern,
FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
antialias = FcTrue;
if (antialias) {
cairo_subpixel_order_t subpixel_order;
int lcd_filter;
@ -1870,7 +1843,6 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
}
}
#ifdef FC_HINT_STYLE
if (FcPatternGetInteger (pattern,
FC_HINT_STYLE, 0, &hintstyle) != FcResultMatch)
hintstyle = FC_HINT_FULL;
@ -1893,11 +1865,6 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
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)
@ -1925,9 +1892,6 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
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;
@ -1935,9 +1899,6 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret)
if (embolden)
ft_options.synth_flags |= CAIRO_FT_SYNTHESIZE_BOLD;
#ifndef FC_FONT_VARIATIONS
#define FC_FONT_VARIATIONS "fontvariations"
#endif
if (FcPatternGetString (pattern, FC_FONT_VARIATIONS, 0, (FcChar8 **) &variations) == FcResultMatch) {
ft_options.base.variations = strdup (variations);
}
@ -2061,7 +2022,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
if (unlikely (face == NULL)) /* backend error */
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
scaled_font = _cairo_malloc (sizeof (cairo_ft_scaled_font_t));
scaled_font = _cairo_calloc (sizeof (cairo_ft_scaled_font_t));
if (unlikely (scaled_font == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
@ -2104,27 +2065,15 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
*/
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;
fs_metrics.ascent = SCALE (DOUBLE_FROM_26_6 (metrics->ascender), unscaled->y_scale);
fs_metrics.descent = SCALE (DOUBLE_FROM_26_6 (- metrics->descender), unscaled->y_scale);
fs_metrics.height = SCALE (DOUBLE_FROM_26_6 (metrics->height), unscaled->y_scale);
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_x_advance = SCALE (DOUBLE_FROM_26_6 (metrics->max_advance), unscaled->x_scale);
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;
fs_metrics.max_y_advance = SCALE (DOUBLE_FROM_26_6 (metrics->max_advance), unscaled->y_scale);
}
} else {
double scale = face->units_per_EM;
@ -2173,6 +2122,7 @@ _cairo_ft_scaled_font_fini (void *abstract_font)
if (scaled_font == NULL)
return;
_cairo_font_options_fini (&scaled_font->ft_options.base);
_cairo_unscaled_font_destroy (&scaled_font->unscaled->base);
}
@ -2410,7 +2360,6 @@ skip:
}
current_coords = malloc (sizeof (FT_Fixed) * ft_mm_var->num_axis);
#ifdef HAVE_FT_GET_VAR_DESIGN_COORDINATES
ret = FT_Get_Var_Design_Coordinates (face, ft_mm_var->num_axis, current_coords);
if (ret == 0) {
for (i = 0; i < ft_mm_var->num_axis; i++) {
@ -2420,80 +2369,15 @@ skip:
if (i == ft_mm_var->num_axis)
goto done;
}
#endif
FT_Set_Var_Design_Coordinates (face, ft_mm_var->num_axis, coords);
done:
free (coords);
free (current_coords);
#if HAVE_FT_DONE_MM_VAR
FT_Done_MM_Var (face->glyph->library, ft_mm_var);
#else
free (ft_mm_var);
#endif
}
}
static cairo_int_status_t
_cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph,
FT_Face face,
int load_flags,
cairo_bool_t use_em_size,
cairo_bool_t vertical_layout)
{
FT_Error error;
cairo_status_t status;
if (use_em_size) {
cairo_matrix_t em_size;
cairo_matrix_init_scale (&em_size, face->units_per_EM, face->units_per_EM);
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &em_size);
} else {
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
}
if (unlikely (status))
return status;
cairo_ft_apply_variations (face, scaled_font);
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)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/*
* synthesize glyphs if requested
*/
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
FT_GlyphSlot_Embolden (face->glyph);
#endif
#if HAVE_FT_GLYPHSLOT_OBLIQUE
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
FT_GlyphSlot_Oblique (face->glyph);
#endif
if (vertical_layout)
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph);
if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_Pos xshift, yshift;
xshift = _cairo_scaled_glyph_xphase (scaled_glyph) << 4;
yshift = _cairo_scaled_glyph_yphase (scaled_glyph) << 4;
FT_Outline_Translate (&face->glyph->outline, xshift, -yshift);
}
return CAIRO_STATUS_SUCCESS;
}
typedef enum {
CAIRO_FT_GLYPH_TYPE_BITMAP,
CAIRO_FT_GLYPH_TYPE_OUTLINE,
@ -2508,6 +2392,74 @@ typedef struct {
cairo_ft_glyph_format_t format;
} cairo_ft_glyph_private_t;
static const int ft_glyph_private_key;
static cairo_int_status_t
_cairo_ft_scaled_glyph_load_glyph (cairo_ft_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph,
FT_Face face,
int load_flags,
cairo_bool_t use_em_size,
cairo_bool_t vertical_layout)
{
FT_Error error;
cairo_status_t status;
cairo_ft_glyph_private_t *glyph_priv;
glyph_priv = (cairo_ft_glyph_private_t *) _cairo_scaled_glyph_find_private (scaled_glyph,
&ft_glyph_private_key);
assert (glyph_priv != NULL);
if (use_em_size) {
cairo_matrix_t em_size;
cairo_matrix_init_scale (&em_size, face->units_per_EM, face->units_per_EM);
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &em_size);
} else {
status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
&scaled_font->base.scale);
}
if (unlikely (status))
return status;
cairo_ft_apply_variations (face, scaled_font);
#if defined(HAVE_FT_LOAD_NO_SVG)
if (load_flags & FT_LOAD_COLOR && glyph_priv->format == CAIRO_FT_GLYPH_TYPE_COLR_V1)
load_flags |= FT_LOAD_NO_SVG;
#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)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
/*
* synthesize glyphs if requested
*/
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
FT_GlyphSlot_Embolden (face->glyph);
if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
FT_GlyphSlot_Oblique (face->glyph);
if (vertical_layout)
_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, face->glyph);
if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_Pos xshift, yshift;
xshift = _cairo_scaled_glyph_xphase (scaled_glyph) << 4;
yshift = _cairo_scaled_glyph_yphase (scaled_glyph) << 4;
FT_Outline_Translate (&face->glyph->outline, xshift, -yshift);
}
return CAIRO_STATUS_SUCCESS;
}
static void
_cairo_ft_glyph_fini (cairo_scaled_glyph_private_t *glyph_private,
cairo_scaled_glyph_t *glyph,
@ -2527,7 +2479,6 @@ _cairo_ft_scaled_glyph_set_palette (cairo_ft_scaled_font_t *scaled_font,
unsigned int num_entries = 0;
FT_Color *entries = NULL;
#ifdef HAVE_FT_PALETTE_SELECT
FT_Palette_Data palette_data;
if (FT_Palette_Data_Get (face, &palette_data) == 0 && palette_data.num_palettes > 0) {
@ -2550,7 +2501,6 @@ _cairo_ft_scaled_glyph_set_palette (cairo_ft_scaled_font_t *scaled_font,
}
}
}
#endif
if (num_entries_ret)
*num_entries_ret = num_entries;
@ -2567,7 +2517,6 @@ _cairo_ft_scaled_glyph_set_foreground_color (cairo_ft_scaled_font_t *scaled_font
const cairo_color_t *foreground_color)
{
cairo_bool_t uses_foreground_color = FALSE;
#ifdef HAVE_FT_PALETTE_SELECT
FT_LayerIterator iterator;
FT_UInt layer_glyph_index;
FT_UInt layer_color_index;
@ -2593,7 +2542,7 @@ _cairo_ft_scaled_glyph_set_foreground_color (cairo_ft_scaled_font_t *scaled_font
color.alpha = (FT_Byte)(foreground_color->alpha * 0xFF);
FT_Palette_Set_Foreground_Color (face, color);
}
#endif
return uses_foreground_color;
}
@ -2633,13 +2582,9 @@ _cairo_ft_scaled_glyph_init_surface (cairo_ft_scaled_font_t *scaled_font,
/* clear load target mode */
load_flags &= ~(FT_LOAD_TARGET_(FT_LOAD_TARGET_MODE(load_flags)));
load_flags |= FT_LOAD_TARGET_NORMAL;
#ifdef FT_LOAD_COLOR
load_flags |= FT_LOAD_COLOR;
#endif
} else { /* info == CAIRO_SCALED_GLYPH_INFO_SURFACE */
#ifdef FT_LOAD_COLOR
load_flags &= ~FT_LOAD_COLOR;
#endif
}
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
@ -2710,7 +2655,6 @@ _cairo_ft_scaled_glyph_init_record_colr_v0_glyph (cairo_ft_scaled_font_t *scaled
cairo_bool_t vertical_layout,
int load_flags)
{
#ifdef HAVE_FT_PALETTE_SELECT
cairo_surface_t *recording_surface;
cairo_t *cr;
cairo_status_t status;
@ -2795,9 +2739,6 @@ _cairo_ft_scaled_glyph_init_record_colr_v0_glyph (cairo_ft_scaled_font_t *scaled
recording_surface,
NULL);
return status;
#else
return CAIRO_INT_STATUS_UNSUPPORTED;
#endif
}
static cairo_int_status_t
@ -2867,8 +2808,8 @@ _cairo_ft_scaled_glyph_init_record_colr_v1_glyph (cairo_ft_scaled_font_t *scaled
/* Copied from cairo-user-font.c */
cairo_matrix_t extent_scale;
double extent_x_scale;
double extent_y_scale;
double extent_x_scale = 1.0;
double extent_y_scale = 1.0;
double snap_x_scale;
double snap_y_scale;
double fixed_scale, x_scale, y_scale;
@ -3136,7 +3077,6 @@ _cairo_ft_scaled_glyph_get_metrics (cairo_ft_scaled_font_t *scaled_font,
cairo_text_extents_t *fs_metrics)
{
FT_Glyph_Metrics *metrics;
double x_factor, y_factor;
cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
FT_GlyphSlot glyph = face->glyph;
@ -3146,16 +3086,6 @@ _cairo_ft_scaled_glyph_get_metrics (cairo_ft_scaled_font_t *scaled_font,
*/
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.
*
@ -3180,13 +3110,13 @@ _cairo_ft_scaled_glyph_get_metrics (cairo_ft_scaled_font_t *scaled_font,
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->x_bearing = SCALE (DOUBLE_FROM_26_6 (x1), unscaled->x_scale);
fs_metrics->y_bearing = SCALE (DOUBLE_FROM_26_6 (y1), unscaled->y_scale);
fs_metrics->width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
fs_metrics->height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
fs_metrics->width = SCALE (DOUBLE_FROM_26_6 (x2 - x1), unscaled->x_scale);
fs_metrics->height = SCALE (DOUBLE_FROM_26_6 (y2 - y1), unscaled->y_scale);
fs_metrics->x_advance = DOUBLE_FROM_26_6 (advance) * x_factor;
fs_metrics->x_advance = SCALE (DOUBLE_FROM_26_6 (advance), unscaled->x_scale);
fs_metrics->y_advance = 0;
} else {
x1 = (metrics->vertBearingX) & -64;
@ -3196,37 +3126,37 @@ _cairo_ft_scaled_glyph_get_metrics (cairo_ft_scaled_font_t *scaled_font,
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->x_bearing = SCALE (DOUBLE_FROM_26_6 (x1), unscaled->x_scale);
fs_metrics->y_bearing = SCALE (DOUBLE_FROM_26_6 (y1), unscaled->y_scale);
fs_metrics->width = DOUBLE_FROM_26_6 (x2 - x1) * x_factor;
fs_metrics->height = DOUBLE_FROM_26_6 (y2 - y1) * y_factor;
fs_metrics->width = SCALE (DOUBLE_FROM_26_6 (x2 - x1), unscaled->x_scale);
fs_metrics->height = SCALE (DOUBLE_FROM_26_6 (y2 - y1), unscaled->y_scale);
fs_metrics->x_advance = 0;
fs_metrics->y_advance = DOUBLE_FROM_26_6 (advance) * y_factor;
fs_metrics->y_advance = SCALE (DOUBLE_FROM_26_6 (advance), unscaled->y_scale);
}
} else {
fs_metrics->width = DOUBLE_FROM_26_6 (metrics->width) * x_factor;
fs_metrics->height = DOUBLE_FROM_26_6 (metrics->height) * y_factor;
fs_metrics->width = SCALE (DOUBLE_FROM_26_6 (metrics->width), unscaled->x_scale);
fs_metrics->height = SCALE (DOUBLE_FROM_26_6 (metrics->height), unscaled->y_scale);
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;
fs_metrics->x_bearing = SCALE (DOUBLE_FROM_26_6 (metrics->horiBearingX), unscaled->x_scale);
fs_metrics->y_bearing = SCALE (DOUBLE_FROM_26_6 (-metrics->horiBearingY), unscaled->y_scale);
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
fs_metrics->x_advance = DOUBLE_FROM_26_6 (metrics->horiAdvance) * x_factor;
fs_metrics->x_advance = SCALE (DOUBLE_FROM_26_6 (metrics->horiAdvance), unscaled->x_scale);
else
fs_metrics->x_advance = DOUBLE_FROM_16_16 (glyph->linearHoriAdvance) * x_factor;
fs_metrics->y_advance = 0 * y_factor;
fs_metrics->x_advance = SCALE (DOUBLE_FROM_16_16 (glyph->linearHoriAdvance), unscaled->x_scale);
fs_metrics->y_advance = 0;
} 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_bearing = SCALE (DOUBLE_FROM_26_6 (metrics->vertBearingX), unscaled->x_scale);
fs_metrics->y_bearing = SCALE (DOUBLE_FROM_26_6 (metrics->vertBearingY), unscaled->y_scale);
fs_metrics->x_advance = 0 * x_factor;
fs_metrics->x_advance = 0;
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
fs_metrics->y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
fs_metrics->y_advance = SCALE (DOUBLE_FROM_26_6 (metrics->vertAdvance), unscaled->y_scale);
else
fs_metrics->y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor;
fs_metrics->y_advance = SCALE (DOUBLE_FROM_16_16 (glyph->linearVertAdvance), unscaled->y_scale);
}
}
}
@ -3236,7 +3166,6 @@ _cairo_ft_scaled_glyph_is_colr_v0 (cairo_ft_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph,
FT_Face face)
{
#ifdef HAVE_FT_PALETTE_SELECT
FT_LayerIterator iterator;
FT_UInt layer_glyph_index;
FT_UInt layer_color_index;
@ -3250,7 +3179,7 @@ _cairo_ft_scaled_glyph_is_colr_v0 (cairo_ft_scaled_font_t *scaled_font,
{
return TRUE;
}
#endif
return FALSE;
}
@ -3273,8 +3202,6 @@ _cairo_ft_scaled_glyph_is_colr_v1 (cairo_ft_scaled_font_t *scaled_font,
return FALSE;
}
static const int ft_glyph_private_key;
static cairo_int_status_t
_cairo_ft_scaled_glyph_init_metrics (cairo_ft_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph,
@ -3294,7 +3221,7 @@ _cairo_ft_scaled_glyph_init_metrics (cairo_ft_scaled_font_t *scaled_font,
* cairo_ft_glyph_private_t struct and determine the glyph type.
*/
glyph_priv = _cairo_malloc (sizeof (*glyph_priv));
glyph_priv = _cairo_calloc (sizeof (*glyph_priv));
if (unlikely (glyph_priv == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3305,10 +3232,9 @@ _cairo_ft_scaled_glyph_init_metrics (cairo_ft_scaled_font_t *scaled_font,
/* We need to load color to determine if this is a color format. */
int color_flag = 0;
#ifdef FT_LOAD_COLOR
if (scaled_font->unscaled->have_color && scaled_font->base.options.color_mode != CAIRO_COLOR_MODE_NO_COLOR)
color_flag = FT_LOAD_COLOR;
#endif
/* Ensure use_em_size = FALSE as the format (bitmap or outline)
* may change with the size. */
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
@ -3327,7 +3253,15 @@ _cairo_ft_scaled_glyph_init_metrics (cairo_ft_scaled_font_t *scaled_font,
#endif
if (is_svg_format) {
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_SVG;
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_SVG;
#if defined(HAVE_FT_COLR_V1) && defined(HAVE_FT_LOAD_NO_SVG)
/* Prefer COLRv1 table over SVG table due to performance reasons for now */
if (_cairo_ft_scaled_glyph_is_colr_v1 (scaled_font, scaled_glyph, face)) {
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_COLR_V1;
}
#endif
} else if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
glyph_priv->format = CAIRO_FT_GLYPH_TYPE_OUTLINE;
if (color_flag) {
@ -3419,11 +3353,6 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
cairo_bool_t vertical_layout = FALSE;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
cairo_ft_glyph_private_t *glyph_priv;
int color_flag = 0;
#ifdef FT_LOAD_COLOR
color_flag = FT_LOAD_COLOR;
#endif
face = _cairo_ft_unscaled_font_lock_face (unscaled);
if (!face)
@ -3472,7 +3401,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
scaled_glyph,
face,
load_flags | color_flag,
load_flags | FT_LOAD_COLOR,
FALSE,
vertical_layout);
if (unlikely (status))
@ -3610,7 +3539,6 @@ _cairo_ft_load_truetype_table (void *abstract_font,
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);
@ -3624,7 +3552,6 @@ _cairo_ft_load_truetype_table (void *abstract_font,
}
_cairo_ft_unscaled_font_unlock_face (unscaled);
#endif
return status;
}
@ -3683,6 +3610,7 @@ _cairo_ft_is_synthetic (void *abstract_font,
FT_MM_Var *mm_var = NULL;
FT_Fixed *coords = NULL;
int num_axis;
int i;
/* If this is an MM or variable font we can't assume the current outlines
* are the same as the font tables */
@ -3701,32 +3629,22 @@ _cairo_ft_is_synthetic (void *abstract_font,
goto cleanup;
}
#if FREETYPE_MAJOR > 2 || ( FREETYPE_MAJOR == 2 && FREETYPE_MINOR >= 8)
/* If FT_Get_Var_Blend_Coordinates() is available, we can check if the
* current design coordinates are the default coordinates. In this case
* the current outlines match the font tables.
/* Check if the current design coordinates are the default
* coordinates. In this case the current outlines match the
* font tables.
*/
{
int i;
FT_Get_Var_Blend_Coordinates (face, num_axis, coords);
*is_synthetic = FALSE;
for (i = 0; i < num_axis; i++) {
if (coords[i]) {
*is_synthetic = TRUE;
break;
}
FT_Get_Var_Blend_Coordinates (face, num_axis, coords);
*is_synthetic = FALSE;
for (i = 0; i < num_axis; i++) {
if (coords[i]) {
*is_synthetic = TRUE;
break;
}
}
#endif
cleanup:
free (coords);
#if HAVE_FT_DONE_MM_VAR
FT_Done_MM_Var (face->glyph->library, mm_var);
#else
free (mm_var);
#endif
}
_cairo_ft_unscaled_font_unlock_face (unscaled);
@ -3797,15 +3715,13 @@ _cairo_index_to_glyph_name (void *abstract_font,
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);
const char *font_format = FT_Get_Font_Format (face);
if (font_format &&
(strcmp (font_format, "Type 1") == 0 ||
strcmp (font_format, "CFF") == 0))
{
return TRUE;
}
#endif
return FALSE;
}
@ -3832,12 +3748,10 @@ _cairo_ft_load_type1_data (void *abstract_font,
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;
@ -4118,7 +4032,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
{
cairo_ft_font_face_t *font_face;
font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t));
font_face = _cairo_calloc (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;
@ -4180,7 +4094,7 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled,
}
/* No match found, create a new one */
font_face = _cairo_malloc (sizeof (cairo_ft_font_face_t));
font_face = _cairo_calloc (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;
@ -4307,7 +4221,6 @@ _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
#ifdef FC_HINT_STYLE
if (FcPatternGet (pattern, FC_HINT_STYLE, 0, &v) == FcResultNoMatch)
{
int hint_style;
@ -4332,7 +4245,6 @@ _cairo_ft_font_options_substitute (const cairo_font_options_t *options,
if (! FcPatternAddInteger (pattern, FC_HINT_STYLE, hint_style))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
#endif
}
return CAIRO_STATUS_SUCCESS;

View file

@ -43,6 +43,8 @@
#if CAIRO_HAS_FT_FONT
#include FT_COLOR_H
CAIRO_BEGIN_DECLS
typedef struct _cairo_ft_unscaled_font cairo_ft_unscaled_font_t;

View file

@ -41,7 +41,7 @@
#if CAIRO_HAS_FT_FONT
/* Fontconfig/Freetype platform-specific font interface */
/* Fontconfig/FreeType platform-specific font interface */
#include <ft2build.h>
#include FT_FREETYPE_H

View file

@ -66,7 +66,8 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
cairo_text_cluster_flags_t cluster_flags,
cairo_glyph_t *transformed_glyphs,
int *num_transformed_glyphs,
cairo_text_cluster_t *transformed_clusters);
cairo_text_cluster_t *transformed_clusters,
cairo_bool_t perform_early_clip);
static void
_cairo_gstate_update_device_transform (cairo_observer_t *observer,
@ -193,6 +194,7 @@ void
_cairo_gstate_fini (cairo_gstate_t *gstate)
{
_cairo_stroke_style_fini (&gstate->stroke_style);
_cairo_font_options_fini (&gstate->font_options);
cairo_font_face_destroy (gstate->font_face);
gstate->font_face = NULL;
@ -241,7 +243,7 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
top = *freelist;
if (top == NULL) {
top = _cairo_malloc (sizeof (cairo_gstate_t));
top = _cairo_calloc (sizeof (cairo_gstate_t));
if (unlikely (top == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
} else
@ -1919,6 +1921,8 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate)
&font_ctm,
&options);
_cairo_font_options_fini (&options);
status = cairo_scaled_font_status (scaled_font);
if (unlikely (status))
return status;
@ -2032,14 +2036,16 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
info->cluster_flags,
transformed_glyphs,
&num_glyphs,
transformed_clusters);
transformed_clusters,
TRUE);
} else {
_cairo_gstate_transform_glyphs_to_backend (gstate,
glyphs, num_glyphs,
NULL, 0, 0,
transformed_glyphs,
&num_glyphs,
NULL);
NULL,
TRUE);
}
if (num_glyphs == 0)
@ -2141,7 +2147,7 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
glyphs, num_glyphs,
NULL, 0, 0,
transformed_glyphs,
&num_glyphs, NULL);
&num_glyphs, NULL, FALSE);
status = _cairo_scaled_font_glyph_path (gstate->scaled_font,
transformed_glyphs, num_glyphs,
@ -2195,7 +2201,8 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
cairo_text_cluster_flags_t cluster_flags,
cairo_glyph_t *transformed_glyphs,
int *num_transformed_glyphs,
cairo_text_cluster_t *transformed_clusters)
cairo_text_cluster_t *transformed_clusters,
cairo_bool_t perform_early_clip)
{
cairo_rectangle_int_t surface_extents;
cairo_matrix_t *ctm = &gstate->ctm;
@ -2206,7 +2213,7 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
int i, j, k;
drop = TRUE;
if (! _cairo_gstate_int_clip_extents (gstate, &surface_extents)) {
if (!perform_early_clip || !_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);

View file

@ -164,7 +164,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
{
cairo_hash_table_t *hash_table;
hash_table = _cairo_malloc (sizeof (cairo_hash_table_t));
hash_table = _cairo_calloc (sizeof (cairo_hash_table_t));
if (unlikely (hash_table == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -178,7 +178,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t 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,
hash_table->entries = _cairo_calloc_ab (*hash_table->table_size,
sizeof (cairo_hash_entry_t *));
if (unlikely (hash_table->entries == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
@ -304,7 +304,7 @@ _cairo_hash_table_manage (cairo_hash_table_t *hash_table)
}
new_size = *tmp.table_size;
tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*));
tmp.entries = _cairo_calloc_ab (new_size, sizeof (cairo_hash_entry_t*));
if (unlikely (tmp.entries == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -696,7 +696,6 @@ composite_traps (void *_dst,
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)
{
@ -797,7 +796,6 @@ composite_tristrip (void *_dst,
return CAIRO_STATUS_SUCCESS;
}
#endif
static cairo_int_status_t
check_composite_glyphs (const cairo_composite_rectangles_t *extents,
@ -1296,9 +1294,7 @@ _cairo_image_traps_compositor_get (void)
//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;

View file

@ -1104,7 +1104,7 @@ attach_proxy (cairo_surface_t *source,
{
struct proxy *proxy;
proxy = _cairo_malloc (sizeof (*proxy));
proxy = _cairo_calloc (sizeof (*proxy));
if (unlikely (proxy == NULL))
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
@ -1529,7 +1529,7 @@ _pixman_image_for_raster (cairo_image_surface_t *dst,
return NULL;
}
cleanup = _cairo_malloc (sizeof (*cleanup));
cleanup = _cairo_calloc (sizeof (*cleanup));
if (unlikely (cleanup == NULL)) {
pixman_image_unref (pixman_image);
_cairo_surface_release_source_image (surface, image, extra);
@ -1625,7 +1625,7 @@ _cairo_image_source_create_for_pattern (cairo_surface_t *dst,
TRACE ((stderr, "%s\n", __FUNCTION__));
source = _cairo_malloc (sizeof (cairo_image_source_t));
source = _cairo_calloc (sizeof (cairo_image_source_t));
if (unlikely (source == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

View file

@ -109,11 +109,10 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
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:
#if HAS_PIXMAN_r8g8b8_sRGB
case PIXMAN_r8g8b8_sRGB:
#endif
case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8:
case PIXMAN_b8g8r8: case PIXMAN_b5g6r5:
@ -131,9 +130,7 @@ _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
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;
}
@ -186,7 +183,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
{
cairo_image_surface_t *surface;
surface = _cairo_malloc (sizeof (cairo_image_surface_t));
surface = _cairo_calloc (sizeof (cairo_image_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -248,6 +245,24 @@ _pixman_format_from_masks (cairo_format_masks_t *masks,
return TRUE;
}
/* Convenience function to convert #cairo_dither_t into #pixman_dither_t */
static pixman_dither_t
_cairo_dither_to_pixman_dither (cairo_dither_t dither)
{
switch (dither) {
case CAIRO_DITHER_FAST:
return PIXMAN_DITHER_FAST;
case CAIRO_DITHER_GOOD:
return PIXMAN_DITHER_GOOD;
case CAIRO_DITHER_BEST:
return PIXMAN_DITHER_BEST;
case CAIRO_DITHER_NONE:
case CAIRO_DITHER_DEFAULT:
default:
return PIXMAN_DITHER_NONE;
}
}
/* A mask consisting of N bits set to 1. */
#define MASK(N) ((1UL << (N))-1)
@ -411,9 +426,8 @@ cairo_image_surface_create (cairo_format_t 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_surface_t *
_cairo_image_surface_create_with_content (cairo_content_t content,
int width,
int height)
@ -449,7 +463,7 @@ _cairo_image_surface_create_with_content (cairo_content_t content,
*
* Since: 1.6
**/
int
int
cairo_format_stride_for_width (cairo_format_t format,
int width)
{
@ -466,7 +480,6 @@ cairo_format_stride_for_width (cairo_format_t format,
return CAIRO_STRIDE_FOR_WIDTH_BPP (width, bpp);
}
slim_hidden_def (cairo_format_stride_for_width);
/**
* cairo_image_surface_create_for_data:
@ -513,7 +526,7 @@ slim_hidden_def (cairo_format_stride_for_width);
*
* Since: 1.0
**/
cairo_surface_t *
cairo_surface_t *
cairo_image_surface_create_for_data (unsigned char *data,
cairo_format_t format,
int width,
@ -549,7 +562,6 @@ cairo_image_surface_create_for_data (unsigned char *data,
width, height,
stride);
}
slim_hidden_def (cairo_image_surface_create_for_data);
/**
* cairo_image_surface_get_data:
@ -581,7 +593,6 @@ cairo_image_surface_get_data (cairo_surface_t *surface)
return image_surface->data;
}
slim_hidden_def (cairo_image_surface_get_data);
/**
* cairo_image_surface_get_format:
@ -605,7 +616,6 @@ cairo_image_surface_get_format (cairo_surface_t *surface)
return image_surface->format;
}
slim_hidden_def (cairo_image_surface_get_format);
/**
* cairo_image_surface_get_width:
@ -629,7 +639,6 @@ cairo_image_surface_get_width (cairo_surface_t *surface)
return image_surface->width;
}
slim_hidden_def (cairo_image_surface_get_width);
/**
* cairo_image_surface_get_height:
@ -653,7 +662,6 @@ cairo_image_surface_get_height (cairo_surface_t *surface)
return image_surface->height;
}
slim_hidden_def (cairo_image_surface_get_height);
/**
* cairo_image_surface_get_stride:
@ -681,9 +689,8 @@ cairo_image_surface_get_stride (cairo_surface_t *surface)
return image_surface->stride;
}
slim_hidden_def (cairo_image_surface_get_stride);
cairo_format_t
cairo_format_t
_cairo_format_from_content (cairo_content_t content)
{
switch (content) {
@ -699,7 +706,7 @@ _cairo_format_from_content (cairo_content_t content)
return CAIRO_FORMAT_INVALID;
}
cairo_content_t
cairo_content_t
_cairo_content_from_format (cairo_format_t format)
{
switch (format) {
@ -724,7 +731,7 @@ _cairo_content_from_format (cairo_format_t format)
return CAIRO_CONTENT_COLOR_ALPHA;
}
int
int
_cairo_format_bits_per_pixel (cairo_format_t format)
{
switch (format) {
@ -938,6 +945,8 @@ _cairo_image_surface_paint (void *abstract_surface,
const cairo_clip_t *clip)
{
cairo_image_surface_t *surface = abstract_surface;
pixman_dither_t pixman_dither = _cairo_dither_to_pixman_dither (source->dither);
pixman_image_set_dither (surface->pixman_image, pixman_dither);
TRACE ((stderr, "%s (surface=%d)\n",
__FUNCTION__, surface->base.unique_id));

View file

@ -39,7 +39,7 @@
#include "cairo-list-private.h"
/**
/*< private >
* cairo_list_entry:
* @ptr: the pointer to the #cairo_list_t member.
* @type: the type of the struct.
@ -56,7 +56,7 @@
#define cairo_list_last_entry(ptr, type, member) \
cairo_list_entry((ptr)->prev, type, member)
/**
/*< private >
* cairo_list_foreach:
* @pos: a #cairo_list_t* to use as a loop variable.
* @head: the list.
@ -66,7 +66,7 @@
#define cairo_list_foreach(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
/*< private >
* cairo_list_foreach_entry:
* @pos: a variable of type T * to use as a loop variable.
* @type: the type of the entry struct
@ -80,7 +80,7 @@
&pos->member != (head); \
pos = cairo_list_entry(pos->member.next, type, member))
/**
/*< private >
* cairo_list_foreach_entry_safe:
* @pos: a variable of type T * to use as a loop variable.
* @n: a variable of type T * that point to the next item after @pos.
@ -92,7 +92,7 @@
* iterating. @n is a temporary variable required to support safe
* iterating.
*
* <informalexample><programlisting>
* |[<!-- language="C" -->
* struct foo {
* int a;
* cairo_list_t list;
@ -107,7 +107,7 @@
* printf("%d\n", pos->a);
* cairo_list_del (pos);
* }
* </programlisting></informalexample>
* ]|
**/
#define cairo_list_foreach_entry_safe(pos, n, type, head, member) \
for (pos = cairo_list_entry ((head)->next, type, member),\
@ -115,7 +115,7 @@
&pos->member != (head); \
pos = n, n = cairo_list_entry (n->member.next, type, member))
/**
/*< private >
* cairo_list_foreach_entry:
* @pos: a variable of type T * to use as a loop variable.
* @type: the type of the entry struct
@ -129,7 +129,7 @@
&pos->member != (head); \
pos = cairo_list_entry(pos->member.prev, type, member))
/**
/*< private >
* cairo_list_foreach_entry_safe:
* @pos: a variable of type T * to use as a loop variable.
* @n: a variable of type T * that point to the next item after @pos.
@ -175,7 +175,7 @@ cairo_list_validate_is_empty (const cairo_list_t *head)
#define cairo_list_validate_is_empty(head)
#endif
/**
/*< private >
* cairo_list_init:
* @entry: list entry to initialize
*
@ -200,7 +200,7 @@ __cairo_list_add (cairo_list_t *entry,
prev->next = entry;
}
/**
/*< private >
* cairo_list_add:
* @entry: new entry
* @head: linked list head
@ -216,7 +216,7 @@ cairo_list_add (cairo_list_t *entry, cairo_list_t *head)
cairo_list_validate (head);
}
/**
/*< private >
* cairo_list_add_tail:
* @entry: new entry
* @head: linked list head
@ -245,7 +245,7 @@ _cairo_list_del (cairo_list_t *entry)
__cairo_list_del (entry->prev, entry->next);
}
/**
/*< private >
* cairo_list_del:
* @entry: entry to remove
*
@ -258,7 +258,7 @@ cairo_list_del (cairo_list_t *entry)
cairo_list_init (entry);
}
/**
/*< private >
* cairo_list_move:
* @entry: entry to move
* @head: linked list to move @entry to
@ -274,7 +274,7 @@ cairo_list_move (cairo_list_t *entry, cairo_list_t *head)
cairo_list_validate (head);
}
/**
/*< private >
* cairo_list_move_tail:
* @entry: entry tp move
* @head: linked list to move @entry to
@ -290,7 +290,7 @@ cairo_list_move_tail (cairo_list_t *entry, cairo_list_t *head)
cairo_list_validate (head);
}
/**
/*< private >
* cairo_list_move_list:
* @old: List to move
* @new: List to move to. Should be empty,
@ -304,7 +304,7 @@ cairo_list_move_list (cairo_list_t *old, cairo_list_t *new)
cairo_list_init (old);
}
/**
/*< private >
* cairo_list_is_first:
* @entry: entry to check
* @head: linked list
@ -319,7 +319,7 @@ cairo_list_is_first (const cairo_list_t *entry,
return entry->prev == head;
}
/**
/*< private >
* cairo_list_is_last:
* @entry: entry to check
* @head: linked list
@ -334,7 +334,7 @@ cairo_list_is_last (const cairo_list_t *entry,
return entry->next == head;
}
/**
/*< private >
* cairo_list_is_empty:
* @head: linked list
*
@ -347,7 +347,7 @@ cairo_list_is_empty (const cairo_list_t *head)
return head->next == head;
}
/**
/*< private >
* cairo_list_is_singular:
* @head: linked list
*

View file

@ -62,6 +62,22 @@
#define _cairo_malloc(size) \
((size) != 0 ? malloc(size) : NULL)
/**
* _cairo_calloc:
* @size: size of each element
*
* Allocates @size memory using calloc(). Behaves much like
* calloc(), except that only one parameter is required.
* The memory should be freed using free().
* calloc 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 calloc() failure or overflow.
**/
#define _cairo_calloc(size) \
((size) != 0 ? calloc(1,size) : NULL)
/**
* _cairo_malloc_ab:
* @a: number of elements to allocate
@ -89,6 +105,31 @@ _cairo_malloc_ab(size_t a, size_t size)
return _cairo_malloc(c);
}
/**
* _cairo_calloc_ab:
* @a: number of elements to allocate
* @size: size of each element
*
* Allocates @a*@size memory using _cairo_calloc(), taking care to not
* overflow when doing the multiplication.
*
* @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 calloc() failure or overflow.
**/
static cairo_always_inline void *
_cairo_calloc_ab(size_t a, size_t size)
{
size_t c;
if (_cairo_mul_size_t_overflow (a, size, &c))
return NULL;
return _cairo_calloc(c);
}
/**
* _cairo_realloc_ab:
* @ptr: original pointer to block of memory to be resized

View file

@ -85,7 +85,6 @@ cairo_matrix_init_identity (cairo_matrix_t *matrix)
0, 1,
0, 0);
}
slim_hidden_def(cairo_matrix_init_identity);
/**
* cairo_matrix_init:
@ -118,7 +117,6 @@ cairo_matrix_init (cairo_matrix_t *matrix,
matrix->xy = xy; matrix->yy = yy;
matrix->x0 = x0; matrix->y0 = y0;
}
slim_hidden_def(cairo_matrix_init);
/**
* _cairo_matrix_get_affine:
@ -178,7 +176,6 @@ cairo_matrix_init_translate (cairo_matrix_t *matrix,
0, 1,
tx, ty);
}
slim_hidden_def(cairo_matrix_init_translate);
/**
* cairo_matrix_translate:
@ -202,7 +199,6 @@ cairo_matrix_translate (cairo_matrix_t *matrix, double tx, double ty)
cairo_matrix_multiply (matrix, &tmp, matrix);
}
slim_hidden_def (cairo_matrix_translate);
/**
* cairo_matrix_init_scale:
@ -224,7 +220,6 @@ cairo_matrix_init_scale (cairo_matrix_t *matrix,
0, sy,
0, 0);
}
slim_hidden_def(cairo_matrix_init_scale);
/**
* cairo_matrix_scale:
@ -247,7 +242,6 @@ cairo_matrix_scale (cairo_matrix_t *matrix, double sx, double sy)
cairo_matrix_multiply (matrix, &tmp, matrix);
}
slim_hidden_def(cairo_matrix_scale);
/**
* cairo_matrix_init_rotate:
@ -277,7 +271,6 @@ cairo_matrix_init_rotate (cairo_matrix_t *matrix,
-s, c,
0, 0);
}
slim_hidden_def(cairo_matrix_init_rotate);
/**
* cairo_matrix_rotate:
@ -304,7 +297,6 @@ cairo_matrix_rotate (cairo_matrix_t *matrix, double radians)
cairo_matrix_multiply (matrix, &tmp, matrix);
}
slim_hidden_def (cairo_matrix_rotate);
/**
* cairo_matrix_multiply:
@ -344,7 +336,6 @@ cairo_matrix_multiply (cairo_matrix_t *result, const cairo_matrix_t *a, const ca
*result = r;
}
slim_hidden_def(cairo_matrix_multiply);
void
_cairo_matrix_multiply (cairo_matrix_t *r,
@ -390,7 +381,6 @@ cairo_matrix_transform_distance (const cairo_matrix_t *matrix, double *dx, doubl
*dx = new_x;
*dy = new_y;
}
slim_hidden_def(cairo_matrix_transform_distance);
/**
* cairo_matrix_transform_point:
@ -410,7 +400,6 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix, double *x, double *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,
@ -621,7 +610,6 @@ cairo_matrix_invert (cairo_matrix_t *matrix)
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def(cairo_matrix_invert);
cairo_bool_t
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix)

View file

@ -305,7 +305,7 @@ _cairo_mempool_init (cairo_mempool_t *pool,
pool->max_free_bits = -1;
num_blocks = bytes >> min_bits;
pool->blocks = calloc (num_blocks, sizeof (struct _cairo_memblock));
pool->blocks = _cairo_calloc_ab (num_blocks, sizeof (struct _cairo_memblock));
if (pool->blocks == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -48,6 +48,9 @@
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
COMPILE_TIME_ASSERT ((int)CAIRO_STATUS_LAST_STATUS < (int)CAIRO_INT_STATUS_UNSUPPORTED);
COMPILE_TIME_ASSERT (CAIRO_INT_STATUS_LAST_STATUS <= 127);
@ -184,7 +187,6 @@ cairo_status_to_string (cairo_status_t status)
}
}
/**
* cairo_glyph_allocate:
* @num_glyphs: number of glyphs to allocate
@ -213,7 +215,6 @@ cairo_glyph_allocate (int num_glyphs)
return _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
}
slim_hidden_def (cairo_glyph_allocate);
/**
* cairo_glyph_free:
@ -233,7 +234,6 @@ cairo_glyph_free (cairo_glyph_t *glyphs)
{
free (glyphs);
}
slim_hidden_def (cairo_glyph_free);
/**
* cairo_text_cluster_allocate:
@ -263,7 +263,6 @@ cairo_text_cluster_allocate (int num_clusters)
return _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
}
slim_hidden_def (cairo_text_cluster_allocate);
/**
* cairo_text_cluster_free:
@ -283,8 +282,6 @@ cairo_text_cluster_free (cairo_text_cluster_t *clusters)
{
free (clusters);
}
slim_hidden_def (cairo_text_cluster_free);
/* Private stuff */
@ -809,12 +806,12 @@ get_C_locale (void)
locale_t C;
retry:
C = (locale_t) _cairo_atomic_ptr_get ((void **) &C_locale);
C = (locale_t) _cairo_atomic_ptr_get ((cairo_atomic_intptr_t *) &C_locale);
if (unlikely (!C)) {
C = newlocale (LC_ALL_MASK, "C", NULL);
if (!_cairo_atomic_ptr_cmpxchg ((void **) &C_locale, NULL, C)) {
if (!_cairo_atomic_ptr_cmpxchg ((cairo_atomic_intptr_t *) &C_locale, NULL, C)) {
freelocale (C_locale);
goto retry;
}
@ -962,14 +959,40 @@ _cairo_fopen (const char *filename, const char *mode, FILE **file_out)
return status;
}
result = _wfopen(filename_w, mode_w);
result = _wfopen (filename_w, mode_w);
free (filename_w);
free (mode_w);
#else /* Use fopen directly */
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)
/* Glibc 2.7 supports the "e" mode flag that opens the file with O_CLOEXEC.
* this avoid the race condition in the fcntl fallback below. */
char new_mode[20];
snprintf (new_mode, sizeof (new_mode), "%s%s", mode, "e");
result = fopen (filename, new_mode);
#else /* fopen "e" not available */
result = fopen (filename, mode);
#endif
#if defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
/* Manually set CLOEXEC */
if (result != NULL) {
int fd = fileno (result);
if (fd != -1) {
int flags = fcntl (fd, F_GETFD);
if (flags >= 0)
flags = fcntl (fd, F_SETFD, flags | FD_CLOEXEC);
}
}
#endif /* defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) */
#endif /* fopen "e" not available */
#endif /* !_WIN32 */
*file_out = result;
@ -977,18 +1000,15 @@ _cairo_fopen (const char *filename, const char *mode, FILE **file_out)
}
#ifdef _WIN32
#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 insufficient privileges. However, this isn't a
* problem on Windows CE so we don't use it there.
* may fail due to insufficient privileges.
*/
FILE *
static FILE *
_cairo_win32_tmpfile (void)
{
DWORD path_len;
@ -1002,7 +1022,7 @@ _cairo_win32_tmpfile (void)
if (path_len <= 0 || path_len >= MAX_PATH)
return NULL;
if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
if (GetTempFileNameW (path_name, L"cairo_", 0, file_name) == 0)
return NULL;
handle = CreateFileW (file_name,
@ -1031,10 +1051,60 @@ _cairo_win32_tmpfile (void)
return fp;
}
#endif /* !_WIN32_WCE */
#endif /* _WIN32 */
/**
* _cairo_tmpfile:
*
* Exactly like the C library function. On platforms that support
* O_CLOEXEC, the file will be opened with this flag. On Windows, the
* file is opened in the temp directory instead of the root directory.
*
* Return value: a file handle or NULL on error.
**/
FILE *
_cairo_tmpfile (void)
{
#ifdef _WIN32
return _cairo_win32_tmpfile ();
#else /* !_WIN32 */
int fd;
FILE *file;
int flags;
#ifdef O_TMPFILE
fd = open(P_tmpdir,
O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC,
0600);
if (fd == -1 && errno == ENOENT) {
fd = open("/tmp",
O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC,
0600);
}
if (fd != -1)
return fdopen (fd, "wb+");
/* Fallback */
#endif /* O_TMPFILE */
file = tmpfile();
#if defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC)
/* Manually set CLOEXEC */
if (file != NULL) {
fd = fileno(file);
if (fd != -1) {
flags = fcntl(fd, F_GETFD);
if (flags >= 0 && !(flags & FD_CLOEXEC))
fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
}
#endif /* defined(HAVE_FCNTL_H) && defined(FD_CLOEXEC) */
return file;
#endif /* !_WIN32 */
}
typedef struct _cairo_intern_string {
cairo_hash_entry_t hash_entry;
int len;

View file

@ -562,7 +562,7 @@ _cairo_mono_scan_converter_create (int xmin,
cairo_mono_scan_converter_t *self;
cairo_status_t status;
self = _cairo_malloc (sizeof(struct _cairo_mono_scan_converter));
self = _cairo_calloc (sizeof(struct _cairo_mono_scan_converter));
if (unlikely (self == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto bail_nomem;

View file

@ -53,7 +53,6 @@ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
#if CAIRO_HAS_WIN32_FONT
CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
CAIRO_MUTEX_DECLARE (_cairo_win32_font_dc_mutex)
#endif
#if CAIRO_HAS_XLIB_SURFACE

View file

@ -53,9 +53,15 @@ 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
#if HAS_ATOMIC_OPS
cairo_private extern cairo_atomic_int_t _cairo_mutex_initialized;
#else
cairo_private extern int _cairo_mutex_initialized;
#endif
#endif
/* Finally, extern the static mutexes and undef */
#define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex;

View file

@ -51,7 +51,11 @@
# define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE _CAIRO_MUTEX_INITIALIZED
# endif
#if HAS_ATOMIC_OPS
cairo_atomic_int_t _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
#else
int _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
#endif
# undef _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE

View file

@ -148,7 +148,7 @@ _cairo_output_stream_create (cairo_write_func_t write_func,
{
cairo_output_stream_with_closure_t *stream;
stream = _cairo_malloc (sizeof (cairo_output_stream_with_closure_t));
stream = _cairo_calloc (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;
@ -174,7 +174,7 @@ _cairo_output_stream_create_in_error (cairo_status_t status)
if (status == CAIRO_STATUS_WRITE_ERROR)
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
stream = _cairo_malloc (sizeof (cairo_output_stream_t));
stream = _cairo_calloc (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;
@ -655,7 +655,7 @@ _cairo_output_stream_create_for_file (FILE *file)
return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error;
}
stream = _cairo_malloc (sizeof *stream);
stream = _cairo_calloc (sizeof *stream);
if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@ -694,7 +694,7 @@ _cairo_output_stream_create_for_filename (const char *filename)
}
}
stream = _cairo_malloc (sizeof *stream);
stream = _cairo_calloc (sizeof *stream);
if (unlikely (stream == NULL)) {
fclose (file);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
@ -738,7 +738,7 @@ _cairo_memory_stream_create (void)
{
memory_stream_t *stream;
stream = _cairo_malloc (sizeof *stream);
stream = _cairo_calloc (sizeof *stream);
if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;
@ -765,7 +765,7 @@ _cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream,
stream = (memory_stream_t *) abstract_stream;
*length_out = _cairo_array_num_elements (&stream->array);
*data_out = _cairo_malloc (*length_out);
*data_out = _cairo_calloc (*length_out);
if (unlikely (*data_out == NULL)) {
status = _cairo_output_stream_destroy (abstract_stream);
assert (status == CAIRO_STATUS_SUCCESS);
@ -812,7 +812,7 @@ _cairo_null_stream_create (void)
{
cairo_output_stream_t *stream;
stream = _cairo_malloc (sizeof *stream);
stream = _cairo_calloc (sizeof *stream);
if (unlikely (stream == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_output_stream_t *) &_cairo_output_stream_nil;

View file

@ -99,7 +99,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
cairo_paginated_surface_t *surface;
cairo_status_t status;
surface = _cairo_malloc (sizeof (cairo_paginated_surface_t));
surface = _cairo_calloc (sizeof (cairo_paginated_surface_t));
if (unlikely (surface == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto FAIL;

View file

@ -325,7 +325,7 @@ _cairo_path_fixed_create (void)
{
cairo_path_fixed_t *path;
path = _cairo_malloc (sizeof (cairo_path_fixed_t));
path = _cairo_calloc (sizeof (cairo_path_fixed_t));
if (!path) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;

View file

@ -162,6 +162,10 @@ _cairo_stroker_init (cairo_stroker_t *stroker,
stroker->has_first_face = FALSE;
stroker->has_initial_sub_path = FALSE;
/* Coverity complains these may be unitialized. */
memset (&stroker->current_face, 0, sizeof (cairo_stroke_face_t));
memset (&stroker->first_face, 0, sizeof (cairo_stroke_face_t));
_cairo_stroker_dash_init (&stroker->dash, stroke_style);
stroker->add_external_edge = NULL;

View file

@ -294,7 +294,7 @@ _cairo_path_create_in_error (cairo_status_t status)
if (status == CAIRO_STATUS_NO_MEMORY)
return (cairo_path_t*) &_cairo_path_nil;
path = _cairo_malloc (sizeof (cairo_path_t));
path = _cairo_calloc (sizeof (cairo_path_t));
if (unlikely (path == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_path_t*) &_cairo_path_nil;
@ -314,7 +314,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed,
{
cairo_path_t *path;
path = _cairo_malloc (sizeof (cairo_path_t));
path = _cairo_calloc (sizeof (cairo_path_t));
if (unlikely (path == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_path_t*) &_cairo_path_nil;
@ -372,7 +372,6 @@ cairo_path_destroy (cairo_path_t *path)
free (path);
}
slim_hidden_def (cairo_path_destroy);
/**
* _cairo_path_create:

View file

@ -52,6 +52,7 @@ enum {
CAIRO_PATTERN_NOTIFY_FILTER = 0x2,
CAIRO_PATTERN_NOTIFY_EXTEND = 0x4,
CAIRO_PATTERN_NOTIFY_OPACITY = 0x9,
CAIRO_PATTERN_NOTIFY_DITHER = 0x12,
};
struct _cairo_pattern_observer {
@ -73,6 +74,7 @@ struct _cairo_pattern {
cairo_extend_t extend;
cairo_bool_t has_component_alpha;
cairo_bool_t is_foreground_marker;
cairo_dither_t dither;
cairo_matrix_t matrix;
double opacity;

View file

@ -63,6 +63,14 @@
* functions.
**/
/**
* CAIRO_HAS_MIME_SURFACE:
*
* Unused symbol, always defined.
*
* Since: 1.12
**/
static freed_pool_t freed_pattern_pool[5];
static const cairo_solid_pattern_t _cairo_pattern_nil = {
@ -77,6 +85,7 @@ static const cairo_solid_pattern_t _cairo_pattern_nil = {
CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */
FALSE, /* has component alpha */
FALSE, /* is_foreground_marker */
CAIRO_DITHER_DEFAULT, /* dither */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
1.0 /* opacity */
}
@ -94,6 +103,7 @@ static const cairo_solid_pattern_t _cairo_pattern_nil_null_pointer = {
CAIRO_EXTEND_GRADIENT_DEFAULT, /* extend */
FALSE, /* has component alpha */
FALSE, /* is_foreground_marker */
CAIRO_DITHER_DEFAULT, /* dither */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
1.0 /* opacity */
}
@ -111,6 +121,7 @@ const cairo_solid_pattern_t _cairo_pattern_black = {
CAIRO_EXTEND_REPEAT, /* extend */
FALSE, /* has component alpha */
FALSE, /* is_foreground_marker */
CAIRO_DITHER_DEFAULT, /* dither */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
1.0 /* opacity */
},
@ -129,6 +140,7 @@ const cairo_solid_pattern_t _cairo_pattern_clear = {
CAIRO_EXTEND_REPEAT, /* extend */
FALSE, /* has component alpha */
FALSE, /* is_foreground_marker */
CAIRO_DITHER_DEFAULT, /* dither */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
1.0 /* opacity */
},
@ -147,6 +159,7 @@ const cairo_solid_pattern_t _cairo_pattern_white = {
CAIRO_EXTEND_REPEAT, /* extend */
FALSE, /* has component alpha */
FALSE, /* is_foreground_marker */
CAIRO_DITHER_DEFAULT, /* dither */
{ 1., 0., 0., 1., 0., 0., }, /* matrix */
1.0 /* opacity */
},
@ -240,6 +253,8 @@ _cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
pattern->has_component_alpha = FALSE;
pattern->is_foreground_marker = FALSE;
pattern->dither = CAIRO_DITHER_DEFAULT;
cairo_matrix_init_identity (&pattern->matrix);
cairo_list_init (&pattern->observers);
@ -611,7 +626,7 @@ _cairo_pattern_create_solid (const cairo_color_t *color)
_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SOLID]);
if (unlikely (pattern == NULL)) {
/* None cached, need to create a new pattern. */
pattern = _cairo_malloc (sizeof (cairo_solid_pattern_t));
pattern = _cairo_calloc (sizeof (cairo_solid_pattern_t));
if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil;
@ -676,7 +691,6 @@ 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:
@ -720,7 +734,6 @@ cairo_pattern_create_rgba (double red, double green, double blue,
return _cairo_pattern_create_solid (&color);
}
slim_hidden_def (cairo_pattern_create_rgba);
/**
* cairo_pattern_create_for_surface:
@ -755,7 +768,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
pattern =
_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SURFACE]);
if (unlikely (pattern == NULL)) {
pattern = _cairo_malloc (sizeof (cairo_surface_pattern_t));
pattern = _cairo_calloc (sizeof (cairo_surface_pattern_t));
if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *)&_cairo_pattern_nil.base;
@ -769,7 +782,6 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
return &pattern->base;
}
slim_hidden_def (cairo_pattern_create_for_surface);
/**
* cairo_pattern_create_linear:
@ -807,7 +819,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
pattern =
_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_LINEAR]);
if (unlikely (pattern == NULL)) {
pattern = _cairo_malloc (sizeof (cairo_linear_pattern_t));
pattern = _cairo_calloc (sizeof (cairo_linear_pattern_t));
if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@ -821,7 +833,6 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
return &pattern->base.base;
}
slim_hidden_def (cairo_pattern_create_linear);
/**
* cairo_pattern_create_radial:
@ -862,7 +873,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
pattern =
_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_RADIAL]);
if (unlikely (pattern == NULL)) {
pattern = _cairo_malloc (sizeof (cairo_radial_pattern_t));
pattern = _cairo_calloc (sizeof (cairo_radial_pattern_t));
if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@ -876,7 +887,6 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
return &pattern->base.base;
}
slim_hidden_def (cairo_pattern_create_radial);
/* This order is specified in the diagram in the documentation for
* cairo_pattern_create_mesh() */
@ -1041,7 +1051,7 @@ cairo_pattern_create_mesh (void)
pattern =
_freed_pool_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_MESH]);
if (unlikely (pattern == NULL)) {
pattern = _cairo_malloc (sizeof (cairo_mesh_pattern_t));
pattern = _cairo_calloc (sizeof (cairo_mesh_pattern_t));
if (unlikely (pattern == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
@ -1057,7 +1067,6 @@ cairo_pattern_create_mesh (void)
return &pattern->base;
}
slim_hidden_def (cairo_pattern_create_mesh);
/**
* cairo_pattern_reference:
@ -1087,7 +1096,6 @@ cairo_pattern_reference (cairo_pattern_t *pattern)
return pattern;
}
slim_hidden_def (cairo_pattern_reference);
/**
* cairo_pattern_get_type:
@ -1105,7 +1113,6 @@ cairo_pattern_get_type (cairo_pattern_t *pattern)
{
return pattern->type;
}
slim_hidden_def (cairo_pattern_get_type);
/**
* cairo_pattern_status:
@ -1159,7 +1166,6 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
else
free (pattern);
}
slim_hidden_def (cairo_pattern_destroy);
/**
* cairo_pattern_get_reference_count:
@ -1293,7 +1299,6 @@ cairo_mesh_pattern_begin_patch (cairo_pattern_t *pattern)
for (i = 0; i < 4; i++)
mesh->has_color[i] = FALSE;
}
slim_hidden_def (cairo_mesh_pattern_begin_patch);
static void
_calc_control_point (cairo_mesh_patch_t *patch, int control_point)
@ -1410,7 +1415,6 @@ cairo_mesh_pattern_end_patch (cairo_pattern_t *pattern)
mesh->current_patch = NULL;
}
slim_hidden_def (cairo_mesh_pattern_end_patch);
/**
* cairo_mesh_pattern_curve_to:
@ -1500,7 +1504,6 @@ cairo_mesh_pattern_curve_to (cairo_pattern_t *pattern,
mesh->current_patch->points[i][j].y = y3;
}
}
slim_hidden_def (cairo_mesh_pattern_curve_to);
/**
* cairo_mesh_pattern_line_to:
@ -1571,7 +1574,6 @@ cairo_mesh_pattern_line_to (cairo_pattern_t *pattern,
(last_point.y + 2 * y) * (1. / 3),
x, y);
}
slim_hidden_def (cairo_mesh_pattern_line_to);
/**
* cairo_mesh_pattern_move_to:
@ -1621,7 +1623,6 @@ cairo_mesh_pattern_move_to (cairo_pattern_t *pattern,
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:
@ -1840,7 +1841,6 @@ cairo_mesh_pattern_set_corner_color_rgba (cairo_pattern_t *pattern,
_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,
@ -1984,7 +1984,6 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern,
_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:
@ -2041,7 +2040,6 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern,
if (unlikely (status))
status = _cairo_pattern_set_error (pattern, status);
}
slim_hidden_def (cairo_pattern_set_matrix);
/**
* cairo_pattern_get_matrix:
@ -2107,6 +2105,45 @@ cairo_pattern_get_filter (cairo_pattern_t *pattern)
return pattern->filter;
}
/**
* cairo_pattern_get_dither:
* @pattern: a #cairo_pattern_t
*
* Gets the current dithering mode, as set by
* cairo_pattern_set_dither().
*
* Return value: the current dithering mode.
*
* Since: 1.18
**/
cairo_dither_t
cairo_pattern_get_dither (cairo_pattern_t *pattern)
{
return pattern->dither;
}
/**
* cairo_pattern_set_dither:
* @pattern: a #cairo_pattern_t
* @dither: a #cairo_dither_t describing the new dithering mode
*
* Set the dithering 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, only pixman is supported.
*
* Since: 1.18
**/
void
cairo_pattern_set_dither (cairo_pattern_t *pattern, cairo_dither_t dither)
{
if (pattern->status)
return;
pattern->dither = dither;
_cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_DITHER);
}
/**
* cairo_pattern_set_extend:
* @pattern: a #cairo_pattern_t
@ -2131,7 +2168,6 @@ cairo_pattern_set_extend (cairo_pattern_t *pattern, cairo_extend_t extend)
pattern->extend = extend;
_cairo_pattern_notify_observers (pattern, CAIRO_PATTERN_NOTIFY_EXTEND);
}
slim_hidden_def (cairo_pattern_set_extend);
/**
* cairo_pattern_get_extend:
@ -2150,7 +2186,6 @@ 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,
@ -2714,7 +2749,6 @@ _cairo_gradient_pattern_interpolate (const cairo_gradient_pattern_t *gradient,
#undef lerp
}
/**
* _cairo_gradient_pattern_fit_to_range:
*
@ -2767,6 +2801,12 @@ _cairo_gradient_pattern_fit_to_range (const cairo_gradient_pattern_t *gradient,
dim = MAX (dim, fabs (radial->cd1.center.y - radial->cd2.center.y));
dim = MAX (dim, fabs (radial->cd1.radius - radial->cd2.radius));
}
dim = MAX (dim, fabs (gradient->base.matrix.xx));
dim = MAX (dim, fabs (gradient->base.matrix.xy));
dim = MAX (dim, fabs (gradient->base.matrix.x0));
dim = MAX (dim, fabs (gradient->base.matrix.yx));
dim = MAX (dim, fabs (gradient->base.matrix.yy));
dim = MAX (dim, fabs (gradient->base.matrix.y0));
if (unlikely (dim > max_value)) {
cairo_matrix_t scale;
@ -4213,7 +4253,6 @@ cairo_pattern_get_rgba (cairo_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_pattern_get_rgba);
/**
* cairo_pattern_get_surface:
@ -4463,7 +4502,6 @@ cairo_mesh_pattern_get_patch_count (cairo_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_mesh_pattern_get_patch_count);
/**
* cairo_mesh_pattern_get_path:
@ -4509,12 +4547,12 @@ cairo_mesh_pattern_get_path (cairo_pattern_t *pattern,
patch = _cairo_array_index_const (&mesh->patches, patch_num);
path = _cairo_malloc (sizeof (cairo_path_t));
path = _cairo_calloc (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,
path->data = _cairo_calloc_ab (path->num_data,
sizeof (cairo_path_data_t));
if (path->data == NULL) {
free (path);
@ -4551,7 +4589,6 @@ cairo_mesh_pattern_get_path (cairo_pattern_t *pattern,
return path;
}
slim_hidden_def (cairo_mesh_pattern_get_path);
/**
* cairo_mesh_pattern_get_corner_color_rgba:
@ -4621,7 +4658,6 @@ cairo_mesh_pattern_get_corner_color_rgba (cairo_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_mesh_pattern_get_corner_color_rgba);
/**
* cairo_mesh_pattern_get_control_point:
@ -4686,7 +4722,6 @@ cairo_mesh_pattern_get_control_point (cairo_pattern_t *pattern,
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_mesh_pattern_get_control_point);
void
_cairo_pattern_reset_static_data (void)

View file

@ -52,6 +52,7 @@
#include "cairo-array-private.h"
#include "cairo-error-private.h"
#include "cairo-output-stream-private.h"
#include "cairo-recording-surface-inline.h"
#include "cairo-recording-surface-private.h"
#include "cairo-surface-snapshot-inline.h"
@ -159,7 +160,7 @@ command_list_push_group (cairo_pdf_surface_t *surface,
cairo_pdf_recording_surface_commands_t recording_commands;
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
group = _cairo_malloc (sizeof(cairo_pdf_command_list_t));
group = _cairo_calloc (sizeof(cairo_pdf_command_list_t));
_cairo_array_init (&group->commands, sizeof(cairo_pdf_command_t));
group->parent = ic->current_commands;
@ -373,7 +374,7 @@ add_tree_node (cairo_pdf_surface_t *surface,
cairo_pdf_struct_tree_node_t *node;
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
node = _cairo_malloc (sizeof(cairo_pdf_struct_tree_node_t));
node = _cairo_calloc (sizeof(cairo_pdf_struct_tree_node_t));
if (unlikely (node == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -483,7 +484,7 @@ add_annotation (cairo_pdf_surface_t *surface,
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_pdf_annotation_t *annot;
annot = _cairo_malloc (sizeof (cairo_pdf_annotation_t));
annot = _cairo_calloc (sizeof (cairo_pdf_annotation_t));
if (unlikely (annot == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -767,13 +768,11 @@ static cairo_int_status_t
cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
cairo_link_attrs_t *link_attrs)
{
cairo_int_status_t status;
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_pdf_forward_link_t *link;
cairo_pdf_resource_t link_res;
/* If the dest is known, emit an explicit dest */
if (link_attrs->dest) {
if (link_attrs->link_type == TAG_LINK_DEST_AND_URI || link_attrs->link_type == TAG_LINK_DEST) {
cairo_pdf_named_dest_t key;
cairo_pdf_named_dest_t *named_dest;
@ -796,53 +795,56 @@ cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
if (named_dest->attrs.y_valid)
y = named_dest->attrs.y;
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
status = cairo_pdf_interchange_write_explicit_dest (surface,
named_dest->page,
TRUE,
x, y);
if (named_dest->attrs.internal) {
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
status = cairo_pdf_interchange_write_explicit_dest (surface,
named_dest->page,
TRUE,
x, y);
} else {
char *name = NULL;
status = _cairo_utf8_to_pdf_string (named_dest->attrs.name, &name);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest %s\n",
name);
free (name);
}
return status;
}
}
/* If the page is known, emit an explicit dest */
if (!link_attrs->dest) {
if (link_attrs->page < 1)
return _cairo_tag_error ("Link attribute: \"page=%d\" page must be >= 1", link_attrs->page);
if (link_attrs->page <= (int)_cairo_array_num_elements (&surface->pages)) {
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
return cairo_pdf_interchange_write_explicit_dest (surface,
link_attrs->page,
link_attrs->has_pos,
link_attrs->pos.x,
link_attrs->pos.y);
/* name does not exist */
if (link_attrs->link_type == TAG_LINK_DEST_AND_URI) {
/* Don't emit anything. The caller will fallback to emitting a URI destination. */
return CAIRO_INT_STATUS_NOTHING_TO_DO;
}
/* Mising destination. Emit a "do nothing" dest that points to the same page and position. */
_cairo_tag_warning ("Link to dest=\"%s\" not found", link_attrs->dest);
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
status = cairo_pdf_interchange_write_explicit_dest (surface,
link_attrs->link_page,
FALSE,
0, 0);
return status;
}
/* Link refers to a future or unknown page. Use an indirect object
* and write the link at the end of the document */
/* link_attrs->link_type == TAG_LINK_PAGE */
link = _cairo_malloc (sizeof (cairo_pdf_forward_link_t));
if (unlikely (link == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (link_attrs->page < 1)
return _cairo_tag_error ("Link attribute: \"page=%d\" page must be >= 1", link_attrs->page);
link_res = _cairo_pdf_surface_new_object (surface);
if (link_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (link_attrs->page > (int)_cairo_array_num_elements (&surface->pages))
return _cairo_tag_error ("Link attribute: \"page=%d\" page exceeds page count (%d)",
link_attrs->page, _cairo_array_num_elements (&surface->pages));
_cairo_output_stream_printf (surface->object_stream.stream,
" /Dest %d 0 R\n",
link_res.id);
link->res = link_res;
link->dest = link_attrs->dest ? strdup (link_attrs->dest) : NULL;
link->page = link_attrs->page;
link->has_pos = link_attrs->has_pos;
link->pos = link_attrs->pos;
status = _cairo_array_append (&surface->forward_links, link);
return status;
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
return cairo_pdf_interchange_write_explicit_dest (surface,
link_attrs->page,
link_attrs->has_pos,
link_attrs->pos.x,
link_attrs->pos.y);
}
static cairo_int_status_t
@ -917,12 +919,20 @@ cairo_pdf_interchange_write_link_action (cairo_pdf_surface_t *surface,
cairo_int_status_t status;
char *dest = NULL;
if (link_attrs->link_type == TAG_LINK_DEST) {
if (link_attrs->link_type == TAG_LINK_DEST_AND_URI ||
link_attrs->link_type == TAG_LINK_DEST ||
link_attrs->link_type == TAG_LINK_PAGE)
{
status = cairo_pdf_interchange_write_dest (surface, link_attrs);
if (unlikely (status))
if (status != CAIRO_INT_STATUS_NOTHING_TO_DO)
return status;
} else if (link_attrs->link_type == TAG_LINK_URI) {
/* CAIRO_INT_STATUS_NOTHING_TO_DO means that the link type is TAG_LINK_DEST_AND_URI
* and the DEST is missing. Fall through to writing a URI link below.
*/
}
if (link_attrs->link_type == TAG_LINK_URI || link_attrs->link_type == TAG_LINK_DEST_AND_URI) {
status = _cairo_utf8_to_pdf_string (link_attrs->uri, &dest);
if (unlikely (status))
return status;
@ -1459,67 +1469,6 @@ strcmp_null (const char *s1, const char *s2)
return FALSE;
}
static cairo_int_status_t
cairo_pdf_interchange_write_forward_links (cairo_pdf_surface_t *surface)
{
int num_elems, i;
cairo_pdf_forward_link_t *link;
cairo_int_status_t status;
cairo_pdf_named_dest_t key;
cairo_pdf_named_dest_t *named_dest;
cairo_pdf_interchange_t *ic = &surface->interchange;
num_elems = _cairo_array_num_elements (&surface->forward_links);
for (i = 0; i < num_elems; i++) {
link = _cairo_array_index (&surface->forward_links, i);
if (link->page > (int)_cairo_array_num_elements (&surface->pages))
return _cairo_tag_error ("Link attribute: \"page=%d\" page exceeds page count (%d)",
link->page, _cairo_array_num_elements (&surface->pages));
status = _cairo_pdf_surface_object_begin (surface, link->res);
if (unlikely (status))
return status;
if (link->dest) {
key.attrs.name = link->dest;
init_named_dest_key (&key);
named_dest = _cairo_hash_table_lookup (ic->named_dests, &key.base);
if (named_dest) {
double x = 0;
double y = 0;
if (named_dest->extents.valid) {
x = named_dest->extents.extents.x;
y = named_dest->extents.extents.y;
}
if (named_dest->attrs.x_valid)
x = named_dest->attrs.x;
if (named_dest->attrs.y_valid)
y = named_dest->attrs.y;
status = cairo_pdf_interchange_write_explicit_dest (surface,
named_dest->page,
TRUE,
x, y);
} else {
return _cairo_tag_error ("Link to dest=\"%s\" not found", link->dest);
}
} else {
cairo_pdf_interchange_write_explicit_dest (surface,
link->page,
link->has_pos,
link->pos.x,
link->pos.y);
}
_cairo_pdf_surface_object_end (surface);
}
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
{
@ -1634,7 +1583,7 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
}
ic->sorted_dests = calloc (ic->num_dests, sizeof (cairo_pdf_named_dest_t *));
ic->sorted_dests = _cairo_calloc_ab (ic->num_dests, sizeof (cairo_pdf_named_dest_t *));
if (unlikely (ic->sorted_dests == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1657,6 +1606,7 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
cairo_pdf_named_dest_t *dest = ic->sorted_dests[i];
double x = 0;
double y = 0;
char *name = NULL;
if (dest->attrs.internal)
continue;
@ -1672,13 +1622,19 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
if (dest->attrs.y_valid)
y = dest->attrs.y;
status = _cairo_utf8_to_pdf_string (dest->attrs.name, &name);
if (unlikely (status))
return status;
page_info = _cairo_array_index (&surface->pages, dest->page - 1);
_cairo_output_stream_printf (surface->object_stream.stream,
" (%s) [%d 0 R /XYZ %f %f 0]\n",
dest->attrs.name,
" %s [%d 0 R /XYZ %f %f 0]\n",
name,
page_info->page_res.id,
x,
page_info->height - y);
free (name);
}
_cairo_output_stream_printf (surface->object_stream.stream,
" ]\n"
@ -1810,7 +1766,7 @@ _cairo_pdf_interchange_begin_structure_tag (cairo_pdf_surface_t *surface,
return status;
/* Add to command_id to node map. */
command_entry = _cairo_malloc (sizeof(cairo_pdf_command_entry_t));
command_entry = _cairo_calloc (sizeof(cairo_pdf_command_entry_t));
command_entry->recording_id = ic->recording_id;
command_entry->command_id = ic->command_id;
command_entry->node = ic->current_analyze_node;
@ -1826,7 +1782,7 @@ _cairo_pdf_interchange_begin_structure_tag (cairo_pdf_surface_t *surface,
}
if (ic->current_analyze_node->type == PDF_NODE_CONTENT) {
cairo_pdf_content_tag_t *content = _cairo_malloc (sizeof(cairo_pdf_content_tag_t));
cairo_pdf_content_tag_t *content = _cairo_calloc (sizeof(cairo_pdf_content_tag_t));
content->node = ic->current_analyze_node;
_cairo_pdf_content_tag_init_key (content);
status = _cairo_hash_table_insert (ic->content_tag_map, &content->base);
@ -1882,7 +1838,7 @@ _cairo_pdf_interchange_begin_dest_tag (cairo_pdf_surface_t *surface,
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
dest = calloc (1, sizeof (cairo_pdf_named_dest_t));
dest = _cairo_calloc (sizeof (cairo_pdf_named_dest_t));
if (unlikely (dest == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2003,6 +1959,8 @@ _cairo_pdf_interchange_tag_end (cairo_pdf_surface_t *surface,
} else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER) {
status = _cairo_tag_stack_pop (&ic->render_tag_stack, name, &elem);
} else {
ASSERT_NOT_REACHED;
}
if (unlikely (status))
return status;
@ -2035,14 +1993,22 @@ _cairo_pdf_interchange_command_id (cairo_pdf_surface_t *surface,
if (surface->paginated_mode == CAIRO_PAGINATED_MODE_RENDER && ic->current_render_node) {
/* TODO If the group does not have tags we don't need to close the current tag. */
if (command_list_is_group (surface, command_id)) {
/* A "Do /xnnn" can not be inside a tag (since the
* XObject may also contain tags). Close the tag.
*/
if (ic->marked_content_open) {
status = _cairo_pdf_operators_tag_end (&surface->pdf_operators);
ic->marked_content_open = FALSE;
}
if (command_list_has_content (surface, command_id, NULL)) {
/* If there is any more content after this and we are
* inside a tag (current node is not the root node),
* ensure that the next command will open the tag.
*/
if (command_list_has_content (surface, command_id, NULL) && ic->current_render_node->parent) {
ic->render_next_command_has_content = TRUE;
}
} else if (ic->render_next_command_has_content) {
/* After a "Do /xnnn" operation, if there is more content, open the tag. */
add_mcid_to_node (surface, ic->current_render_node, ic->command_id, &mcid);
status = _cairo_pdf_operators_tag_begin (&surface->pdf_operators,
ic->current_render_node->name, mcid);
@ -2071,7 +2037,9 @@ _cairo_pdf_interchange_struct_tree_requires_recording_surface (
if (_cairo_surface_is_snapshot (recording_surface))
free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
if (_cairo_recording_surface_has_tags (recording_surface)) {
if (_cairo_surface_is_recording (recording_surface) &&
_cairo_recording_surface_has_tags (recording_surface))
{
/* Check if tags are to be ignored in this source */
switch (source_type) {
case CAIRO_ANALYSIS_SOURCE_PAINT:
@ -2416,10 +2384,6 @@ _cairo_pdf_interchange_write_document_objects (cairo_pdf_surface_t *surface)
if (unlikely (status))
return status;
status = cairo_pdf_interchange_write_forward_links (surface);
if (unlikely (status))
return status;
status = cairo_pdf_interchange_write_names_dict (surface);
if (unlikely (status))
return status;
@ -2477,7 +2441,7 @@ _cairo_pdf_interchange_init (cairo_pdf_surface_t *surface)
_cairo_tag_stack_init (&ic->analysis_tag_stack);
_cairo_tag_stack_init (&ic->render_tag_stack);
ic->struct_root = calloc (1, sizeof(cairo_pdf_struct_tree_node_t));
ic->struct_root = _cairo_calloc (sizeof(cairo_pdf_struct_tree_node_t));
if (unlikely (ic->struct_root == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2521,7 +2485,7 @@ _cairo_pdf_interchange_init (cairo_pdf_surface_t *surface)
ic->mcid_order = 0;
_cairo_array_init (&ic->outline, sizeof(cairo_pdf_outline_entry_t *));
outline_root = calloc (1, sizeof(cairo_pdf_outline_entry_t));
outline_root = _cairo_calloc (sizeof(cairo_pdf_outline_entry_t));
if (unlikely (outline_root == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2635,7 +2599,7 @@ _cairo_pdf_interchange_add_outline (cairo_pdf_surface_t *surface,
if (parent_id < 0 || parent_id >= (int)_cairo_array_num_elements (&ic->outline))
return CAIRO_STATUS_SUCCESS;
outline = _cairo_malloc (sizeof(cairo_pdf_outline_entry_t));
outline = _cairo_calloc (sizeof(cairo_pdf_outline_entry_t));
if (unlikely (outline == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2869,8 +2833,10 @@ _cairo_pdf_interchange_set_custom_metadata (cairo_pdf_surface_t *surface,
if (value && strlen(value)) {
new_data.name = strdup (name);
status = _cairo_utf8_to_pdf_string (value, &s);
if (unlikely (status))
if (unlikely (status)) {
free (new_data.name);
return status;
}
new_data.value = s;
status = _cairo_array_append (&ic->custom_metadata, &new_data);
}

View file

@ -359,7 +359,7 @@ _word_wrap_stream_create (cairo_output_stream_t *output, cairo_bool_t ps, int ma
if (output->status)
return _cairo_output_stream_create_in_error (output->status);
stream = _cairo_malloc (sizeof (word_wrap_stream_t));
stream = _cairo_calloc (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;

View file

@ -266,14 +266,6 @@ typedef struct _cairo_pdf_outline_entry {
int count;
} cairo_pdf_outline_entry_t;
typedef struct _cairo_pdf_forward_link {
cairo_pdf_resource_t res;
char *dest;
int page;
cairo_bool_t has_pos;
cairo_point_double_t pos;
} cairo_pdf_forward_link_t;
struct docinfo {
char *title;
char *author;
@ -468,7 +460,6 @@ struct _cairo_pdf_surface {
cairo_pdf_interchange_t interchange;
int page_parent_tree; /* -1 if not used */
cairo_array_t page_annots;
cairo_array_t forward_links;
cairo_bool_t tagged;
char *current_page_label;
cairo_array_t page_labels;

View file

@ -52,6 +52,7 @@
#include "cairo-composite-rectangles-private.h"
#include "cairo-default-context-private.h"
#include "cairo-error-private.h"
#include "cairo-user-font-private.h"
#include "cairo-image-surface-inline.h"
#include "cairo-image-info-private.h"
#include "cairo-recording-surface-inline.h"
@ -446,7 +447,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
cairo_pdf_surface_t *surface;
cairo_status_t status, status_ignored;
surface = _cairo_malloc (sizeof (cairo_pdf_surface_t));
surface = _cairo_calloc (sizeof (cairo_pdf_surface_t));
if (unlikely (surface == NULL)) {
/* destroy stream on behalf of caller */
status = _cairo_output_stream_destroy (output);
@ -554,7 +555,6 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
surface->page_parent_tree = -1;
_cairo_array_init (&surface->page_annots, sizeof (cairo_pdf_resource_t));
_cairo_array_init (&surface->forward_links, sizeof (cairo_pdf_forward_link_t));
surface->tagged = FALSE;
surface->current_page_label = NULL;
_cairo_array_init (&surface->page_labels, sizeof (char *));
@ -1402,7 +1402,7 @@ _cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface,
{
cairo_pdf_smask_group_t *group;
group = calloc (1, sizeof (cairo_pdf_smask_group_t));
group = _cairo_calloc (sizeof (cairo_pdf_smask_group_t));
if (unlikely (group == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -1766,7 +1766,7 @@ _cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
unique_id_length = 0;
}
surface_entry = _cairo_malloc (sizeof (cairo_pdf_source_surface_entry_t));
surface_entry = _cairo_calloc (sizeof (cairo_pdf_source_surface_entry_t));
if (surface_entry == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail1;
@ -2534,6 +2534,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
_cairo_pdf_surface_open_stream (surface,
resource,
surface->compress_streams,
"%s",
str);
free (str);
free (data);
@ -2698,16 +2699,18 @@ _cairo_pdf_surface_finish (void *abstract_surface)
status = _cairo_pdf_surface_open_object_stream (surface);
if (unlikely (status))
return status;
goto CLEANUP;
/* Emit unbounded surfaces */
_cairo_pdf_surface_write_patterns_and_smask_groups (surface, TRUE);
status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface, TRUE);
if (unlikely (status))
goto CLEANUP;
_cairo_pdf_surface_clear (surface, TRUE);
status = surface->base.status;
if (status == CAIRO_STATUS_SUCCESS)
status = _cairo_pdf_surface_emit_font_subsets (surface);
status = _cairo_pdf_surface_emit_font_subsets (surface);
if (unlikely (status))
goto CLEANUP;
/* Emit any new patterns or surfaces created by the Type 3 font subset. */
_cairo_pdf_surface_write_patterns_and_smask_groups (surface, TRUE);
@ -2716,27 +2719,29 @@ _cairo_pdf_surface_finish (void *abstract_surface)
status = _cairo_pdf_surface_write_pages (surface);
if (unlikely (status))
return status;
goto CLEANUP;
status = _cairo_pdf_interchange_write_document_objects (surface);
if (unlikely (status))
return status;
goto CLEANUP;
status = _cairo_pdf_surface_write_page_dicts (surface);
if (unlikely (status))
return status;
goto CLEANUP;
catalog = _cairo_pdf_surface_new_object (surface);
if (catalog.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (catalog.id == 0) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
}
status = _cairo_pdf_surface_write_catalog (surface, catalog);
if (unlikely (status))
return status;
goto CLEANUP;
status = _cairo_pdf_surface_close_object_stream (surface);
if (unlikely (status))
return status;
goto CLEANUP;
if (!surface->debug && surface->pdf_version >= CAIRO_PDF_VERSION_1_5)
{
@ -2822,7 +2827,6 @@ _cairo_pdf_surface_finish (void *abstract_surface)
_cairo_array_fini (&surface->fonts);
_cairo_array_fini (&surface->knockout_group);
_cairo_array_fini (&surface->page_annots);
_cairo_array_fini (&surface->forward_links);
_cairo_hash_table_foreach (surface->color_glyphs,
_cairo_pdf_color_glyph_pluck,
@ -9296,6 +9300,13 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface,
if (unlikely (status))
goto cleanup;
/* User-fonts can use strokes; reset the stroke pattern as well. */
if (_cairo_font_face_is_user(scaled_font->font_face)) {
status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE);
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
@ -9386,7 +9397,7 @@ _cairo_pdf_surface_supports_color_glyph (void *abstract_surface
if (glyph_entry)
return glyph_entry->supported;
glyph_entry = _cairo_malloc (sizeof (cairo_pdf_color_glyph_t));
glyph_entry = _cairo_calloc (sizeof (cairo_pdf_color_glyph_t));
if (glyph_entry == NULL) {
status = _cairo_surface_set_error (&surface->base,
_cairo_error (CAIRO_STATUS_NO_MEMORY));

View file

@ -42,10 +42,4 @@
#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

View file

@ -569,7 +569,6 @@ cairo_surface_write_to_png_stream (cairo_surface_t *surface,
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)
@ -731,13 +730,8 @@ read_png (struct png_read_closure_t *png_closure)
png_set_palette_to_rgb (png);
/* expand gray bit depth if needed */
if (color_type == PNG_COLOR_TYPE_GRAY) {
#if PNG_LIBPNG_VER >= 10209
if (color_type == PNG_COLOR_TYPE_GRAY)
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))
@ -987,4 +981,3 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
return read_png (&png_closure);
}
slim_hidden_def (cairo_image_surface_create_from_png_stream);

View file

@ -1065,7 +1065,7 @@ _cairo_ps_surface_get_page_media (cairo_ps_surface_t *surface)
}
}
page = _cairo_malloc (sizeof (cairo_page_media_t));
page = _cairo_calloc (sizeof (cairo_page_media_t));
if (unlikely (page == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -1101,7 +1101,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
cairo_status_t status, status_ignored;
cairo_ps_surface_t *surface;
surface = _cairo_malloc (sizeof (cairo_ps_surface_t));
surface = _cairo_calloc (sizeof (cairo_ps_surface_t));
if (unlikely (surface == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP;
@ -1115,7 +1115,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
surface->final_stream = stream;
surface->tmpfile = tmpfile ();
surface->tmpfile = _cairo_tmpfile ();
if (surface->tmpfile == NULL) {
switch (errno) {
case ENOMEM:
@ -2351,7 +2351,7 @@ _base85_strings_stream_create (cairo_output_stream_t *output)
{
string_array_stream_t *stream;
stream = _cairo_malloc (sizeof (string_array_stream_t));
stream = _cairo_calloc (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;
@ -2381,7 +2381,7 @@ _base85_wrap_stream_create (cairo_output_stream_t *output)
{
string_array_stream_t *stream;
stream = _cairo_malloc (sizeof (string_array_stream_t));
stream = _cairo_calloc (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;
@ -3507,13 +3507,13 @@ _cairo_ps_surface_use_form (cairo_ps_surface_t *surface,
if (surface->ps_level == CAIRO_PS_LEVEL_3)
max_size = MAX_L3_FORM_DATA;
else
max_size = MAX_L3_FORM_DATA;
max_size = MAX_L2_FORM_DATA;
/* Don't add any more Forms if we exceed the form memory limit */
if (surface->total_form_size + params->approx_size > max_size)
return CAIRO_INT_STATUS_UNSUPPORTED;
surface->total_form_size += params->approx_size > max_size;
surface->total_form_size += params->approx_size;
unique_id = _cairo_malloc (source_key.unique_id_length);
if (unique_id == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3521,7 +3521,7 @@ _cairo_ps_surface_use_form (cairo_ps_surface_t *surface,
unique_id_length = source_key.unique_id_length;
memcpy (unique_id, source_key.unique_id, unique_id_length);
source_entry = calloc (sizeof (cairo_ps_form_t), 1);
source_entry = _cairo_calloc (sizeof (cairo_ps_form_t));
if (source_entry == NULL) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto fail;

View file

@ -51,6 +51,7 @@
* @Short_Description: Font support via Core Text on Apple operating systems.
* @See_Also: #cairo_font_face_t
*
* Provide support for font faces via Core Text.
**/
/**
@ -76,10 +77,10 @@ static const CGFloat font_scale = 1.0;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
#define FONT_ORIENTATION_HORIZONTAL kCTFontHorizontalOrientation
#define FONT_COLOR_GLYPHS kCTFontTraitColorGlyphs
#define FONT_COLOR_GLYPHS kCTFontColorGlyphsTrait
#else
#define FONT_ORIENTATION_HORIZONTAL kCTFontOrientationHorizontal
#define FONT_COLOR_GLYPHS kCTFontColorGlyphsTrait
#define FONT_COLOR_GLYPHS kCTFontTraitColorGlyphs
#endif
static void
@ -164,6 +165,17 @@ _cairo_quartz_font_face_create_for_toy (cairo_toy_font_face_t *toy_face,
cgFont = CGFontCreateWithFontName (FontName);
CFRelease (FontName);
if (!cgFont) {
/* Attempt to create font by replacing hyphens for spaces in font name. */
for (size_t i = 0; i < strlen (full_name); i++) {
if (full_name[i] == '-')
full_name[i] = ' ';
}
FontName = CFStringCreateWithCString (NULL, full_name, kCFStringEncodingASCII);
cgFont = CGFontCreateWithFontName (FontName);
CFRelease (FontName);
}
if (cgFont)
break;
}
@ -249,7 +261,7 @@ _cairo_quartz_font_face_scaled_font_create (void *abstract_face,
CTFontRef ctFont;
CGRect bbox;
font = _cairo_malloc (sizeof(cairo_quartz_scaled_font_t));
font = _cairo_calloc (sizeof(cairo_quartz_scaled_font_t));
if (font == NULL)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -306,7 +318,7 @@ static inline cairo_quartz_font_face_t*
_cairo_quartz_font_face_create ()
{
cairo_quartz_font_face_t *font_face =
_cairo_malloc (sizeof (cairo_quartz_font_face_t));
_cairo_calloc (sizeof (cairo_quartz_font_face_t));
if (!font_face) {
cairo_status_t ignore_status;

View file

@ -49,6 +49,15 @@
#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)))
/**
* CAIRO_HAS_QUARTZ_IMAGE_SURFACE:
*
* Defined if the Quartz image surface backend is available.
* This macro can be used to conditionally compile backend-specific code.
*
* Since: 1.10
**/
static cairo_surface_t *
_cairo_quartz_image_surface_create_similar (void *asurface,
cairo_content_t content,
@ -283,7 +292,7 @@ cairo_quartz_image_surface_create (cairo_surface_t *surface)
if (format != CAIRO_FORMAT_ARGB32 && format != CAIRO_FORMAT_RGB24)
return SURFACE_ERROR_INVALID_FORMAT;
qisurf = _cairo_malloc (sizeof(cairo_quartz_image_surface_t));
qisurf = _cairo_calloc (sizeof(cairo_quartz_image_surface_t));
if (qisurf == NULL)
return SURFACE_ERROR_NO_MEMORY;
@ -326,7 +335,7 @@ cairo_quartz_image_surface_create (cairo_surface_t *surface)
* or %NULL if the quartz surface is not an image surface.
*
* Since: 1.6
*/
**/
cairo_surface_t *
cairo_quartz_image_surface_get_image (cairo_surface_t *surface)
{

View file

@ -851,7 +851,7 @@ _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (cairo_quartz_surface_t
if (unlikely (status))
return status;
info = _cairo_malloc (sizeof (SurfacePatternDrawInfo));
info = _cairo_calloc (sizeof (SurfacePatternDrawInfo));
if (unlikely (!info))
{
CGImageRelease (image);
@ -2136,7 +2136,7 @@ _cairo_quartz_surface_create_internal (CGContextRef cgContext,
cairo_quartz_surface_t *surface;
/* Init the base surface */
surface = _cairo_malloc (sizeof (cairo_quartz_surface_t));
surface = _cairo_calloc (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));
@ -2386,7 +2386,7 @@ _cairo_quartz_snapshot_create (cairo_surface_t *surface)
! _cairo_quartz_is_cgcontext_bitmap_context (((cairo_quartz_surface_t*)surface)->cgContext))
return NULL;
snapshot = _cairo_malloc (sizeof (cairo_quartz_snapshot_t));
snapshot = _cairo_calloc (sizeof (cairo_quartz_snapshot_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

View file

@ -168,7 +168,7 @@ cairo_pattern_create_raster_source (void *user_data,
if (! CAIRO_CONTENT_VALID (content))
return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
pattern = calloc (1, sizeof (*pattern));
pattern = _cairo_calloc (sizeof (*pattern));
if (unlikely (pattern == NULL))
return _cairo_pattern_create_in_error (CAIRO_STATUS_NO_MEMORY);

View file

@ -183,8 +183,6 @@ typedef struct _cairo_recording_region_array {
cairo_list_t link;
} cairo_recording_regions_array_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);

View file

@ -168,7 +168,7 @@ static int bbtree_left_or_right (struct bbtree *bbt,
static struct bbtree *
bbtree_new (const cairo_box_t *box, cairo_command_header_t *chain)
{
struct bbtree *bbt = _cairo_malloc (sizeof (*bbt));
struct bbtree *bbt = _cairo_calloc (sizeof (*bbt));
if (bbt == NULL)
return NULL;
bbt->extents = *box;
@ -399,7 +399,7 @@ cairo_recording_surface_create (cairo_content_t content,
{
cairo_recording_surface_t *surface;
surface = _cairo_malloc (sizeof (cairo_recording_surface_t));
surface = _cairo_calloc (sizeof (cairo_recording_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -445,7 +445,6 @@ cairo_recording_surface_create (cairo_content_t content,
return &surface->base;
}
slim_hidden_def (cairo_recording_surface_create);
static cairo_surface_t *
_cairo_recording_surface_create_similar (void *abstract_surface,
@ -481,7 +480,7 @@ _cairo_recording_surface_region_array_destroy (cairo_recording_surface_t *
cairo_recording_region_element_t *region_elements;
int i, num_elements;
num_elements = surface->commands.num_elements;
num_elements = MIN(surface->commands.num_elements, _cairo_array_num_elements(&region_array->regions));
elements = _cairo_array_index (&surface->commands, 0);
region_elements = _cairo_array_index (&region_array->regions, 0);
for (i = 0; i < num_elements; i++) {
@ -654,7 +653,7 @@ attach_proxy (cairo_surface_t *source,
{
struct proxy *proxy;
proxy = _cairo_malloc (sizeof (*proxy));
proxy = _cairo_calloc (sizeof (*proxy));
if (unlikely (proxy == NULL))
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
@ -823,7 +822,7 @@ _cairo_recording_surface_paint (void *abstract_surface,
if (unlikely (status))
return status;
command = _cairo_malloc (sizeof (cairo_command_paint_t));
command = _cairo_calloc (sizeof (cairo_command_paint_t));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPOSITE;
@ -879,7 +878,7 @@ _cairo_recording_surface_mask (void *abstract_surface,
if (unlikely (status))
return status;
command = _cairo_malloc (sizeof (cairo_command_mask_t));
command = _cairo_calloc (sizeof (cairo_command_mask_t));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPOSITE;
@ -947,7 +946,7 @@ _cairo_recording_surface_stroke (void *abstract_surface,
if (unlikely (status))
return status;
command = _cairo_malloc (sizeof (cairo_command_stroke_t));
command = _cairo_calloc (sizeof (cairo_command_stroke_t));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPOSITE;
@ -1023,7 +1022,7 @@ _cairo_recording_surface_fill (void *abstract_surface,
if (unlikely (status))
return status;
command = _cairo_malloc (sizeof (cairo_command_fill_t));
command = _cairo_calloc (sizeof (cairo_command_fill_t));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPOSITE;
@ -1105,7 +1104,7 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
if (unlikely (status))
return status;
command = _cairo_malloc (sizeof (cairo_command_show_text_glyphs_t));
command = _cairo_calloc (sizeof (cairo_command_show_text_glyphs_t));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_COMPOSITE;
@ -1155,6 +1154,10 @@ _cairo_recording_surface_show_text_glyphs (void *abstract_surface,
command->cluster_flags = cluster_flags;
status = scaled_font->status;
if (unlikely (status))
goto CLEANUP_ARRAYS;
command->scaled_font = cairo_scaled_font_reference (scaled_font);
status = _cairo_recording_surface_commit (surface, &command->header);
@ -1194,7 +1197,7 @@ _cairo_recording_surface_tag (void *abstract_surface,
surface->has_tags = TRUE;
command = calloc (1, sizeof (cairo_command_tag_t));
command = _cairo_calloc (sizeof (cairo_command_tag_t));
if (unlikely (command == NULL)) {
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
@ -1268,7 +1271,7 @@ _cairo_recording_surface_copy__paint (cairo_recording_surface_t *surface,
cairo_command_paint_t *command;
cairo_status_t status;
command = _cairo_malloc (sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1302,7 +1305,7 @@ _cairo_recording_surface_copy__mask (cairo_recording_surface_t *surface,
cairo_command_mask_t *command;
cairo_status_t status;
command = _cairo_malloc (sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1343,7 +1346,7 @@ _cairo_recording_surface_copy__stroke (cairo_recording_surface_t *surface,
cairo_command_stroke_t *command;
cairo_status_t status;
command = _cairo_malloc (sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1395,7 +1398,7 @@ _cairo_recording_surface_copy__fill (cairo_recording_surface_t *surface,
cairo_command_fill_t *command;
cairo_status_t status;
command = _cairo_malloc (sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1439,7 +1442,7 @@ _cairo_recording_surface_copy__glyphs (cairo_recording_surface_t *surface,
cairo_command_show_text_glyphs_t *command;
cairo_status_t status;
command = _cairo_malloc (sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1517,7 +1520,7 @@ _cairo_recording_surface_copy__tag (cairo_recording_surface_t *surface,
cairo_command_tag_t *command;
cairo_status_t status;
command = calloc (1, sizeof (*command));
command = _cairo_calloc (sizeof (*command));
if (unlikely (command == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto err;
@ -1624,7 +1627,7 @@ _cairo_recording_surface_snapshot (void *abstract_other)
cairo_recording_surface_t *surface;
cairo_status_t status;
surface = _cairo_malloc (sizeof (cairo_recording_surface_t));
surface = _cairo_calloc (sizeof (cairo_recording_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -1732,7 +1735,7 @@ _cairo_recording_surface_regions_allocate_unique_id (void)
unique_id = 1;
return unique_id;
#else
cairo_atomic_int_t old, id;
int old, id;
do {
old = _cairo_atomic_uint_get (&unique_id);
@ -1773,7 +1776,7 @@ _cairo_recording_surface_region_array_attach (cairo_surface_t *abstract_surface,
assert (_cairo_surface_is_recording (abstract_surface));
region_array = _cairo_malloc (sizeof (cairo_recording_regions_array_t));
region_array = _cairo_calloc (sizeof (cairo_recording_regions_array_t));
if (region_array == NULL) {
*id = 0;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2673,7 +2676,6 @@ DONE:
if (height)
*height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
}
slim_hidden_def (cairo_recording_surface_ink_extents);
cairo_status_t
_cairo_recording_surface_get_bbox (cairo_recording_surface_t *surface,

View file

@ -52,7 +52,7 @@ typedef struct {
#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_VALUE ((int) -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)

View file

@ -202,7 +202,7 @@ cairo_region_create (void)
{
cairo_region_t *region;
region = _cairo_malloc (sizeof (cairo_region_t));
region = _cairo_calloc (sizeof (cairo_region_t));
if (region == NULL)
return (cairo_region_t *) &_cairo_region_nil;
@ -213,7 +213,6 @@ cairo_region_create (void)
return region;
}
slim_hidden_def (cairo_region_create);
/**
* cairo_region_create_rectangles:
@ -239,7 +238,7 @@ cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
cairo_region_t *region;
int i;
region = _cairo_malloc (sizeof (cairo_region_t));
region = _cairo_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -281,14 +280,13 @@ cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
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));
region = _cairo_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -334,7 +332,7 @@ cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
{
cairo_region_t *region;
region = _cairo_malloc (sizeof (cairo_region_t));
region = _cairo_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return (cairo_region_t *) &_cairo_region_nil;
@ -347,7 +345,6 @@ cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
return region;
}
slim_hidden_def (cairo_region_create_rectangle);
/**
* cairo_region_copy:
@ -384,7 +381,6 @@ cairo_region_copy (const cairo_region_t *original)
return copy;
}
slim_hidden_def (cairo_region_copy);
/**
* cairo_region_reference:
@ -409,7 +405,6 @@ cairo_region_reference (cairo_region_t *region)
_cairo_reference_count_inc (&region->ref_count);
return region;
}
slim_hidden_def (cairo_region_reference);
/**
* cairo_region_destroy:
@ -435,7 +430,6 @@ cairo_region_destroy (cairo_region_t *region)
_cairo_region_fini (region);
free (region);
}
slim_hidden_def (cairo_region_destroy);
/**
* cairo_region_num_rectangles:
@ -455,7 +449,6 @@ cairo_region_num_rectangles (const cairo_region_t *region)
return pixman_region32_n_rects (CONST_CAST &region->rgn);
}
slim_hidden_def (cairo_region_num_rectangles);
/**
* cairo_region_get_rectangle:
@ -487,7 +480,6 @@ cairo_region_get_rectangle (const cairo_region_t *region,
rectangle->width = pbox->x2 - pbox->x1;
rectangle->height = pbox->y2 - pbox->y1;
}
slim_hidden_def (cairo_region_get_rectangle);
/**
* cairo_region_get_extents:
@ -517,7 +509,6 @@ cairo_region_get_extents (const cairo_region_t *region,
extents->width = pextents->x2 - pextents->x1;
extents->height = pextents->y2 - pextents->y1;
}
slim_hidden_def (cairo_region_get_extents);
/**
* cairo_region_status:
@ -535,7 +526,6 @@ cairo_region_status (const cairo_region_t *region)
{
return region->status;
}
slim_hidden_def (cairo_region_status);
/**
* cairo_region_subtract:
@ -566,7 +556,6 @@ cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other)
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_region_subtract);
/**
* cairo_region_subtract_rectangle:
@ -600,7 +589,6 @@ cairo_region_subtract_rectangle (cairo_region_t *dst,
return status;
}
slim_hidden_def (cairo_region_subtract_rectangle);
/**
* cairo_region_intersect:
@ -627,7 +615,6 @@ cairo_region_intersect (cairo_region_t *dst, const cairo_region_t *other)
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_region_intersect);
/**
* cairo_region_intersect_rectangle:
@ -662,7 +649,6 @@ cairo_region_intersect_rectangle (cairo_region_t *dst,
return status;
}
slim_hidden_def (cairo_region_intersect_rectangle);
/**
* cairo_region_union:
@ -690,7 +676,6 @@ cairo_region_union (cairo_region_t *dst,
return CAIRO_STATUS_SUCCESS;
}
slim_hidden_def (cairo_region_union);
/**
* cairo_region_union_rectangle:
@ -724,7 +709,6 @@ cairo_region_union_rectangle (cairo_region_t *dst,
return status;
}
slim_hidden_def (cairo_region_union_rectangle);
/**
* cairo_region_xor:
@ -763,7 +747,6 @@ cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other)
return status;
}
slim_hidden_def (cairo_region_xor);
/**
* cairo_region_xor_rectangle:
@ -804,7 +787,6 @@ cairo_region_xor_rectangle (cairo_region_t *dst,
return status;
}
slim_hidden_def (cairo_region_xor_rectangle);
/**
* cairo_region_is_empty:
@ -824,7 +806,6 @@ cairo_region_is_empty (const cairo_region_t *region)
return ! pixman_region32_not_empty (CONST_CAST &region->rgn);
}
slim_hidden_def (cairo_region_is_empty);
/**
* cairo_region_translate:
@ -845,7 +826,6 @@ cairo_region_translate (cairo_region_t *region,
pixman_region32_translate (&region->rgn, dx, dy);
}
slim_hidden_def (cairo_region_translate);
/**
* cairo_region_contains_rectangle:
@ -886,7 +866,6 @@ cairo_region_contains_rectangle (const cairo_region_t *region,
case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART;
}
}
slim_hidden_def (cairo_region_contains_rectangle);
/**
* cairo_region_contains_point:
@ -911,7 +890,6 @@ cairo_region_contains_point (const cairo_region_t *region,
return pixman_region32_contains_point (CONST_CAST &region->rgn, x, y, &box);
}
slim_hidden_def (cairo_region_contains_point);
/**
* cairo_region_equal:
@ -942,4 +920,3 @@ cairo_region_equal (const cairo_region_t *a,
return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn);
}
slim_hidden_def (cairo_region_equal);

View file

@ -166,7 +166,7 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index,
{
cairo_sub_font_glyph_t *sub_font_glyph;
sub_font_glyph = _cairo_malloc (sizeof (cairo_sub_font_glyph_t));
sub_font_glyph = _cairo_calloc (sizeof (cairo_sub_font_glyph_t));
if (unlikely (sub_font_glyph == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -276,7 +276,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent,
cairo_sub_font_t *sub_font;
int i;
sub_font = _cairo_malloc (sizeof (cairo_sub_font_t));
sub_font = _cairo_calloc (sizeof (cairo_sub_font_t));
if (unlikely (sub_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -430,7 +430,7 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
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)
strncmp (utf8, sub_font_glyph->utf8, utf8_len) == 0)
{
/* Requested utf8 mapping matches the existing mapping */
*is_mapped = TRUE;
@ -749,7 +749,7 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type)
{
cairo_scaled_font_subsets_t *subsets;
subsets = _cairo_malloc (sizeof (cairo_scaled_font_subsets_t));
subsets = _cairo_calloc (sizeof (cairo_scaled_font_subsets_t));
if (unlikely (subsets == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
@ -922,6 +922,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
font_face = cairo_scaled_font_get_font_face (scaled_font);
cairo_matrix_init_identity (&identity);
_cairo_font_options_init_default (&font_options);
cairo_scaled_font_get_font_options (scaled_font, &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,
@ -1205,7 +1206,7 @@ _cairo_string_init_key (cairo_string_entry_t *key, char *s)
static cairo_status_t
create_string_entry (char *s, cairo_string_entry_t **entry)
{
*entry = _cairo_malloc (sizeof (cairo_string_entry_t));
*entry = _cairo_calloc (sizeof (cairo_string_entry_t));
if (unlikely (*entry == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1237,7 +1238,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
if (unlikely (names == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *));
subset->glyph_names = _cairo_calloc_ab (subset->num_glyphs, sizeof (char *));
if (unlikely (subset->glyph_names == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
goto CLEANUP_HASH;

View file

@ -336,7 +336,6 @@ 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.
@ -379,7 +378,7 @@ _cairo_scaled_font_map_lock (void)
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
if (cairo_scaled_font_map == NULL) {
cairo_scaled_font_map = _cairo_malloc (sizeof (cairo_scaled_font_map_t));
cairo_scaled_font_map = _cairo_calloc (sizeof (cairo_scaled_font_map_t));
if (unlikely (cairo_scaled_font_map == NULL))
goto CLEANUP_MUTEX_LOCK;
@ -520,7 +519,7 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t
if (unlikely (status))
return status;
placeholder_scaled_font = _cairo_malloc (sizeof (cairo_scaled_font_t));
placeholder_scaled_font = _cairo_calloc (sizeof (cairo_scaled_font_t));
if (unlikely (placeholder_scaled_font == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -679,6 +678,12 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font,
_cairo_scaled_font_compute_hash (scaled_font);
}
static void
_cairo_scaled_font_fini_key (cairo_scaled_font_t *scaled_font)
{
_cairo_font_options_fini (&scaled_font->options);
}
static cairo_bool_t
_cairo_scaled_font_keys_equal (const void *abstract_key_a,
const void *abstract_key_b)
@ -915,6 +920,7 @@ _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font)
_cairo_scaled_font_reset_cache (scaled_font);
_cairo_hash_table_destroy (scaled_font->glyphs);
_cairo_font_options_fini (&scaled_font->options);
cairo_font_face_destroy (scaled_font->font_face);
cairo_font_face_destroy (scaled_font->original_font_face);
@ -1106,6 +1112,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
* just wait until it's done, then retry */
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font);
}
_cairo_scaled_font_fini_key (&key);
if (scaled_font != NULL) {
/* If the original reference count is 0, then this font must have
@ -1239,7 +1246,6 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
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];
@ -1257,7 +1263,7 @@ _cairo_scaled_font_create_in_error (cairo_status_t status)
CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex);
scaled_font = _cairo_scaled_font_nil_objects[status];
if (unlikely (scaled_font == NULL)) {
scaled_font = _cairo_malloc (sizeof (cairo_scaled_font_t));
scaled_font = _cairo_calloc (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);
@ -1325,7 +1331,6 @@ cairo_scaled_font_reference (cairo_scaled_font_t *scaled_font)
return scaled_font;
}
slim_hidden_def (cairo_scaled_font_reference);
/**
* cairo_scaled_font_destroy:
@ -1409,7 +1414,6 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
free (lru);
}
}
slim_hidden_def (cairo_scaled_font_destroy);
/**
* cairo_scaled_font_get_reference_count:
@ -1453,7 +1457,6 @@ cairo_scaled_font_get_user_data (cairo_scaled_font_t *scaled_font,
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:
@ -1485,7 +1488,6 @@ cairo_scaled_font_set_user_data (cairo_scaled_font_t *scaled_font,
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. */
@ -1513,7 +1515,6 @@ cairo_scaled_font_extents (cairo_scaled_font_t *scaled_font,
*extents = scaled_font->extents;
}
slim_hidden_def (cairo_scaled_font_extents);
/**
* cairo_scaled_font_text_extents:
@ -1713,7 +1714,6 @@ ZERO_EXTENTS:
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
@ -2180,7 +2180,6 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
return status;
}
slim_hidden_def (cairo_scaled_font_text_to_glyphs);
static inline cairo_bool_t
_range_contains_glyph (const cairo_box_t *extents,
@ -2662,7 +2661,7 @@ _cairo_scaled_glyph_set_path (cairo_scaled_glyph_t *scaled_glyph,
* glyph, or NULL if foreground color not required.
*
* Sets the surface that was used to record the glyph.
*/
**/
void
_cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font,
@ -2695,7 +2694,7 @@ _cairo_scaled_glyph_set_recording_surface (cairo_scaled_glyph_t *scaled_glyph,
* used when rendering the surface color.
*
* Sets the color surface of the glyph.
*/
**/
void
_cairo_scaled_glyph_set_color_surface (cairo_scaled_glyph_t *scaled_glyph,
cairo_scaled_font_t *scaled_font,
@ -2760,7 +2759,7 @@ _cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font,
}
}
page = _cairo_malloc (sizeof (cairo_scaled_glyph_page_t));
page = _cairo_calloc (sizeof (cairo_scaled_glyph_page_t));
if (unlikely (page == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -2991,7 +2990,6 @@ _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
@ -3017,7 +3015,6 @@ cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font)
return scaled_font->font_face;
}
slim_hidden_def (cairo_scaled_font_get_font_face);
/**
* cairo_scaled_font_get_font_matrix:
@ -3040,7 +3037,6 @@ cairo_scaled_font_get_font_matrix (cairo_scaled_font_t *scaled_font,
*font_matrix = scaled_font->font_matrix;
}
slim_hidden_def (cairo_scaled_font_get_font_matrix);
/**
* cairo_scaled_font_get_ctm:
@ -3065,7 +3061,6 @@ cairo_scaled_font_get_ctm (cairo_scaled_font_t *scaled_font,
*ctm = scaled_font->ctm;
}
slim_hidden_def (cairo_scaled_font_get_ctm);
/**
* cairo_scaled_font_get_scale_matrix:
@ -3116,7 +3111,6 @@ cairo_scaled_font_get_font_options (cairo_scaled_font_t *scaled_font,
_cairo_font_options_fini (options);
_cairo_font_options_init_copy (options, &scaled_font->options);
}
slim_hidden_def (cairo_scaled_font_get_font_options);
cairo_bool_t
_cairo_scaled_font_has_color_glyphs (cairo_scaled_font_t *scaled_font)

View file

@ -52,8 +52,6 @@ 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 */

View file

@ -264,7 +264,7 @@ _bitmap_next_id (struct _bitmap *b,
} while (b != NULL);
assert (prev != NULL);
bb = _cairo_malloc (sizeof (struct _bitmap));
bb = _cairo_calloc (sizeof (struct _bitmap));
if (unlikely (bb == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -370,6 +370,21 @@ _filter_to_string (cairo_filter_t filter)
return names[filter];
}
static const char *
_dither_to_string (cairo_dither_t dither)
{
static const char *names[] = {
"DITHER_DEFAULT", /* CAIRO_FILTER_FAST */
"DITHER_NONE", /* CAIRO_FILTER_GOOD */
"DITHER_FAST", /* CAIRO_FILTER_BEST */
"DITHER_GOOD", /* CAIRO_FILTER_NEAREST */
"DITHER_BEST", /* CAIRO_FILTER_BILINEAR */
};
assert (dither < ARRAY_LENGTH (names));
return names[dither];
}
static const char *
_fill_rule_to_string (cairo_fill_rule_t rule)
{
@ -1129,7 +1144,7 @@ attach_snapshot (cairo_script_context_t *ctx,
if (! ctx->attach_snapshots)
return;
surface = _cairo_malloc (sizeof (*surface));
surface = _cairo_calloc (sizeof (*surface));
if (unlikely (surface == NULL))
return;
@ -1731,6 +1746,17 @@ _emit_pattern (cairo_script_surface_t *surface,
" //%s set-filter\n ",
_filter_to_string (pattern->filter));
}
/* XXX need to discriminate the user explicitly setting the default */
if (pattern->dither != CAIRO_DITHER_DEFAULT) {
if (need_newline) {
_cairo_output_stream_puts (ctx->stream, "\n ");
need_newline = FALSE;
}
_cairo_output_stream_printf (ctx->stream,
" //%s set-dither\n ",
_dither_to_string (pattern->dither));
}
if (! is_default_extend ){
if (need_newline) {
_cairo_output_stream_puts (ctx->stream, "\n ");
@ -2204,6 +2230,7 @@ _cairo_script_surface_finish (void *abstract_surface)
_cairo_pattern_fini (&surface->cr.current_source.base);
_cairo_path_fixed_fini (&surface->cr.current_path);
_cairo_font_options_fini (&surface->cr.current_font_options);
_cairo_surface_clipper_reset (&surface->clipper);
status = cairo_device_acquire (&ctx->base);
@ -2231,7 +2258,7 @@ _cairo_script_surface_finish (void *abstract_surface)
}
cairo_list_del (&surface->operand.link);
} else {
struct deferred_finish *link = _cairo_malloc (sizeof (*link));
struct deferred_finish *link = _cairo_calloc (sizeof (*link));
if (link == NULL) {
status2 = _cairo_error (CAIRO_STATUS_NO_MEMORY);
if (status == CAIRO_STATUS_SUCCESS)
@ -2965,7 +2992,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface,
cairo_script_font_t *font_private;
cairo_int_status_t status;
font_private = _cairo_malloc (sizeof (cairo_script_font_t));
font_private = _cairo_calloc (sizeof (cairo_script_font_t));
if (unlikely (font_private == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -3701,7 +3728,7 @@ _cairo_script_surface_create_internal (cairo_script_context_t *ctx,
if (unlikely (ctx == NULL))
return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
surface = _cairo_malloc (sizeof (cairo_script_surface_t));
surface = _cairo_calloc (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));
@ -3750,7 +3777,7 @@ _cairo_script_context_create_internal (cairo_output_stream_t *stream)
{
cairo_script_context_t *ctx;
ctx = _cairo_malloc (sizeof (cairo_script_context_t));
ctx = _cairo_calloc (sizeof (cairo_script_context_t));
if (unlikely (ctx == NULL))
return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -3963,7 +3990,6 @@ cairo_script_surface_create (cairo_device_t *script,
content, extents,
NULL)->base;
}
slim_hidden_def (cairo_script_surface_create);
/**
* cairo_script_surface_create_for_target:

View file

@ -60,8 +60,17 @@
* @Short_Description: Observing other surfaces
* @See_Also: #cairo_surface_t
*
* A surface that exists solely to watch another is doing.
*/
* A surface that exists solely to watch what another surface is doing.
**/
/**
* CAIRO_HAS_OBSERVER_SURFACE:
*
* Defined if the observer surface backend is available.
* This macro can be used to conditionally compile backend-specific code.
*
* Since: 1.12
**/
static const cairo_surface_backend_t _cairo_surface_observer_backend;
@ -357,7 +366,7 @@ _cairo_device_create_observer_internal (cairo_device_t *target,
cairo_device_observer_t *device;
cairo_status_t status;
device = _cairo_malloc (sizeof (cairo_device_observer_t));
device = _cairo_calloc (sizeof (cairo_device_observer_t));
if (unlikely (device == NULL))
return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -388,7 +397,7 @@ _cairo_surface_create_observer_internal (cairo_device_t *device,
cairo_surface_observer_t *surface;
cairo_status_t status;
surface = _cairo_malloc (sizeof (cairo_surface_observer_t));
surface = _cairo_calloc (sizeof (cairo_surface_observer_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@ -1382,8 +1391,8 @@ static const cairo_surface_backend_t _cairo_surface_observer_backend = {
* 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 @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
@ -1427,7 +1436,7 @@ _cairo_surface_observer_add_callback (cairo_list_t *head,
{
struct callback_list *cb;
cb = _cairo_malloc (sizeof (*cb));
cb = _cairo_calloc (sizeof (*cb));
if (unlikely (cb == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -1438,6 +1447,18 @@ _cairo_surface_observer_add_callback (cairo_list_t *head,
return CAIRO_STATUS_SUCCESS;
}
/**
* cairo_surface_observer_add_paint_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for paint operations
* @data: closure to pass to the callback
*
* Adds a callback for paint operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.12
**/
cairo_status_t
cairo_surface_observer_add_paint_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1456,6 +1477,18 @@ cairo_surface_observer_add_paint_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_mask_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for mask operations
* @data: closure to pass to the callback
*
* Adds a callback for mask operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.12
**/
cairo_status_t
cairo_surface_observer_add_mask_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1474,6 +1507,18 @@ cairo_surface_observer_add_mask_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_fill_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for fill operations
* @data: closure to pass to the callback
*
* Adds a callback for fill operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.12
**/
cairo_status_t
cairo_surface_observer_add_fill_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1492,6 +1537,18 @@ cairo_surface_observer_add_fill_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_stroke_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for stroke operations
* @data: closure to pass to the callback
*
* Adds a callback for stroke operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.12
**/
cairo_status_t
cairo_surface_observer_add_stroke_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1510,6 +1567,18 @@ cairo_surface_observer_add_stroke_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_glyphs_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for glyph operations
* @data: closure to pass to the callback
*
* Adds a callback for glyph operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.10
**/
cairo_status_t
cairo_surface_observer_add_glyphs_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1528,6 +1597,18 @@ cairo_surface_observer_add_glyphs_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_flush_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback for flush operations
* @data: closure to pass to the callback
*
* Adds a callback for flush operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.10
**/
cairo_status_t
cairo_surface_observer_add_flush_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1546,6 +1627,18 @@ cairo_surface_observer_add_flush_callback (cairo_surface_t *abstract_surface,
func, data);
}
/**
* cairo_surface_observer_add_finish_callback:
* @abstract_surface: a #cairo_surface_observer_t
* @func: callback function for the finish operation
* @data: closure to pass to the callback
*
* Adds a callback for finish operations on the observed surface.
*
* Returns: the status of the surface
*
* Since: 1.10
**/
cairo_status_t
cairo_surface_observer_add_finish_callback (cairo_surface_t *abstract_surface,
cairo_surface_observer_callback_t func,
@ -1966,6 +2059,18 @@ _cairo_observation_print (cairo_output_stream_t *stream,
cairo_device_destroy (script);
}
/**
* cairo_surface_observer_print:
* @abstract_surface: a #cairo_surface_observer_t
* @write_func: callback for writing on a stream
* @closure: data to pass to @write_func
*
* Prints the observer log using the given callback.
*
* Returns: the status of the print operation
*
* Since: 1.12
**/
cairo_status_t
cairo_surface_observer_print (cairo_surface_t *abstract_surface,
cairo_write_func_t write_func,
@ -1987,6 +2092,16 @@ cairo_surface_observer_print (cairo_surface_t *abstract_surface,
return _cairo_output_stream_destroy (stream);
}
/**
* cairo_surface_observer_elapsed:
* @abstract_surface: a #cairo_surface_observer_t
*
* Returns the total observation time.
*
* Returns: the elapsed time, in nanoseconds
*
* Since: 1.12
**/
double
cairo_surface_observer_elapsed (cairo_surface_t *abstract_surface)
{
@ -2002,6 +2117,18 @@ cairo_surface_observer_elapsed (cairo_surface_t *abstract_surface)
return _cairo_time_to_ns (_cairo_observation_total_elapsed (&surface->log));
}
/**
* cairo_device_observer_print:
* @abstract_device: the observed #cairo_device_t
* @write_func: the write function
* @closure: data to pass to the @write_func
*
* Prints the device log using the given function.
*
* Returns: the status after the operation
*
* Since: 1.12
**/
cairo_status_t
cairo_device_observer_print (cairo_device_t *abstract_device,
cairo_write_func_t write_func,
@ -2023,6 +2150,16 @@ cairo_device_observer_print (cairo_device_t *abstract_device,
return _cairo_output_stream_destroy (stream);
}
/**
* cairo_device_observer_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the total elapsed time of the observation.
*
* Returns: the elapsed time, in nanoseconds.
*
* Since: 1.12
**/
double
cairo_device_observer_elapsed (cairo_device_t *abstract_device)
{
@ -2038,6 +2175,16 @@ cairo_device_observer_elapsed (cairo_device_t *abstract_device)
return _cairo_time_to_ns (_cairo_observation_total_elapsed (&device->log));
}
/**
* cairo_device_observer_paint_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the elapsed time of the paint operations.
*
* Returns: the elapsed time, in nanoseconds.
*
* Since: 1.12
**/
double
cairo_device_observer_paint_elapsed (cairo_device_t *abstract_device)
{
@ -2053,6 +2200,16 @@ cairo_device_observer_paint_elapsed (cairo_device_t *abstract_device)
return _cairo_time_to_ns (device->log.paint.elapsed);
}
/**
* cairo_device_observer_mask_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the elapsed time of the mask operations.
*
* Returns: the elapsed time, in nanoseconds
*
* Since: 1.12
**/
double
cairo_device_observer_mask_elapsed (cairo_device_t *abstract_device)
{
@ -2068,6 +2225,16 @@ cairo_device_observer_mask_elapsed (cairo_device_t *abstract_device)
return _cairo_time_to_ns (device->log.mask.elapsed);
}
/**
* cairo_device_observer_fill_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the elapsed time of the fill operations.
*
* Returns: the elapsed time, in nanoseconds.
*
* Since: 1.12
**/
double
cairo_device_observer_fill_elapsed (cairo_device_t *abstract_device)
{
@ -2083,6 +2250,16 @@ cairo_device_observer_fill_elapsed (cairo_device_t *abstract_device)
return _cairo_time_to_ns (device->log.fill.elapsed);
}
/**
* cairo_device_observer_stroke_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the elapsed time of the stroke operations.
*
* Returns: the elapsed time, in nanoseconds.
*
* Since: 1.12
**/
double
cairo_device_observer_stroke_elapsed (cairo_device_t *abstract_device)
{
@ -2098,6 +2275,16 @@ cairo_device_observer_stroke_elapsed (cairo_device_t *abstract_device)
return _cairo_time_to_ns (device->log.stroke.elapsed);
}
/**
* cairo_device_observer_glyphs_elapsed:
* @abstract_device: the observed #cairo_device_t
*
* Returns the elapsed time of the glyph operations.
*
* Returns: the elapsed time, in nanoseconds.
*
* Since: 1.12
**/
double
cairo_device_observer_glyphs_elapsed (cairo_device_t *abstract_device)
{

View file

@ -101,7 +101,7 @@ _cairo_surface_snapshot_acquire_source_image (void *abstract_
struct snapshot_extra *extra;
cairo_status_t status;
extra = _cairo_malloc (sizeof (*extra));
extra = _cairo_calloc (sizeof (*extra));
if (unlikely (extra == NULL)) {
*extra_out = NULL;
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
@ -263,7 +263,7 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
if (snapshot != NULL)
return cairo_surface_reference (&snapshot->base);
snapshot = _cairo_malloc (sizeof (cairo_surface_snapshot_t));
snapshot = _cairo_calloc (sizeof (cairo_surface_snapshot_t));
if (unlikely (snapshot == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));

Some files were not shown because too many files have changed in this diff Show more