mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 21:08:10 +02:00
Implement PS Type 3 font image support
There does not appear to be any way of emulating PDF inline images in PostScript so we call back to the PS or PDF surface to emit the image.
This commit is contained in:
parent
5b05034cc9
commit
42c212135d
4 changed files with 104 additions and 30 deletions
|
|
@ -3397,6 +3397,46 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface,
|
|||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
|
||||
cairo_output_stream_t *stream)
|
||||
{
|
||||
unsigned char *byte, output_byte;
|
||||
int row, col, num_cols;
|
||||
|
||||
/* The only image type supported by Type 3 fonts are 1-bit image
|
||||
* masks */
|
||||
assert (image->format == CAIRO_FORMAT_A1);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"BI\n"
|
||||
"/IM true\n"
|
||||
"/W %d\n"
|
||||
"/H %d\n"
|
||||
"/BPC 1\n"
|
||||
"/D [1 0]\n",
|
||||
image->width,
|
||||
image->height);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"ID ");
|
||||
|
||||
num_cols = (image->width + 7) / 8;
|
||||
for (row = 0; row < image->height; row++) {
|
||||
byte = image->data + row * image->stride;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
|
||||
_cairo_output_stream_write (stream, &output_byte, 1);
|
||||
byte++;
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"\nEI\n");
|
||||
|
||||
return _cairo_output_stream_get_status (stream);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
|
|
@ -3430,7 +3470,9 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
|
|||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, NULL);
|
||||
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
|
||||
NULL,
|
||||
_cairo_pdf_emit_imagemask);
|
||||
|
||||
for (i = 0; i < font_subset->num_glyphs; i++) {
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
|
|
|
|||
|
|
@ -374,6 +374,51 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_emit_imagemask (cairo_image_surface_t *image,
|
||||
cairo_output_stream_t *stream)
|
||||
{
|
||||
unsigned char *row, *byte;
|
||||
int rows, cols;
|
||||
|
||||
/* The only image type supported by Type 3 fonts are 1-bit image
|
||||
* masks */
|
||||
assert (image->format == CAIRO_FORMAT_A1);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"<<\n"
|
||||
" /ImageType 1\n"
|
||||
" /Width %d\n"
|
||||
" /Height %d\n"
|
||||
" /ImageMatrix [%d 0 0 %d 0 %d]\n"
|
||||
" /Decode [1 0]\n"
|
||||
" /BitsPerComponent 1\n",
|
||||
image->width,
|
||||
image->height,
|
||||
image->width,
|
||||
-image->height,
|
||||
image->height);
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
" /DataSource {<");
|
||||
for (row = image->data, rows = image->height; rows; row += image->stride, rows--) {
|
||||
for (byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
|
||||
unsigned char output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
|
||||
_cairo_output_stream_printf (stream, "%02x ", output_byte);
|
||||
}
|
||||
_cairo_output_stream_printf (stream, "\n ");
|
||||
}
|
||||
_cairo_output_stream_printf (stream,
|
||||
" >}\n");
|
||||
_cairo_output_stream_printf (stream,
|
||||
">>\n");
|
||||
|
||||
_cairo_output_stream_printf (stream,
|
||||
"imagemask\n");
|
||||
|
||||
return _cairo_output_stream_get_status (stream);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
|
||||
cairo_scaled_font_subset_t *font_subset)
|
||||
|
|
@ -401,7 +446,9 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface,
|
|||
"/Encoding 256 array def\n"
|
||||
"0 1 255 { Encoding exch /.notdef put } for\n");
|
||||
|
||||
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font, NULL);
|
||||
type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
|
||||
NULL,
|
||||
_cairo_ps_emit_imagemask);
|
||||
|
||||
for (i = 1; i < font_subset->num_glyphs; i++) {
|
||||
if (font_subset->glyph_names != NULL) {
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
#include "cairo-surface-private.h"
|
||||
#include "cairo-pdf-operators-private.h"
|
||||
|
||||
typedef cairo_status_t (*cairo_type3_glyph_surface_emit_image_t) (cairo_image_surface_t *image,
|
||||
cairo_output_stream_t *stream);
|
||||
|
||||
typedef struct cairo_type3_glyph_surface {
|
||||
cairo_surface_t base;
|
||||
|
||||
|
|
@ -47,11 +50,13 @@ typedef struct cairo_type3_glyph_surface {
|
|||
cairo_output_stream_t *stream;
|
||||
cairo_pdf_operators_t pdf_operators;
|
||||
cairo_matrix_t cairo_to_pdf;
|
||||
cairo_type3_glyph_surface_emit_image_t emit_image;
|
||||
} cairo_type3_glyph_surface_t;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream);
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream,
|
||||
cairo_type3_glyph_surface_emit_image_t emit_image);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_type3_glyph_surface_emit_notdef_glyph (void *abstract_surface,
|
||||
|
|
|
|||
|
|
@ -42,8 +42,9 @@
|
|||
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream)
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream,
|
||||
cairo_type3_glyph_surface_emit_image_t emit_image)
|
||||
{
|
||||
cairo_type3_glyph_surface_t *surface;
|
||||
cairo_matrix_t invert_y_axis;
|
||||
|
|
@ -57,6 +58,7 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
surface->scaled_font = scaled_font;
|
||||
surface->stream = stream;
|
||||
surface->emit_image = emit_image;
|
||||
|
||||
/* Setup the transform from the user-font device space to Type 3
|
||||
* font space. The Type 3 font space is defined by the FontMatrix
|
||||
|
|
@ -81,8 +83,6 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
|
|||
{
|
||||
cairo_status_t status;
|
||||
cairo_image_surface_t *image_mask;
|
||||
unsigned char *byte, output_byte;
|
||||
int row, col, num_cols;
|
||||
|
||||
/* The only image type supported by Type 3 fonts are 1-bit image
|
||||
* masks */
|
||||
|
|
@ -104,30 +104,10 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
|
|||
image_matrix->x0,
|
||||
image_matrix->y0);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"BI\n"
|
||||
"/IM true\n"
|
||||
"/W %d\n"
|
||||
"/H %d\n"
|
||||
"/BPC 1\n"
|
||||
"/D [1 0]\n",
|
||||
image_mask->width,
|
||||
image_mask->height);
|
||||
status = surface->emit_image (image_mask, surface->stream);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"ID ");
|
||||
|
||||
num_cols = (image_mask->width + 7) / 8;
|
||||
for (row = 0; row < image_mask->height; row++) {
|
||||
byte = image_mask->data + row * image_mask->stride;
|
||||
for (col = 0; col < num_cols; col++) {
|
||||
output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
|
||||
_cairo_output_stream_write (surface->stream, &output_byte, 1);
|
||||
byte++;
|
||||
}
|
||||
}
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"\nEI Q\n");
|
||||
"Q\n");
|
||||
|
||||
if (image_mask != image)
|
||||
cairo_surface_destroy (&image_mask->base);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue