[cairo-commit] 2 commits - src/cairo-pdf-surface.c

Adrian Johnson ajohnson at kemper.freedesktop.org
Sun Sep 29 06:18:56 PDT 2013


 src/cairo-pdf-surface.c |  215 ++++++++++++++++++++++++++++++------------------
 1 file changed, 138 insertions(+), 77 deletions(-)

New commits:
commit 5e6e4536716197ea0605732d32959c57ea8bb140
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Sep 29 22:23:31 2013 +0930

    pdf: stencil masks may be opaque

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index a5a43bc..a8a1217 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2301,6 +2301,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 
     /* This is the only image format we support, which simplifies things. */
     assert (image->format == CAIRO_FORMAT_ARGB32 ||
+	    image->format == CAIRO_FORMAT_RGB24 ||
 	    image->format == CAIRO_FORMAT_A8 ||
 	    image->format == CAIRO_FORMAT_A1 );
 
@@ -2309,11 +2310,10 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 	assert (transparency == CAIRO_IMAGE_IS_OPAQUE ||
 		transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA);
     } else {
-	if (transparency == CAIRO_IMAGE_IS_OPAQUE)
-	    return status;
+	assert (transparency != CAIRO_IMAGE_IS_OPAQUE);
     }
 
-    if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA) {
+    if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA || transparency == CAIRO_IMAGE_IS_OPAQUE) {
 	alpha_size = (image->width + 7) / 8 * image->height;
 	alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
     } else {
@@ -2328,7 +2328,10 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
 
     i = 0;
     for (y = 0; y < image->height; y++) {
-	if (image->format == CAIRO_FORMAT_A1) {
+	if (transparency == CAIRO_IMAGE_IS_OPAQUE) {
+	    for (x = 0; x < (image->width + 7) / 8; x++)
+		alpha[i++] = 0xff;
+	} else if (image->format == CAIRO_FORMAT_A1) {
 	    pixel8 = (uint8_t *) (image->data + y * image->stride);
 
 	    for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
commit d3a8d5a9c266b79b0059dd309b5e3eff3ce81a64
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun Sep 29 22:18:06 2013 +0930

    pdf: Support stencil masks with jpeg/jpx/jbig2 embedding

diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c
index 1d6b8ec..a5a43bc 100644
--- a/src/cairo-pdf-surface.c
+++ b/src/cairo-pdf-surface.c
@@ -2464,7 +2464,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t              *surface,
             goto CLEANUP;
     }
 
-    if (surface_entry->stencil_mask) {
+    if (surface_entry->smask || surface_entry->stencil_mask) {
 	return _cairo_pdf_surface_emit_smask (surface, image,
 					      surface_entry->stencil_mask,
 					      surface_entry->interpolate,
@@ -2716,24 +2716,44 @@ _cairo_pdf_surface_emit_jbig2_image (cairo_pdf_surface_t              *surface,
     else
 	smask_buf[0] = 0;
 
-    status = _cairo_pdf_surface_open_stream (surface,
-					     &surface_entry->surface_res,
-					     FALSE,
-					     "   /Type /XObject\n"
-					     "   /Subtype /Image\n"
-					     "   /Width %d\n"
-					     "   /Height %d\n"
-					     "   /ColorSpace /DeviceGray\n"
-					     "   /BitsPerComponent 1\n"
-					     "   /Interpolate %s\n"
-					     "%s"
-					     "   /Filter /JBIG2Decode\n"
-					     "%s",
-					     info.width,
-					     info.height,
-					     surface_entry->interpolate ? "true" : "false",
-					     smask_buf,
-					     decode_parms_buf);
+    if (surface_entry->stencil_mask) {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /ImageMask true\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /Interpolate %s\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Decode [1 0]\n"
+						 "   /Filter /JPXDecode\n"
+						 "%s",
+						 info.width,
+						 info.height,
+						 surface_entry->interpolate ? "true" : "false",
+						 decode_parms_buf);
+    } else {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /ColorSpace /DeviceGray\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Interpolate %s\n"
+						 "%s"
+						 "   /Filter /JBIG2Decode\n"
+						 "%s",
+						 info.width,
+						 info.height,
+						 surface_entry->interpolate ? "true" : "false",
+						 smask_buf,
+						 decode_parms_buf);
+    }
     if (unlikely(status))
 	return status;
 
@@ -2766,25 +2786,49 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t              *surface,
     if (status)
 	return status;
 
+    if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if ((surface_entry->stencil_mask) && info.bits_per_component != 1)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     if (surface_entry->smask_res.id)
 	snprintf(smask_buf, sizeof(smask_buf), "   /SMask %d 0 R\n", surface_entry->smask_res.id);
     else
 	smask_buf[0] = 0;
 
-    status = _cairo_pdf_surface_open_stream (surface,
-					     &surface_entry->surface_res,
-					     FALSE,
-					     "   /Type /XObject\n"
-					     "   /Subtype /Image\n"
-					     "   /Width %d\n"
-					     "   /Height %d\n"
-					     "   /Interpolate %s\n"
-					     "%s"
-					     "   /Filter /JPXDecode\n",
-					     info.width,
-					     info.height,
-					     surface_entry->interpolate ? "true" : "false",
-					     smask_buf);
+    if (surface_entry->stencil_mask) {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /ImageMask true\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /Interpolate %s\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Decode [1 0]\n"
+						 "   /Filter /JPXDecode\n",
+						 info.width,
+						 info.height,
+						 surface_entry->interpolate ? "true" : "false");
+    } else {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /Interpolate %s\n"
+						 "%s"
+						 "   /Filter /JPXDecode\n",
+						 info.width,
+						 info.height,
+						 surface_entry->interpolate ? "true" : "false",
+						 smask_buf);
+    }
     if (status)
 	return status;
 
@@ -2817,6 +2861,12 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t              *surface,
     if (unlikely (status))
 	return status;
 
+    if ((surface_entry->smask || surface_entry->stencil_mask) && info.num_components != 1)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    if ((surface_entry->stencil_mask) && info.bits_per_component != 1)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
     switch (info.num_components) {
 	case 1:
 	    colorspace = "/DeviceGray";
@@ -2836,24 +2886,42 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t              *surface,
     else
 	smask_buf[0] = 0;
 
-    status = _cairo_pdf_surface_open_stream (surface,
-					     &surface_entry->surface_res,
-					     FALSE,
-					     "   /Type /XObject\n"
-					     "   /Subtype /Image\n"
-					     "   /Width %d\n"
-					     "   /Height %d\n"
-					     "   /ColorSpace %s\n"
-					     "   /Interpolate %s\n"
-					     "   /BitsPerComponent %d\n"
-					     "%s"
-					     "   /Filter /DCTDecode\n",
-					     info.width,
-					     info.height,
-					     colorspace,
-					     surface_entry->interpolate ? "true" : "false",
-					     info.bits_per_component,
-					     smask_buf);
+    if (surface_entry->stencil_mask) {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /ImageMask true\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /Interpolate %s\n"
+						 "   /BitsPerComponent 1\n"
+						 "   /Decode [1 0]\n"
+						 "   /Filter /DCTDecode\n",
+						 info.width,
+						 info.height,
+						 surface_entry->interpolate ? "true" : "false");
+    } else {
+	status = _cairo_pdf_surface_open_stream (surface,
+						 &surface_entry->surface_res,
+						 FALSE,
+						 "   /Type /XObject\n"
+						 "   /Subtype /Image\n"
+						 "   /Width %d\n"
+						 "   /Height %d\n"
+						 "   /ColorSpace %s\n"
+						 "   /Interpolate %s\n"
+						 "   /BitsPerComponent %d\n"
+						 "%s"
+						 "   /Filter /DCTDecode\n",
+						 info.width,
+						 info.height,
+						 colorspace,
+						 surface_entry->interpolate ? "true" : "false",
+						 info.bits_per_component,
+						 smask_buf);
+    }
     if (unlikely (status))
 	return status;
 
@@ -2872,19 +2940,17 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t        *surface,
     cairo_int_status_t status;
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
-	if (!source->hash_entry->stencil_mask) {
-	    status = _cairo_pdf_surface_emit_jbig2_image (surface, source->surface, source->hash_entry);
-	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-		return status;
+	status = _cairo_pdf_surface_emit_jbig2_image (surface, source->surface, source->hash_entry);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	    return status;
 
-	    status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry);
-	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-		return status;
+	status = _cairo_pdf_surface_emit_jpx_image (surface, source->surface, source->hash_entry);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	    return status;
 
-	    status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
-	    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-		return status;
-	}
+	status = _cairo_pdf_surface_emit_jpeg_image (surface, source->surface, source->hash_entry);
+	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+	    return status;
     }
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
@@ -2896,17 +2962,9 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t        *surface,
     if (unlikely (status))
 	return status;
 
-    if (source->hash_entry->smask) {
-	status = _cairo_pdf_surface_emit_smask (surface,
-						image,
-						FALSE,
-						source->hash_entry->interpolate,
-						&source->hash_entry->surface_res);
-    } else {
-	status = _cairo_pdf_surface_emit_image (surface,
-						image,
-						source->hash_entry);
-    }
+    status = _cairo_pdf_surface_emit_image (surface,
+					    image,
+					    source->hash_entry);
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
 	_cairo_surface_release_source_image (source->surface, image, image_extra);


More information about the cairo-commit mailing list