[cairo-commit] Branch '1.14' - 14 commits - cairo-version.h NEWS RELEASING src/cairo-cff-subset.c src/cairo-ft-font.c src/cairo-image-info.c src/cairo-pdf-operators.c src/cairo-pdf-surface.c src/cairo-ps-surface.c src/cairo-scaled-font-subsets.c src/cairo-scaled-font-subsets-private.h src/cairo-surface.c src/cairo-truetype-subset.c src/cairo-xlib-surface.c

Bryce Harrington bryce at kemper.freedesktop.org
Thu Jun 15 23:06:12 UTC 2017


 NEWS                                    |   57 ++++++++++++
 RELEASING                               |  125 ++++++++++++++++++++--------
 cairo-version.h                         |    2 
 src/cairo-cff-subset.c                  |   16 ++-
 src/cairo-ft-font.c                     |  142 ++++++++++++++++++++------------
 src/cairo-image-info.c                  |    2 
 src/cairo-pdf-operators.c               |    3 
 src/cairo-pdf-surface.c                 |   32 ++++---
 src/cairo-ps-surface.c                  |   25 ++++-
 src/cairo-scaled-font-subsets-private.h |    5 +
 src/cairo-scaled-font-subsets.c         |  121 +++++++++++++++++++++++----
 src/cairo-surface.c                     |   17 ++-
 src/cairo-truetype-subset.c             |   21 +++-
 src/cairo-xlib-surface.c                |    2 
 14 files changed, 424 insertions(+), 146 deletions(-)

New commits:
commit 96b918c4458ce0546e107af69bb7efe832c097a3
Author: Bryce Harrington <bryce at osg.samsung.com>
Date:   Thu Jun 15 15:52:56 2017 -0700

    Start 1.14.11 development

diff --git a/cairo-version.h b/cairo-version.h
index dd31ba2f..f7acbc11 100644
--- a/cairo-version.h
+++ b/cairo-version.h
@@ -3,6 +3,6 @@
 
 #define CAIRO_VERSION_MAJOR 1
 #define CAIRO_VERSION_MINOR 14
-#define CAIRO_VERSION_MICRO 10
+#define CAIRO_VERSION_MICRO 11
 
 #endif
commit 05b63e807bb5f86f600283df1c3ca554778d90fa
Author: Bryce Harrington <bryce at osg.samsung.com>
Date:   Tue Jun 13 18:39:23 2017 -0700

    Release 1.14.10

diff --git a/NEWS b/NEWS
index 08889d2d..16381fbb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,60 @@
+Release 1.14.10   (2017-06-13  Bryce Harrington <bryce at osg.samsung.com>)
+========================================================================
+Bugfix release rolling up backported fixes for the past half year.
+
+For a complete log of changes since 1.14.8, please see:
+
+    http://cairographics.org/releases/ChangeLog.cairo-1.14.10
+
+
+Features
+--------
+None
+
+API Changes
+-----------
+None
+
+Dependency Changes
+------------------
+None
+
+Performance Optimizations
+-------------------------
+None
+
+Bug Fixes
+---------
+* Clarify documentation	regarding device scale inheritance and the units
+  used in cairo_surface_create_similar_image.
+  Bug #99094.
+
+* Fix error reporting in the xcb backend if fallback fails.  Instead of
+  returning NULL when the X11 server can't do some operation, return a
+  surface in an error state.
+
+* Call XSync in the xlib backend before setting the error handler to
+  ignore errors for certain requests, to make sure all pending errors
+  are handled first.
+
+* For opentype fonts, always use gid to lookup glyph.
+
+* If glyph 0 used for rendering, remap to different index.
+
+* Set font size to em size when retrieving unhinted metrics.
+
+* Flush ASCII85Decode file after use with Postscript files.
+
+* pdf: Don't fail subsetting if unable to convert utf8 to utf16.
+
+* For truetype, reverse cmap search should end when 0xffff- 0xffff range
+  reached.
+
+* Fix bug in line wrapping with the PDF operators.
+
+* Fix an off by one check in cairo-image-info.c.
+
+
 Release 1.14.8    (2016-12-07  Bryce Harrington <bryce at osg.samsung.com>)
 ========================================================================
 Bugfix release rolling up backported fixes for the past year.
diff --git a/cairo-version.h b/cairo-version.h
index 73acc756..dd31ba2f 100644
--- a/cairo-version.h
+++ b/cairo-version.h
@@ -3,6 +3,6 @@
 
 #define CAIRO_VERSION_MAJOR 1
 #define CAIRO_VERSION_MINOR 14
-#define CAIRO_VERSION_MICRO 9
+#define CAIRO_VERSION_MICRO 10
 
 #endif
commit ff7ac087cbae9c2a71dc7b1e4cad5898755151b3
Author: Bryce Harrington <bryce at osg.samsung.com>
Date:   Thu Jun 15 14:45:11 2017 -0700

    RELEASING: Sync doc from trunk

diff --git a/RELEASING b/RELEASING
index 641ac1fc..424902e9 100644
--- a/RELEASING
+++ b/RELEASING
@@ -1,10 +1,11 @@
 Here are the steps to follow to create a new cairo release:
 
-1) Ensure that there are no local, uncommitted/unpushed
-   modifications. You're probably in a good state if both "git diff
-   HEAD" and "git log master..origin/master" give no output.  Also make
-   sure you have libglib2.0-doc installed (else you'll get excessive
-   gtk-doc cross reference warnings in the next step).
+1) Ensure that there are no local, uncommitted/unpushed mods.
+
+	You're probably in a good state if both "git diff
+	HEAD" and "git log master..origin/master" give no output.  Also make
+	sure you have libglib2.0-doc installed (else you'll get
+	excessive gtk-doc cross reference warnings in the next step).
 
 2) Verify that the code passes "make distcheck"
 
@@ -37,19 +38,52 @@ Here are the steps to follow to create a new cairo release:
 	suite passing, here's the magic env vars to set when doing
 	'make distcheck' and 'make release-publish' that will let you
 	get away with it.  At any cost, never ever release without
-	(implied) distchecking.  Every time we got around it, it turned
+	(implied) distchecking.	 Every time we got around it, it turned
 	out to be a disaster.  Anyway, here's the pass code:
 
 		DISPLAY= CAIRO_TEST_TARGET=" "
 
-3) Fill out an entry in the NEWS file
+3) Decide what the new version number for the release will be.
+
+	There are three types of releases:  Minor, Micro, and
+	Snapshot.  Micro releases should be only bugfixes and no API
+	additions.  If there are API additions consider making a Minor
+	release.  Snapshot releases can be done of the current
+	development tree between Minor releases, as desired.
+
+	Cairo uses even numbers for official releases, and odd numbers
+	for development snapshots.  Thus, for a Minor release it would
+	be:
+
+		LAST_RELEASE="X.Y.Z"     # e.g. 1.12.0
+		THIS_RELEASE="X.Y+2.0"	 # e.g. 1.14.0
+
+	While for a Micro release the version numbers should be:
+
+		LAST_RELEASE="X.Y.Z"     # e.g. 1.14.0
+		THIS_RELEASE="X.Y.Z+2"   # e.g. 1.14.2
+
+	Snapshots are similar but have odd minor versions.  Also, the
+	first snapshot release in a new series will be .2 rather than
+	.0, e.g.:
+
+		LAST_RELEASE="X.Y.Z"     # e.g. 1.14.0
+		THIS_RELEASE="X.Y+1.0"   # e.g. 1.15.2
+
+	and subsequent snapshots in that series are just normal micro
+	releases:
+
+		LAST_RELEASE="X.Y.Z"     # e.g. 1.15.2
+		THIS_RELEASE="X.Y.Z+2"   # e.g. 1.15.4
+
+
+
+4) Fill out an entry in the NEWS file
 
 	Sift through the logs since the last release. This is most
 	easily done with a command such as:
 
-		git log --stat X.Y.Z..
-
-	where X.Y.Z is the previous release version.
+		git log --stat ${LAST_RELEASE}..
 
 	Summarize major changes briefly in a style similar to other
 	entries in NEWS. Take special care to note any additions in
@@ -58,8 +92,14 @@ Here are the steps to follow to create a new cairo release:
 	the following command will show each patch that has changed a
 	public header file since the given version:
 
-		find src/ -name '*.h' ! -name '*-private.h' ! -name 'cairoint.h' ! -name 'cairo-*features*.h' | \
-		xargs git diff X.Y.Z.. --
+		find src/ -name '*.h' ! -name '*-private.h' \
+		  ! -name 'cairoint.h' ! -name 'cairo-*features*.h' | \
+		xargs git diff ${LAST_RELEASE}.. --
+
+	Include a link to the incremental ChangeLog for this release,
+	which we'll be uploading in a later step:
+
+		http://cairographics.org/releases/ChangeLog.cairo-${THIS_RELEASE}
 
 4) Increment cairo_version_{minor|micro} in cairo-version.h:
 
@@ -95,11 +135,11 @@ Here are the steps to follow to create a new cairo release:
 	* Sign the sha1sum using your GPG setup (asks for your GPG password)
 	* scp the three files to appear on http://cairographics.org/releases
 	* Generate a versioned manual and upload it to appear as both:
-	  http://cairographics.org/manual-X.Y.Z
+	  http://cairographics.org/manual-${THIS_RELEASE}
 	  http://cairographics.org/manual
 	* Place local copies of the three files in the releases directory
 	* Create a LATEST-package-version file (after deleting any old one)
-	* Tag the entire source tree with a tag of the form X.Y.Z, and sign
+	* Tag the entire source tree with a ${THIS_RELEASE} tag, and sign
 	  the tag with your GPG key (asks for your GPG password, and you
 	  may need to set GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL to match
 	  your public-key's setting or this fails.)
@@ -107,32 +147,47 @@ Here are the steps to follow to create a new cairo release:
 	  If for some reason you lost this message, "make release-publish-message"
 	  prints it for you.
 
-7) Increment cairo_version_micro to the next larger (odd) number in
-   cairo-version.h, commit, and push.
+	Upload the incremental ChangeLog generated by the above:
+
+		scp ChangeLog.cache-${LAST_RELEASE}.. \
+		    cairographics.org:/srv/cairo.freedesktop.org/www/releases/ChangeLog.cairo-${THIS_RELEASE}
+
+	To undo a release-publish, before you've sent any emails or
+	pushed changes to master, delete the locally created tag (git
+	tag -d ${THIS_RELEASE}); then log into the webserver, repoint
+	the manual and LATEST-cairo-${THIS_RELEASE} symlinks to the
+	previous versions, remove manual-${THIS_RELEASE} and
+	release/cairo-${THIS_RELEASE}.
+
+7) Update trunk (or the stable branch) version number.
+
+	For Micro releases (X.Y.Z), increment cairo_version_micro to the
+	next larger (odd) number in cairo-version.h, commit, and push.
+
+	For Minor releases (X.Y.0), increment cairo_version_minor to the
+	next larger (odd) number, and set cairo_version_micro to 1.  Then
+	commit and push.
+
+8) Push the new tag out to the central tree with a command like:
 
-8) Push the newly created tag out to the central tree with a command
-   something like:
+	git push origin master ${THIS_RELEASE}
 
-	git push origin master X.Y.Z
+9) Edit the cairo bugzilla product and add the new version numbers.
 
-9) Edit the cairo bugzilla product and add the new version numbers. Note
-   that you need to add two versions.  One for the release/snapshot (with
-   an even micro version), another with the post-release version (with an
-   odd micro version).
+	Note that you need to add two versions.  One for the
+	release/snapshot (with an even micro version), another with the
+	post-release version (with an odd micro version).
 
-10) Send a message to cairo-announce at cairographics.org and CC
-    cairo at cairographics.org, gnome-announce-list at gnome.org and
-    ftp-release at lists.freedesktop.org (pr at lwn.net as well for major
-    releases) to announce the new release using the text provided from
-    "make release-publish", adding the excerpt from NEWS, your
-    signature, followed by the standard "What is cairo" and "Where to
-    get more information about cairo" blurbs from README, and finally
-    the shortlog of all changes since last release, generated by:
+10) Send out an announcement message.
 
-	git shortlog X.Y.Z...
+	Send a message to cairo-announce at cairographics.org and CC
+	cairo at cairographics.org, gnome-announce-list at gnome.org and
+	ftp-release at lists.freedesktop.org (pr at lwn.net as well for major
+	releases) to announce the new release using the text provided from
+	"make release-publish", adding the excerpt from NEWS and
+	the shortlog of all changes since last release, generated by:
 
-    where X.Y.Z is the last released version.
+		git shortlog ${LAST_RELEASE}...
 
-11) Edit the cairo wiki to add the announcement to the NEWS page and
-    the front page. (just the parts before your signature).
+11) Add the announcement to the NEWS page and the front page.
 
commit c467f458b14196e699ff104f22b1531b67ba919e
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Jun 15 20:53:29 2017 +0930

    Fix off by one check in cairo-image-info.c
    
    https://bugs.freedesktop.org/show_bug.cgi?id=101427

diff --git a/src/cairo-image-info.c b/src/cairo-image-info.c
index 26e7ae5a..d147e372 100644
--- a/src/cairo-image-info.c
+++ b/src/cairo-image-info.c
@@ -137,7 +137,7 @@ _cairo_image_info_get_jpeg_info (cairo_image_info_t	*info,
 		break;
 	    }
 
-	    if (p + 2 > data + length)
+	    if (p + 3 > data + length)
 		return CAIRO_INT_STATUS_UNSUPPORTED;
 
 	    p = _jpeg_skip_segment (p);
commit e2ab1c608fcb54d86ac30852aec4cac36ef1e577
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Thu Mar 2 19:14:04 2017 +1030

    pdf-operators: fix bug in line wrapping
    
    patch by jmmorlan at sonic.net
    
    https://bugs.freedesktop.org/show_bug.cgi?id=100029

diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c
index dcee25f0..c509ad00 100644
--- a/src/cairo-pdf-operators.c
+++ b/src/cairo-pdf-operators.c
@@ -319,7 +319,8 @@ _word_wrap_stream_write (cairo_output_stream_t  *base,
 	    if (*data == '\n' || stream->column >= stream->max_column) {
 		_cairo_output_stream_printf (stream->output, "\n");
 		stream->column = 0;
-	    } else if (*data == '<') {
+	    }
+	    if (*data == '<') {
 		stream->state = WRAP_STATE_HEXSTRING;
 	    } else if (*data == '(') {
 		stream->state = WRAP_STATE_STRING;
commit d48dd8575d4f49008d6b2c8057ec9f50e4e4f1e2
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Jul 17 21:33:12 2016 +0930

    truetype: reverse cmap search should end when 0xffff- 0xffff range reached

diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 9137ef3a..e3449a0d 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -1310,11 +1310,14 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
 
     /* search for glyph in segments with rangeOffset=0 */
     for (i = 0; i < num_segments; i++) {
+	uint16_t start = be16_to_cpu (start_code[i]);
+	uint16_t end = be16_to_cpu (end_code[i]);
+
+	if (start == 0xffff && end == 0xffff)
+	    break;
+
 	c = index - be16_to_cpu (delta[i]);
-	if (range_offset[i] == 0 &&
-	    c >= be16_to_cpu (start_code[i]) &&
-	    c <= be16_to_cpu (end_code[i]))
-	{
+	if (range_offset[i] == 0 && c >= start && c <= end) {
 	    *ucs4 = c;
 	    goto found;
 	}
@@ -1322,9 +1325,15 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
 
     /* search for glyph in segments with rangeOffset=1 */
     for (i = 0; i < num_segments; i++) {
+	uint16_t start = be16_to_cpu (start_code[i]);
+	uint16_t end = be16_to_cpu (end_code[i]);
+
+	if (start == 0xffff && end == 0xffff)
+	    break;
+
 	if (range_offset[i] != 0) {
 	    uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2;
-	    int range_size = be16_to_cpu (end_code[i]) - be16_to_cpu (start_code[i]) + 1;
+	    int range_size = end - start + 1;
 	    uint16_t g_id_be = cpu_to_be16 (index);
 	    int j;
 
@@ -1334,7 +1343,7 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
 
 		for (j = 0; j < range_size; j++) {
 		    if (glyph_ids[j] == g_id_be) {
-			*ucs4 = be16_to_cpu (start_code[i]) + j;
+			*ucs4 = start + j;
 			goto found;
 		    }
 		}
commit 0b4eda23b0d7d4487352a82405b302f028feb11f
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Jul 17 21:19:37 2016 +0930

    pdf: Don't fail subsetting if unable to convert utf8 to utf16
    
    If the unicode came from the font, don't fail if utf8_to_utf16 fails.

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 4bc29479..ef94e39f 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -4757,8 +4757,12 @@ _cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t	*surface,
 
     if (utf8 && *utf8) {
 	status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
-	if (unlikely (status))
+	if (unlikely (status == CAIRO_INT_STATUS_INVALID_STRING)) {
+	    utf16 = NULL;
+	    utf16_len = 0;
+	} else if (unlikely (status)) {
 	    return status;
+	}
     }
 
     _cairo_output_stream_printf (surface->output, "<");
@@ -5034,13 +5038,14 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t		*surface,
 	char *pdf_str;
 
 	status = _utf8_to_pdf_string (subset->family_name_utf8, &pdf_str);
-	if (unlikely (status))
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /FontFamily %s\n",
+					 pdf_str);
+	    free (pdf_str);
+	} else if (status != CAIRO_INT_STATUS_INVALID_STRING) {
 	    return status;
-
-	_cairo_output_stream_printf (surface->output,
-				     "   /FontFamily %s\n",
-				     pdf_str);
-	free (pdf_str);
+	}
     }
 
     _cairo_output_stream_printf (surface->output,
@@ -5479,13 +5484,14 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
 	char *pdf_str;
 
 	status = _utf8_to_pdf_string (subset.family_name_utf8, &pdf_str);
-	if (unlikely (status))
+	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
+	    _cairo_output_stream_printf (surface->output,
+					 "   /FontFamily %s\n",
+					 pdf_str);
+	    free (pdf_str);
+	} else if (status != CAIRO_INT_STATUS_INVALID_STRING) {
 	    return status;
-
-	_cairo_output_stream_printf (surface->output,
-				     "   /FontFamily %s\n",
-				     pdf_str);
-	free (pdf_str);
+	}
     }
 
     _cairo_output_stream_printf (surface->output,
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 74bfb9ea..bf05fbd5 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -1281,8 +1281,12 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
 	utf16_len = 0;
 	if (utf8 && *utf8) {
 	    status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
-	    if (unlikely (status))
+	    if (status == CAIRO_STATUS_INVALID_STRING) {
+		utf16 = NULL;
+		utf16_len = 0;
+	    } else if (unlikely (status)) {
 		goto CLEANUP_HASH;
+	    }
 	}
 
 	if (utf16_len == 1) {
commit 0aafba93f796758aebb2f8c3b4585b049dc0c30c
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri Jul 15 16:24:03 2016 +0930

    ps: flush ASCII85Decode file after use
    
    If the image operator does not read all the ASCII85 data, the PS
    interpreter will try to execute the next byte of unread data.
    
    Define our own image operator that calls flushfile (reads until end of
    file) on the filter after drawing the image.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=84811

diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c
index 03eba62d..fbec9f29 100644
--- a/src/cairo-ps-surface.c
+++ b/src/cairo-ps-surface.c
@@ -335,7 +335,10 @@ _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
 				 "      cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def\n"
 				 "/g { setgray } bind def\n"
 				 "/rg { setrgbcolor } bind def\n"
-				 "/d1 { setcachedevice } bind def\n");
+				 "/d1 { setcachedevice } bind def\n"
+				 "/cairo_flush_ascii85_file { cairo_ascii85_file status { cairo_ascii85_file flushfile } if } def\n"
+				 "/cairo_image { image cairo_flush_ascii85_file } def\n"
+				 "/cairo_imagemask { imagemask cairo_flush_ascii85_file } def\n");
 
     if (!surface->eps) {
 	_cairo_output_stream_printf (surface->final_stream,
@@ -2679,6 +2682,9 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
 				     "] def\n");
 	_cairo_output_stream_printf (surface->stream,
 				     "/CairoImageDataIndex 0 def\n");
+    } else {
+	_cairo_output_stream_printf (surface->stream,
+				     "/cairo_ascii85_file currentfile /ASCII85Decode filter def\n");
     }
 
     if (use_mask) {
@@ -2713,7 +2719,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
 					 compress_filter);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "    /DataSource currentfile /ASCII85Decode filter /%s filter def\n",
+					 "    /DataSource cairo_ascii85_file /%s filter def\n",
 					 compress_filter);
 	}
 
@@ -2767,15 +2773,16 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
 					 compress_filter);
 	} else {
 	    _cairo_output_stream_printf (surface->stream,
-					 "  /DataSource currentfile /ASCII85Decode filter /%s filter def\n",
+					 "  /DataSource cairo_ascii85_file /%s filter def\n",
 					 compress_filter);
 	}
 
 	_cairo_output_stream_printf (surface->stream,
 				     "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
 				     "end\n"
-				     "%s\n",
+				     "%s%s\n",
 				     ps_image->height,
+				     surface->use_string_datasource ? "" : "cairo_",
 				     stencil_mask ? "imagemask" : "image");
     }
 
@@ -2865,6 +2872,9 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t    *surface,
 				     "] def\n");
 	_cairo_output_stream_printf (surface->stream,
 				     "/CairoImageDataIndex 0 def\n");
+    } else {
+	_cairo_output_stream_printf (surface->stream,
+				     "/cairo_ascii85_file currentfile /ASCII85Decode filter def\n");
     }
 
     _cairo_output_stream_printf (surface->stream,
@@ -2891,14 +2901,15 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t    *surface,
 				     "  } /ASCII85Decode filter /DCTDecode filter def\n");
     } else {
 	_cairo_output_stream_printf (surface->stream,
-				     "  /DataSource currentfile /ASCII85Decode filter /DCTDecode filter def\n");
+				     "  /DataSource cairo_ascii85_file /DCTDecode filter def\n");
     }
 
     _cairo_output_stream_printf (surface->stream,
 				 "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
 				 "end\n"
-				 "image\n",
-				 info.height);
+				 "%simage\n",
+				 info.height,
+				 surface->use_string_datasource ? "" : "cairo_");
 
     if (!surface->use_string_datasource) {
 	/* Emit the image data as a base85-encoded string which will
commit 55f218e8458896616619695a298fa3887026fefd
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat Jun 18 13:16:57 2016 +0930

    ft: set font size to em size when retrieving unhinted metrics
    
    fixes text-unhinted-metrics test

diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c
index 3e485c5b..a997b93b 100644
--- a/src/cairo-ft-font.c
+++ b/src/cairo-ft-font.c
@@ -2206,6 +2206,55 @@ _cairo_ft_scaled_glyph_vertical_layout_bearing_fix (void        *abstract_font,
 }
 
 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;
+
+    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);
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
 _cairo_ft_scaled_glyph_init (void			*abstract_font,
 			     cairo_scaled_glyph_t	*scaled_glyph,
 			     cairo_scaled_glyph_info_t	 info)
@@ -2215,22 +2264,17 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     cairo_ft_unscaled_font_t *unscaled = scaled_font->unscaled;
     FT_GlyphSlot glyph;
     FT_Face face;
-    FT_Error error;
     int load_flags = scaled_font->ft_options.load_flags;
     FT_Glyph_Metrics *metrics;
     double x_factor, y_factor;
     cairo_bool_t vertical_layout = FALSE;
-    cairo_status_t status;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
+    cairo_bool_t scaled_glyph_loaded = FALSE;
 
     face = _cairo_ft_unscaled_font_lock_face (unscaled);
     if (!face)
 	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
 
-    status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled,
-				                &scaled_font->base.scale);
-    if (unlikely (status))
-	goto FAIL;
-
     /* Ignore global advance unconditionally */
     load_flags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
 
@@ -2261,37 +2305,23 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     /* load_flags |= FT_LOAD_COLOR; */
 #endif
 
-    error = FT_Load_Glyph (face,
-			   _cairo_scaled_glyph_index(scaled_glyph),
-			   load_flags);
-    /* XXX ignoring all other errors for now.  They are not fatal, typically
-     * just a glyph-not-found. */
-    if (error == FT_Err_Out_Of_Memory) {
-	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	goto FAIL;
-    }
-
-    glyph = face->glyph;
 
-    /*
-     * synthesize glyphs if requested
-     */
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-	FT_GlyphSlot_Embolden (glyph);
-#endif
+    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
 
-#if HAVE_FT_GLYPHSLOT_OBLIQUE
-    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
-	FT_GlyphSlot_Oblique (glyph);
-#endif
+	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
 
-    if (vertical_layout)
-	_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
+	status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+						    scaled_glyph,
+						    face,
+						    load_flags,
+						    !hint_metrics,
+						    vertical_layout);
+	if (unlikely (status))
+	    goto FAIL;
 
-    if (info & CAIRO_SCALED_GLYPH_INFO_METRICS) {
+	glyph = face->glyph;
+	scaled_glyph_loaded = hint_metrics;
 
-	cairo_bool_t hint_metrics = scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF;
 	/*
 	 * Compute font-space metrics
 	 */
@@ -2389,6 +2419,20 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
     if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
 	cairo_image_surface_t	*surface;
 
+	if (!scaled_glyph_loaded) {
+	    status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+							scaled_glyph,
+							face,
+							load_flags,
+							FALSE,
+							vertical_layout);
+	    if (unlikely (status))
+		goto FAIL;
+
+	    glyph = face->glyph;
+	    scaled_glyph_loaded = TRUE;
+	}
+
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
 	    status = _render_glyph_outline (face, &scaled_font->ft_options.base,
 					    &surface);
@@ -2420,27 +2464,23 @@ _cairo_ft_scaled_glyph_init (void			*abstract_font,
 	 * so reload it. This will probably never occur though
 	 */
 	if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0) {
-	    error = FT_Load_Glyph (face,
-				   _cairo_scaled_glyph_index(scaled_glyph),
-				   load_flags | FT_LOAD_NO_BITMAP);
-	    /* XXX ignoring all other errors for now.  They are not fatal, typically
-	     * just a glyph-not-found. */
-	    if (error == FT_Err_Out_Of_Memory) {
-		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    scaled_glyph_loaded = FALSE;
+	    load_flags |= FT_LOAD_NO_BITMAP;
+	}
+
+	if (!scaled_glyph_loaded) {
+	    status = _cairo_ft_scaled_glyph_load_glyph (scaled_font,
+							scaled_glyph,
+							face,
+							load_flags,
+							FALSE,
+							vertical_layout);
+	    if (unlikely (status))
 		goto FAIL;
-	    }
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-	    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_BOLD)
-		FT_GlyphSlot_Embolden (glyph);
-#endif
-#if HAVE_FT_GLYPHSLOT_OBLIQUE
-	    if (scaled_font->ft_options.synth_flags & CAIRO_FT_SYNTHESIZE_OBLIQUE)
-		FT_GlyphSlot_Oblique (glyph);
-#endif
-	    if (vertical_layout)
-		_cairo_ft_scaled_glyph_vertical_layout_bearing_fix (scaled_font, glyph);
 
+	    glyph = face->glyph;
 	}
+
 	if (glyph->format == FT_GLYPH_FORMAT_OUTLINE)
 	    status = _decompose_glyph_outline (face, &scaled_font->ft_options.base,
 					       &path);
commit 834bab9d1c72daa3fa677f8328d203cd713350db
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Sep 27 08:27:53 2015 +0930

    scaled-font-subsets: if glyph 0 used for rendering, remap to different index
    
    Some broken pdfs use glyph 0 in embedded fonts for rendering instead of .notdef.
    The cmap we use for embedding latin fonts does not allow rendering glyph 0. Ensure
    if glyph 0 is used, it is mapped to a non 0 glyph in the subset.
    
    Bug 89082

diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 866e63d7..e7809f03 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -730,6 +730,11 @@ _cairo_truetype_get_style (cairo_scaled_font_t  	 *scaled_font,
 cairo_private cairo_int_status_t
 _cairo_escape_ps_name (char **ps_name);
 
+#if DEBUG_SUBSETS
+cairo_private void
+dump_scaled_font_subsets (cairo_scaled_font_subsets_t *font_subsets);
+#endif
+
 #endif /* CAIRO_HAS_FONT_SUBSET */
 
 #endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */
diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 196fa999..74bfb9ea 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -71,6 +71,7 @@ typedef struct _cairo_sub_font {
     cairo_bool_t is_composite;
     cairo_bool_t is_user;
     cairo_bool_t use_latin_subset;
+    cairo_bool_t reserve_notdef;
     cairo_scaled_font_subsets_t *parent;
     cairo_scaled_font_t *scaled_font;
     unsigned int font_id;
@@ -283,6 +284,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t	*parent,
     sub_font->is_scaled = is_scaled;
     sub_font->is_composite = is_composite;
     sub_font->is_user = _cairo_font_face_is_user (scaled_font->font_face);
+    sub_font->reserve_notdef = !sub_font->is_user;
     _cairo_sub_font_init_key (sub_font, scaled_font);
 
     sub_font->parent = parent;
@@ -533,23 +535,8 @@ _cairo_sub_font_add_glyph (cairo_sub_font_t	   *sub_font,
     else
 	num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_current_subset;
 
-    /* Reserve first glyph in subset for the .notdef glyph except for
-     * Type 3 fonts */
-    if (*num_glyphs_in_subset_ptr == 0 &&
-	scaled_font_glyph_index != 0 &&
-	! _cairo_font_face_is_user (sub_font->scaled_font->font_face))
-    {
-	status = _cairo_sub_font_add_glyph (sub_font,
-					    0,
-					    is_latin,
-					    0,
-					    0,
-					    NULL,
-					    -1,
-					    &sub_font_glyph);
-	if (unlikely (status))
-	    return status;
-    }
+    if ((*num_glyphs_in_subset_ptr == 0) && sub_font->reserve_notdef)
+	(*num_glyphs_in_subset_ptr)++;
 
     sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
 						   is_latin ? 0 : sub_font->current_subset,
@@ -713,13 +700,26 @@ _cairo_sub_font_collect (void *entry, void *closure)
 	collection->max_glyph = 0;
 	memset (collection->latin_to_subset_glyph_index, 0, 256*sizeof(unsigned long));
 
+	if (sub_font->reserve_notdef) {
+	    // add .notdef
+	    collection->glyphs[0] = 0;
+	    collection->utf8[0] = 0;
+	    collection->to_latin_char[0] = 0;
+	    collection->latin_to_subset_glyph_index[0] = 0;
+	    collection->num_glyphs++;
+	}
+
 	_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
 				   _cairo_sub_font_glyph_collect, collection);
 	if (collection->status)
 	    break;
+
 	if (collection->num_glyphs == 0)
 	    continue;
 
+	if (sub_font->reserve_notdef && collection->num_glyphs == 1)
+	    continue;
+
         /* Ensure the resulting array has no uninitialized holes */
 	assert (collection->num_glyphs == collection->max_glyph + 1);
 
@@ -1121,6 +1121,87 @@ _cairo_string_equal (const void *key_a, const void *key_b)
 	return FALSE;
 }
 
+#if DEBUG_SUBSETS
+
+static void
+dump_glyph (void *entry, void *closure)
+{
+    cairo_sub_font_glyph_t *glyph = entry;
+    char buf[10];
+    int i;
+
+    printf("    font_glyph_index: %ld\n", glyph->base.hash);
+    printf("      subset_id: %d\n", glyph->subset_id);
+    printf("      subset_glyph_index: %d\n", glyph->subset_glyph_index);
+    printf("      x_advance: %f\n", glyph->x_advance);
+    printf("      y_advance: %f\n", glyph->y_advance);
+    printf("      is_latin: %d\n", glyph->is_latin);
+    printf("      latin_character: '%c' (0x%02x)\n", glyph->latin_character, glyph->latin_character);
+    printf("      is_latin: %d\n", glyph->is_latin);
+    printf("      is_mapped: %d\n", glyph->is_mapped);
+    printf("      unicode: U+%04x\n", glyph->unicode);
+    memset(buf, 0, sizeof(buf));
+    memcpy(buf, glyph->utf8, glyph->utf8_len);
+    printf("      utf8: '%s'\n", buf);
+    printf("      utf8 (hex):");
+    for (i = 0; i < glyph->utf8_len; i++)
+	printf(" 0x%02x", glyph->utf8[0]);
+    printf("\n\n");
+}
+
+static void
+dump_subfont (cairo_sub_font_t *sub_font)
+{
+    while (sub_font) {
+	printf("    font_id: %d\n", sub_font->font_id);
+	printf("    current_subset: %d\n", sub_font->current_subset);
+	printf("    is_scaled: %d\n", sub_font->is_scaled);
+	printf("    is_composite: %d\n", sub_font->is_composite);
+	printf("    is_user: %d\n", sub_font->is_user);
+	printf("    use_latin_subset: %d\n", sub_font->use_latin_subset);
+	printf("    reserve_notdef: %d\n", sub_font->reserve_notdef);
+	printf("    num_glyphs_in_current_subset: %d\n", sub_font->num_glyphs_in_current_subset);
+	printf("    num_glyphs_in_latin_subset: %d\n", sub_font->num_glyphs_in_latin_subset);
+	printf("    max_glyphs_per_subset: %d\n\n", sub_font->max_glyphs_per_subset);
+
+	_cairo_hash_table_foreach (sub_font->sub_font_glyphs, dump_glyph, NULL);
+
+	printf("\n");
+	sub_font = sub_font->next;
+    }
+}
+
+void
+dump_scaled_font_subsets (cairo_scaled_font_subsets_t *font_subsets)
+{
+    printf("font subsets\n");
+    switch (font_subsets->type)
+    {
+	case CAIRO_SUBSETS_SCALED:
+	    printf("  type: CAIRO_SUBSETS_SCALED\n");
+	    break;
+	case CAIRO_SUBSETS_SIMPLE:
+	    printf("  type: CAIRO_SUBSETS_SIMPLE\n");
+	    break;
+	case CAIRO_SUBSETS_COMPOSITE:
+	    printf("  type: CAIRO_SUBSETS_COMPOSITE\n");
+	    break;
+    }
+    printf("  use_latin_subset: %d\n", font_subsets->use_latin_subset);
+    printf("  max_glyphs_per_unscaled_subset_used: %d\n", font_subsets->max_glyphs_per_unscaled_subset_used);
+    printf("  max_glyphs_per_scaled_subset_used: %d\n", font_subsets->max_glyphs_per_scaled_subset_used);
+    printf("  num_sub_fonts: %d\n\n", font_subsets->num_sub_fonts);
+
+    printf("  scaled subsets:\n");
+    dump_subfont (font_subsets->scaled_sub_fonts_list);
+
+    printf("\n  unscaled subsets:\n");
+    dump_subfont (font_subsets->unscaled_sub_fonts_list);
+}
+
+#endif
+
+
 static void
 _cairo_string_init_key (cairo_string_entry_t *key, char *s)
 {
commit 0245756c214506a3aa9de550a3c7b1e4702be7cb
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Mon Sep 7 22:20:08 2015 +0930

    cff: opentype fonts always use gid to lookup glyph
    
    Bug 91902

diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c
index 3ffe6f66..775ca61b 100644
--- a/src/cairo-cff-subset.c
+++ b/src/cairo-cff-subset.c
@@ -1780,7 +1780,7 @@ cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
 
     font->subset_subroutines = TRUE;
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
-	if (font->is_cid) {
+	if (font->is_cid && !font->is_opentype) {
 	    cid = font->scaled_font_subset->glyphs[i];
 	    status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph);
 	    if (unlikely (status))
@@ -1847,11 +1847,15 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
 
     font->num_subset_fontdicts = 0;
     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
-	cid = font->scaled_font_subset->glyphs[i];
-	status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
-	if (unlikely (status)) {
-	    free (reverse_map);
-	    return status;
+	if (font->is_opentype) {
+	    gid = font->scaled_font_subset->glyphs[i];
+	} else {
+	    cid = font->scaled_font_subset->glyphs[i];
+	    status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
+	    if (unlikely (status)) {
+		free (reverse_map);
+		return status;
+	    }
 	}
 
         fd = font->fdselect[gid];
commit 2f830badefa8287e85b5ed8a670a827e133241f5
Author: Uli Schlachter <psychon at znc.in>
Date:   Tue Mar 7 10:05:43 2017 +0100

    xlib: Call XSync() before ignoring errors
    
    The code here wants to ignore errors for a specific request. To do so,
    it sets a no-op error handler. However, it could happen that some
    previous request caused an error and this error will also be ignored by
    the no-op error handler.
    
    To avoid this, call XSync() before setting the error handler. This makes
    sure that all pending errors are handled.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>
    Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index ffea476f..ee14af27 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -793,6 +793,7 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
 
 	    _cairo_xlib_shm_surface_get_ximage (&image->base, &shm_image);
 
+	    XSync (display->display, False);
 	    old_handler = XSetErrorHandler (_noop_error_handler);
 	    success = XShmGetImage (display->display,
 				    surface->drawable,
@@ -814,6 +815,7 @@ _get_image_surface (cairo_xlib_surface_t    *surface,
     if (surface->use_pixmap == 0) {
 	cairo_xlib_error_func_t old_handler;
 
+	XSync (display->display, False);
 	old_handler = XSetErrorHandler (_noop_error_handler);
 
 	ximage = XGetImage (display->display,
commit 2d47ccbc012d46818e42b193acd81f0a53911f5c
Author: Debarshi Ray <debarshir at freedesktop.org>
Date:   Thu Dec 15 12:41:39 2016 +0100

    doc: Fix the units used by cairo_surface_create_similar_image
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=99094
    
    Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 4c534e92..fa0ca37d 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -549,8 +549,8 @@ cairo_surface_create_similar (cairo_surface_t  *other,
  * cairo_surface_create_similar_image:
  * @other: an existing surface used to select the preference of the new surface
  * @format: the format for the new surface
- * @width: width of the new surface, (in device-space units)
- * @height: height of the new surface (in device-space units)
+ * @width: width of the new surface, (in pixels)
+ * @height: height of the new surface (in pixels)
  *
  * Create a new image surface that is as compatible as possible for uploading
  * to and the use in conjunction with an existing surface. However, this surface
commit 80a0c20de2c2286cc37506a39667378a4ddfea86
Author: Debarshi Ray <debarshir at freedesktop.org>
Date:   Thu Dec 15 12:50:13 2016 +0100

    doc: Clarify when the device scale is inherited and when it isn't
    
    In short, cairo_surface_create_similar inherits it, while
    cairo_surface_create_similar_image doesn't. It wasn't obvious without
    reading the code or explicitly checking the device scale of the new
    surface.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=99094
    
    Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>

diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index bfe3fa10..4c534e92 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -463,10 +463,11 @@ _cairo_surface_copy_similar_properties (cairo_surface_t *surface,
  *
  * Create a new surface that is as compatible as possible with an
  * existing surface. For example the new surface will have the same
- * fallback resolution and font options as @other. Generally, the new
- * surface will also use the same backend as @other, unless that is
- * not possible for some reason. The type of the returned surface may
- * be examined with cairo_surface_get_type().
+ * device scale, fallback resolution and font options as
+ * @other. Generally, the new surface will also use the same backend
+ * as @other, unless that is not possible for some reason. The type of
+ * the returned surface may be examined with
+ * cairo_surface_get_type().
  *
  * Initially the surface contents are all 0 (transparent if contents
  * have transparency, black otherwise.)
@@ -553,7 +554,9 @@ cairo_surface_create_similar (cairo_surface_t  *other,
  *
  * Create a new image surface that is as compatible as possible for uploading
  * to and the use in conjunction with an existing surface. However, this surface
- * can still be used like any normal image surface.
+ * can still be used like any normal image surface. Unlike
+ * cairo_surface_create_similar() the new image surface won't inherit
+ * the device scale from @other.
  *
  * Initially the surface contents are all 0 (transparent if contents
  * have transparency, black otherwise.)


More information about the cairo-commit mailing list