1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2004 Red Hat, Inc
5 * Copyright © 2006 Red Hat, Inc
6 * Copyright © 2007, 2008 Adrian Johnson
8 * This library is free software; you can redistribute it and/or
9 * modify it either under the terms of the GNU Lesser General Public
10 * License version 2.1 as published by the Free Software Foundation
11 * (the "LGPL") or, at your option, under the terms of the Mozilla
12 * Public License Version 1.1 (the "MPL"). If you do not alter this
13 * notice, a recipient may use your version of this file under either
14 * the MPL or the LGPL.
16 * You should have received a copy of the LGPL along with this library
17 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
19 * You should have received a copy of the MPL along with this library
20 * in the file COPYING-MPL-1.1
22 * The contents of this file are subject to the Mozilla Public License
23 * Version 1.1 (the "License"); you may not use this file except in
24 * compliance with the License. You may obtain a copy of the License at
25 * http://www.mozilla.org/MPL/
27 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29 * the specific language governing rights and limitations.
31 * The Original Code is the cairo graphics library.
33 * The Initial Developer of the Original Code is University of Southern
37 * Kristian Høgsberg <krh@redhat.com>
38 * Carl Worth <cworth@cworth.org>
39 * Adrian Johnson <ajohnson@redneon.com>
44 #if CAIRO_HAS_PDF_OPERATORS
46 #include "cairo-error-private.h"
47 #include "cairo-pdf-operators-private.h"
48 #include "cairo-path-fixed-private.h"
49 #include "cairo-output-stream-private.h"
50 #include "cairo-scaled-font-subsets-private.h"
53 _cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators);
57 _cairo_pdf_operators_init (cairo_pdf_operators_t *pdf_operators,
58 cairo_output_stream_t *stream,
59 cairo_matrix_t *cairo_to_pdf,
60 cairo_scaled_font_subsets_t *font_subsets)
62 pdf_operators->stream = stream;
63 pdf_operators->cairo_to_pdf = *cairo_to_pdf;
64 pdf_operators->font_subsets = font_subsets;
65 pdf_operators->use_font_subset = NULL;
66 pdf_operators->use_font_subset_closure = NULL;
67 pdf_operators->in_text_object = FALSE;
68 pdf_operators->num_glyphs = 0;
69 pdf_operators->has_line_style = FALSE;
70 pdf_operators->use_actual_text = FALSE;
74 _cairo_pdf_operators_fini (cairo_pdf_operators_t *pdf_operators)
76 return _cairo_pdf_operators_flush (pdf_operators);
80 _cairo_pdf_operators_set_font_subsets_callback (cairo_pdf_operators_t *pdf_operators,
81 cairo_pdf_operators_use_font_subset_t use_font_subset,
84 pdf_operators->use_font_subset = use_font_subset;
85 pdf_operators->use_font_subset_closure = closure;
88 /* Change the output stream to a different stream.
89 * _cairo_pdf_operators_flush() should always be called before calling
93 _cairo_pdf_operators_set_stream (cairo_pdf_operators_t *pdf_operators,
94 cairo_output_stream_t *stream)
96 pdf_operators->stream = stream;
97 pdf_operators->has_line_style = FALSE;
101 _cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operators,
102 cairo_matrix_t *cairo_to_pdf)
104 pdf_operators->cairo_to_pdf = *cairo_to_pdf;
105 pdf_operators->has_line_style = FALSE;
109 _cairo_pdf_operators_enable_actual_text (cairo_pdf_operators_t *pdf_operators,
112 pdf_operators->use_actual_text = enable;
115 /* Finish writing out any pending commands to the stream. This
116 * function must be called by the surface before emitting anything
117 * into the PDF stream.
119 * pdf_operators may leave the emitted PDF for some operations
120 * unfinished in case subsequent operations can be merged. This
121 * function will finish off any incomplete operation so the stream
122 * will be in a state where the surface may emit its own PDF
123 * operations (eg changing patterns).
127 _cairo_pdf_operators_flush (cairo_pdf_operators_t *pdf_operators)
129 cairo_status_t status = CAIRO_STATUS_SUCCESS;
131 if (pdf_operators->in_text_object)
132 status = _cairo_pdf_operators_end_text (pdf_operators);
137 /* Reset the known graphics state of the PDF consumer. ie no
138 * assumptions will be made about the state. The next time a
139 * particular graphics state is required (eg line width) the state
140 * operator is always emitted and then remembered for subsequent
143 * This should be called when starting a new stream or after emitting
144 * the 'Q' operator (where pdf-operators functions were called inside
148 _cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators)
150 pdf_operators->has_line_style = FALSE;
153 /* A word wrap stream can be used as a filter to do word wrapping on
154 * top of an existing output stream. The word wrapping is quite
155 * simple, using isspace to determine characters that separate
156 * words. Any word that will cause the column count exceed the given
157 * max_column will have a '\n' character emitted before it.
159 * The stream is careful to maintain integrity for words that cross
160 * the boundary from one call to write to the next.
162 * Note: This stream does not guarantee that the output will never
163 * exceed max_column. In particular, if a single word is larger than
164 * max_column it will not be broken up.
167 typedef enum _cairo_word_wrap_state {
168 WRAP_STATE_DELIMITER,
172 } cairo_word_wrap_state_t;
175 typedef struct _word_wrap_stream {
176 cairo_output_stream_t base;
177 cairo_output_stream_t *output;
180 cairo_word_wrap_state_t state;
181 cairo_bool_t in_escape;
183 } word_wrap_stream_t;
187 /* Emit word bytes up to the next delimiter character */
189 _word_wrap_stream_count_word_up_to (word_wrap_stream_t *stream,
190 const unsigned char *data, int length)
192 const unsigned char *s = data;
196 if (_cairo_isspace (*s) || *s == '<' || *s == '(') {
197 stream->state = WRAP_STATE_DELIMITER;
207 _cairo_output_stream_write (stream->output, data, count);
213 /* Emit hexstring bytes up to either the end of the ASCII hexstring or the number
214 * of columns remaining.
217 _word_wrap_stream_count_hexstring_up_to (word_wrap_stream_t *stream,
218 const unsigned char *data, int length)
220 const unsigned char *s = data;
222 cairo_bool_t newline = FALSE;
228 stream->state = WRAP_STATE_DELIMITER;
232 if (stream->column > stream->max_column) {
240 _cairo_output_stream_write (stream->output, data, count);
243 _cairo_output_stream_printf (stream->output, "\n");
250 /* Count up to either the end of the string or the number of columns
254 _word_wrap_stream_count_string_up_to (word_wrap_stream_t *stream,
255 const unsigned char *data, int length)
257 const unsigned char *s = data;
259 cairo_bool_t newline = FALSE;
264 if (!stream->in_escape) {
266 stream->state = WRAP_STATE_DELIMITER;
270 stream->in_escape = TRUE;
271 stream->escape_digits = 0;
272 } else if (stream->column > stream->max_column) {
277 if (!_cairo_isdigit(*s) || ++stream->escape_digits == 3)
278 stream->in_escape = FALSE;
284 _cairo_output_stream_write (stream->output, data, count);
287 _cairo_output_stream_printf (stream->output, "\\\n");
294 static cairo_status_t
295 _word_wrap_stream_write (cairo_output_stream_t *base,
296 const unsigned char *data,
299 word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
303 switch (stream->state) {
304 case WRAP_STATE_WORD:
305 count = _word_wrap_stream_count_word_up_to (stream, data, length);
307 case WRAP_STATE_HEXSTRING:
308 count = _word_wrap_stream_count_hexstring_up_to (stream, data, length);
310 case WRAP_STATE_STRING:
311 count = _word_wrap_stream_count_string_up_to (stream, data, length);
313 case WRAP_STATE_DELIMITER:
316 if (*data == '\n' || stream->column >= stream->max_column) {
317 _cairo_output_stream_printf (stream->output, "\n");
319 } else if (*data == '<') {
320 stream->state = WRAP_STATE_HEXSTRING;
321 } else if (*data == '(') {
322 stream->state = WRAP_STATE_STRING;
323 } else if (!_cairo_isspace (*data)) {
324 stream->state = WRAP_STATE_WORD;
327 _cairo_output_stream_write (stream->output, data, 1);
339 return _cairo_output_stream_get_status (stream->output);
342 static cairo_status_t
343 _word_wrap_stream_close (cairo_output_stream_t *base)
345 word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
347 return _cairo_output_stream_get_status (stream->output);
350 static cairo_output_stream_t *
351 _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
353 word_wrap_stream_t *stream;
356 return _cairo_output_stream_create_in_error (output->status);
358 stream = malloc (sizeof (word_wrap_stream_t));
359 if (unlikely (stream == NULL)) {
360 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
361 return (cairo_output_stream_t *) &_cairo_output_stream_nil;
364 _cairo_output_stream_init (&stream->base,
365 _word_wrap_stream_write,
367 _word_wrap_stream_close);
368 stream->output = output;
369 stream->max_column = max_column;
371 stream->state = WRAP_STATE_DELIMITER;
372 stream->in_escape = FALSE;
373 stream->escape_digits = 0;
375 return &stream->base;
378 typedef struct _pdf_path_info {
379 cairo_output_stream_t *output;
380 cairo_matrix_t *path_transform;
381 cairo_line_cap_t line_cap;
382 cairo_point_t last_move_to_point;
383 cairo_bool_t has_sub_path;
386 static cairo_status_t
387 _cairo_pdf_path_move_to (void *closure,
388 const cairo_point_t *point)
390 pdf_path_info_t *info = closure;
391 double x = _cairo_fixed_to_double (point->x);
392 double y = _cairo_fixed_to_double (point->y);
394 info->last_move_to_point = *point;
395 info->has_sub_path = FALSE;
396 cairo_matrix_transform_point (info->path_transform, &x, &y);
397 _cairo_output_stream_printf (info->output,
400 return _cairo_output_stream_get_status (info->output);
403 static cairo_status_t
404 _cairo_pdf_path_line_to (void *closure,
405 const cairo_point_t *point)
407 pdf_path_info_t *info = closure;
408 double x = _cairo_fixed_to_double (point->x);
409 double y = _cairo_fixed_to_double (point->y);
411 if (info->line_cap != CAIRO_LINE_CAP_ROUND &&
412 ! info->has_sub_path &&
413 point->x == info->last_move_to_point.x &&
414 point->y == info->last_move_to_point.y)
416 return CAIRO_STATUS_SUCCESS;
419 info->has_sub_path = TRUE;
420 cairo_matrix_transform_point (info->path_transform, &x, &y);
421 _cairo_output_stream_printf (info->output,
424 return _cairo_output_stream_get_status (info->output);
427 static cairo_status_t
428 _cairo_pdf_path_curve_to (void *closure,
429 const cairo_point_t *b,
430 const cairo_point_t *c,
431 const cairo_point_t *d)
433 pdf_path_info_t *info = closure;
434 double bx = _cairo_fixed_to_double (b->x);
435 double by = _cairo_fixed_to_double (b->y);
436 double cx = _cairo_fixed_to_double (c->x);
437 double cy = _cairo_fixed_to_double (c->y);
438 double dx = _cairo_fixed_to_double (d->x);
439 double dy = _cairo_fixed_to_double (d->y);
441 info->has_sub_path = TRUE;
442 cairo_matrix_transform_point (info->path_transform, &bx, &by);
443 cairo_matrix_transform_point (info->path_transform, &cx, &cy);
444 cairo_matrix_transform_point (info->path_transform, &dx, &dy);
445 _cairo_output_stream_printf (info->output,
446 "%g %g %g %g %g %g c ",
447 bx, by, cx, cy, dx, dy);
448 return _cairo_output_stream_get_status (info->output);
451 static cairo_status_t
452 _cairo_pdf_path_close_path (void *closure)
454 pdf_path_info_t *info = closure;
456 if (info->line_cap != CAIRO_LINE_CAP_ROUND &&
457 ! info->has_sub_path)
459 return CAIRO_STATUS_SUCCESS;
462 _cairo_output_stream_printf (info->output,
465 return _cairo_output_stream_get_status (info->output);
468 static cairo_status_t
469 _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
471 double x1 = _cairo_fixed_to_double (box->p1.x);
472 double y1 = _cairo_fixed_to_double (box->p1.y);
473 double x2 = _cairo_fixed_to_double (box->p2.x);
474 double y2 = _cairo_fixed_to_double (box->p2.y);
476 cairo_matrix_transform_point (info->path_transform, &x1, &y1);
477 cairo_matrix_transform_point (info->path_transform, &x2, &y2);
478 _cairo_output_stream_printf (info->output,
480 x1, y1, x2 - x1, y2 - y1);
482 return _cairo_output_stream_get_status (info->output);
485 /* The line cap value is needed to workaround the fact that PostScript
486 * and PDF semantics for stroking degenerate sub-paths do not match
487 * cairo semantics. (PostScript draws something for any line cap
488 * value, while cairo draws something only for round caps).
490 * When using this function to emit a path to be filled, rather than
491 * stroked, simply pass %CAIRO_LINE_CAP_ROUND which will guarantee that
492 * the stroke workaround will not modify the path being emitted.
494 static cairo_status_t
495 _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators,
496 const cairo_path_fixed_t*path,
497 cairo_matrix_t *path_transform,
498 cairo_line_cap_t line_cap)
500 cairo_output_stream_t *word_wrap;
501 cairo_status_t status, status2;
502 pdf_path_info_t info;
505 word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
506 status = _cairo_output_stream_get_status (word_wrap);
507 if (unlikely (status))
508 return _cairo_output_stream_destroy (word_wrap);
510 info.output = word_wrap;
511 info.path_transform = path_transform;
512 info.line_cap = line_cap;
513 if (_cairo_path_fixed_is_rectangle (path, &box)) {
514 status = _cairo_pdf_path_rectangle (&info, &box);
516 status = _cairo_path_fixed_interpret (path,
517 _cairo_pdf_path_move_to,
518 _cairo_pdf_path_line_to,
519 _cairo_pdf_path_curve_to,
520 _cairo_pdf_path_close_path,
524 status2 = _cairo_output_stream_destroy (word_wrap);
525 if (status == CAIRO_STATUS_SUCCESS)
532 _cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators,
533 const cairo_path_fixed_t *path,
534 cairo_fill_rule_t fill_rule)
536 const char *pdf_operator;
537 cairo_status_t status;
539 if (pdf_operators->in_text_object) {
540 status = _cairo_pdf_operators_end_text (pdf_operators);
541 if (unlikely (status))
545 if (! path->has_current_point) {
546 /* construct an empty path */
547 _cairo_output_stream_printf (pdf_operators->stream, "0 0 m ");
549 status = _cairo_pdf_operators_emit_path (pdf_operators,
551 &pdf_operators->cairo_to_pdf,
552 CAIRO_LINE_CAP_ROUND);
553 if (unlikely (status))
560 case CAIRO_FILL_RULE_WINDING:
563 case CAIRO_FILL_RULE_EVEN_ODD:
568 _cairo_output_stream_printf (pdf_operators->stream,
572 return _cairo_output_stream_get_status (pdf_operators->stream);
576 _cairo_pdf_line_cap (cairo_line_cap_t cap)
579 case CAIRO_LINE_CAP_BUTT:
581 case CAIRO_LINE_CAP_ROUND:
583 case CAIRO_LINE_CAP_SQUARE:
592 _cairo_pdf_line_join (cairo_line_join_t join)
595 case CAIRO_LINE_JOIN_MITER:
597 case CAIRO_LINE_JOIN_ROUND:
599 case CAIRO_LINE_JOIN_BEVEL:
608 _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators,
609 const cairo_stroke_style_t *style,
612 double *dash = style->dash;
613 int num_dashes = style->num_dashes;
614 double dash_offset = style->dash_offset;
615 double line_width = style->line_width * scale;
617 /* PostScript has "special needs" when it comes to zero-length
618 * dash segments with butt caps. It apparently (at least
619 * according to ghostscript) draws hairlines for this
620 * case. That's not what the cairo semantics want, so we first
621 * touch up the array to eliminate any 0.0 values that will
622 * result in "on" segments.
624 if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
627 /* If there's an odd number of dash values they will each get
628 * interpreted as both on and off. So we first explicitly
629 * expand the array to remove the duplicate usage so that we
630 * can modify some of the values.
632 if (num_dashes % 2) {
633 dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
634 if (unlikely (dash == NULL))
635 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
637 memcpy (dash, style->dash, num_dashes * sizeof (double));
638 memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
643 for (i = 0; i < num_dashes; i += 2) {
644 if (dash[i] == 0.0) {
645 /* Do not modify the dashes in-place, as we may need to also
646 * replay this stroke to an image fallback.
648 if (dash == style->dash) {
649 dash = _cairo_malloc_ab (num_dashes, sizeof (double));
650 if (unlikely (dash == NULL))
651 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
652 memcpy (dash, style->dash, num_dashes * sizeof (double));
655 /* If we're at the front of the list, we first rotate
656 * two elements from the end of the list to the front
657 * of the list before folding away the 0.0. Or, if
658 * there are only two dash elements, then there is
659 * nothing at all to draw.
664 if (num_dashes == 2) {
666 return CAIRO_INT_STATUS_NOTHING_TO_DO;
669 /* The cases of num_dashes == 0, 1, or 3 elements
670 * cannot exist, so the rotation of 2 elements
671 * will always be safe */
672 memcpy (last_two, dash + num_dashes - 2, sizeof (last_two));
673 memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double));
674 memcpy (dash, last_two, sizeof (last_two));
675 dash_offset += dash[0] + dash[1];
678 dash[i-1] += dash[i+1];
680 memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double));
681 /* If we might have just rotated, it's possible that
682 * we rotated a 0.0 value to the front of the list.
683 * Set i to -2 so it will get incremented to 0. */
690 if (!pdf_operators->has_line_style || pdf_operators->line_width != line_width) {
691 _cairo_output_stream_printf (pdf_operators->stream,
694 pdf_operators->line_width = line_width;
697 if (!pdf_operators->has_line_style || pdf_operators->line_cap != style->line_cap) {
698 _cairo_output_stream_printf (pdf_operators->stream,
700 _cairo_pdf_line_cap (style->line_cap));
701 pdf_operators->line_cap = style->line_cap;
704 if (!pdf_operators->has_line_style || pdf_operators->line_join != style->line_join) {
705 _cairo_output_stream_printf (pdf_operators->stream,
707 _cairo_pdf_line_join (style->line_join));
708 pdf_operators->line_join = style->line_join;
714 _cairo_output_stream_printf (pdf_operators->stream, "[");
715 for (d = 0; d < num_dashes; d++)
716 _cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale);
717 _cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
718 dash_offset * scale);
719 pdf_operators->has_dashes = TRUE;
720 } else if (!pdf_operators->has_line_style || pdf_operators->has_dashes) {
721 _cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
722 pdf_operators->has_dashes = FALSE;
724 if (dash != style->dash)
727 if (!pdf_operators->has_line_style || pdf_operators->miter_limit != style->miter_limit) {
728 _cairo_output_stream_printf (pdf_operators->stream,
730 style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
731 pdf_operators->miter_limit = style->miter_limit;
733 pdf_operators->has_line_style = TRUE;
735 return _cairo_output_stream_get_status (pdf_operators->stream);
738 /* Scale the matrix so the largest absolute value of the non
739 * translation components is 1.0. Return the scale required to restore
740 * the matrix to the original values.
742 * eg the matrix [ 100 0 0 50 20 10 ]
744 * is rescaled to [ 1 0 0 0.5 0.2 0.1 ]
745 * and the scale returned is 100
748 _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
753 if (fabs (m->xy) > s)
755 if (fabs (m->yx) > s)
757 if (fabs (m->yy) > s)
761 cairo_matrix_scale (m, s, s);
764 static cairo_int_status_t
765 _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators,
766 const cairo_path_fixed_t *path,
767 const cairo_stroke_style_t *style,
768 const cairo_matrix_t *ctm,
769 const cairo_matrix_t *ctm_inverse,
770 const char *pdf_operator)
772 cairo_int_status_t status;
773 cairo_matrix_t m, path_transform;
774 cairo_bool_t has_ctm = TRUE;
777 if (pdf_operators->in_text_object) {
778 status = _cairo_pdf_operators_end_text (pdf_operators);
779 if (unlikely (status))
783 /* Optimize away the stroke ctm when it does not affect the
784 * stroke. There are other ctm cases that could be optimized
785 * however this is the most common.
787 if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 &&
788 fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0)
793 /* The PDF CTM is transformed to the user space CTM when stroking
794 * so the corect pen shape will be used. This also requires that
795 * the path be transformed to user space when emitted. The
796 * conversion of path coordinates to user space may cause rounding
797 * errors. For example the device space point (1.234, 3.142) when
798 * transformed to a user space CTM of [100 0 0 100 0 0] will be
799 * emitted as (0.012, 0.031).
801 * To avoid the rounding problem we scale the user space CTM
802 * matrix so that all the non translation components of the matrix
803 * are <= 1. The line width and and dashes are scaled by the
804 * inverse of the scale applied to the CTM. This maintains the
805 * shape of the stroke pen while keeping the user space CTM within
806 * the range that maximizes the precision of the emitted path.
810 /* Zero out the translation since it does not affect the pen
811 * shape however it may cause unnecessary digits to be emitted.
815 _cairo_matrix_factor_out_scale (&m, &scale);
817 status = cairo_matrix_invert (&path_transform);
818 if (unlikely (status))
821 cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
824 status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale);
825 if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
826 return CAIRO_STATUS_SUCCESS;
827 if (unlikely (status))
831 _cairo_output_stream_printf (pdf_operators->stream,
832 "q %f %f %f %f %f %f cm\n",
833 m.xx, m.yx, m.xy, m.yy,
836 path_transform = pdf_operators->cairo_to_pdf;
839 status = _cairo_pdf_operators_emit_path (pdf_operators,
843 if (unlikely (status))
846 _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
848 _cairo_output_stream_printf (pdf_operators->stream, " Q");
850 _cairo_output_stream_printf (pdf_operators->stream, "\n");
852 return _cairo_output_stream_get_status (pdf_operators->stream);
856 _cairo_pdf_operators_stroke (cairo_pdf_operators_t *pdf_operators,
857 const cairo_path_fixed_t *path,
858 const cairo_stroke_style_t *style,
859 const cairo_matrix_t *ctm,
860 const cairo_matrix_t *ctm_inverse)
862 return _cairo_pdf_operators_emit_stroke (pdf_operators,
871 _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators,
872 const cairo_path_fixed_t *path,
873 cairo_fill_rule_t fill_rule)
875 const char *pdf_operator;
876 cairo_status_t status;
878 if (pdf_operators->in_text_object) {
879 status = _cairo_pdf_operators_end_text (pdf_operators);
880 if (unlikely (status))
884 status = _cairo_pdf_operators_emit_path (pdf_operators,
886 &pdf_operators->cairo_to_pdf,
887 CAIRO_LINE_CAP_ROUND);
888 if (unlikely (status))
894 case CAIRO_FILL_RULE_WINDING:
897 case CAIRO_FILL_RULE_EVEN_ODD:
902 _cairo_output_stream_printf (pdf_operators->stream,
906 return _cairo_output_stream_get_status (pdf_operators->stream);
910 _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t *pdf_operators,
911 const cairo_path_fixed_t *path,
912 cairo_fill_rule_t fill_rule,
913 const cairo_stroke_style_t *style,
914 const cairo_matrix_t *ctm,
915 const cairo_matrix_t *ctm_inverse)
917 const char *operator;
922 case CAIRO_FILL_RULE_WINDING:
925 case CAIRO_FILL_RULE_EVEN_ODD:
930 return _cairo_pdf_operators_emit_stroke (pdf_operators,
939 _cairo_pdf_operators_emit_glyph_index (cairo_pdf_operators_t *pdf_operators,
940 cairo_output_stream_t *stream,
943 if (pdf_operators->is_latin) {
944 if (glyph == '(' || glyph == ')' || glyph == '\\')
945 _cairo_output_stream_printf (stream, "\\%c", glyph);
946 else if (glyph >= 0x20 && glyph <= 0x7e)
947 _cairo_output_stream_printf (stream, "%c", glyph);
949 _cairo_output_stream_printf (stream, "\\%03o", glyph);
951 _cairo_output_stream_printf (stream,
953 pdf_operators->hex_width,
958 #define GLYPH_POSITION_TOLERANCE 0.001
960 /* Emit the string of glyphs using the 'Tj' operator. This requires
961 * that the glyphs are positioned at their natural glyph advances. */
962 static cairo_status_t
963 _cairo_pdf_operators_emit_glyph_string (cairo_pdf_operators_t *pdf_operators,
964 cairo_output_stream_t *stream)
968 _cairo_output_stream_printf (stream, "%s", pdf_operators->is_latin ? "(" : "<");
969 for (i = 0; i < pdf_operators->num_glyphs; i++) {
970 _cairo_pdf_operators_emit_glyph_index (pdf_operators,
972 pdf_operators->glyphs[i].glyph_index);
973 pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
975 _cairo_output_stream_printf (stream, "%sTj\n", pdf_operators->is_latin ? ")" : ">");
977 return _cairo_output_stream_get_status (stream);
980 /* Emit the string of glyphs using the 'TJ' operator.
982 * The TJ operator takes an array of strings of glyphs. Each string of
983 * glyphs is displayed using the glyph advances of each glyph to
984 * position the glyphs. A relative adjustment to the glyph advance may
985 * be specified by including the adjustment between two strings. The
986 * adjustment is in units of text space * -1000.
988 static cairo_status_t
989 _cairo_pdf_operators_emit_glyph_string_with_positioning (
990 cairo_pdf_operators_t *pdf_operators,
991 cairo_output_stream_t *stream)
995 _cairo_output_stream_printf (stream, "[%s", pdf_operators->is_latin ? "(" : "<");
996 for (i = 0; i < pdf_operators->num_glyphs; i++) {
997 if (pdf_operators->glyphs[i].x_position != pdf_operators->cur_x)
999 double delta = pdf_operators->glyphs[i].x_position - pdf_operators->cur_x;
1002 delta = -1000.0*delta;
1003 /* As the delta is in 1/1000 of a unit of text space,
1004 * rounding to an integer should still provide sufficient
1005 * precision. We round the delta before adding to Tm_x so
1006 * that we keep track of the accumulated rounding error in
1007 * the PDF interpreter and compensate for it when
1008 * calculating subsequent deltas.
1010 rounded_delta = _cairo_lround (delta);
1011 if (abs(rounded_delta) < 3)
1013 if (rounded_delta != 0) {
1014 if (pdf_operators->is_latin) {
1015 _cairo_output_stream_printf (stream,
1019 _cairo_output_stream_printf (stream,
1025 /* Convert the rounded delta back to text
1026 * space before adding to the current text
1028 delta = rounded_delta/-1000.0;
1029 pdf_operators->cur_x += delta;
1032 _cairo_pdf_operators_emit_glyph_index (pdf_operators,
1034 pdf_operators->glyphs[i].glyph_index);
1035 pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
1037 _cairo_output_stream_printf (stream, "%s]TJ\n", pdf_operators->is_latin ? ")" : ">");
1039 return _cairo_output_stream_get_status (stream);
1042 static cairo_status_t
1043 _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators)
1045 cairo_output_stream_t *word_wrap_stream;
1046 cairo_status_t status, status2;
1050 if (pdf_operators->num_glyphs == 0)
1051 return CAIRO_STATUS_SUCCESS;
1053 word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
1054 status = _cairo_output_stream_get_status (word_wrap_stream);
1055 if (unlikely (status))
1056 return _cairo_output_stream_destroy (word_wrap_stream);
1058 /* Check if glyph advance used to position every glyph */
1059 x = pdf_operators->cur_x;
1060 for (i = 0; i < pdf_operators->num_glyphs; i++) {
1061 if (fabs(pdf_operators->glyphs[i].x_position - x) > GLYPH_POSITION_TOLERANCE)
1063 x += pdf_operators->glyphs[i].x_advance;
1065 if (i == pdf_operators->num_glyphs) {
1066 status = _cairo_pdf_operators_emit_glyph_string (pdf_operators,
1069 status = _cairo_pdf_operators_emit_glyph_string_with_positioning (
1070 pdf_operators, word_wrap_stream);
1073 pdf_operators->num_glyphs = 0;
1074 pdf_operators->glyph_buf_x_pos = pdf_operators->cur_x;
1075 status2 = _cairo_output_stream_destroy (word_wrap_stream);
1076 if (status == CAIRO_STATUS_SUCCESS)
1082 static cairo_status_t
1083 _cairo_pdf_operators_add_glyph (cairo_pdf_operators_t *pdf_operators,
1084 cairo_scaled_font_subsets_glyph_t *glyph,
1089 x = glyph->x_advance;
1090 y = glyph->y_advance;
1091 if (glyph->is_scaled)
1092 cairo_matrix_transform_distance (&pdf_operators->font_matrix_inverse, &x, &y);
1094 pdf_operators->glyphs[pdf_operators->num_glyphs].x_position = x_position;
1095 pdf_operators->glyphs[pdf_operators->num_glyphs].glyph_index = glyph->subset_glyph_index;
1096 pdf_operators->glyphs[pdf_operators->num_glyphs].x_advance = x;
1097 pdf_operators->glyph_buf_x_pos += x;
1098 pdf_operators->num_glyphs++;
1099 if (pdf_operators->num_glyphs == PDF_GLYPH_BUFFER_SIZE)
1100 return _cairo_pdf_operators_flush_glyphs (pdf_operators);
1102 return CAIRO_STATUS_SUCCESS;
1105 /* Use 'Tm' operator to set the PDF text matrix. */
1106 static cairo_status_t
1107 _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators,
1108 cairo_matrix_t *matrix)
1110 cairo_matrix_t inverse;
1111 cairo_status_t status;
1113 /* We require the matrix to be invertable. */
1115 status = cairo_matrix_invert (&inverse);
1116 if (unlikely (status))
1119 pdf_operators->text_matrix = *matrix;
1120 pdf_operators->cur_x = 0;
1121 pdf_operators->cur_y = 0;
1122 pdf_operators->glyph_buf_x_pos = 0;
1123 _cairo_output_stream_printf (pdf_operators->stream,
1124 "%f %f %f %f %f %f Tm\n",
1125 pdf_operators->text_matrix.xx,
1126 pdf_operators->text_matrix.yx,
1127 pdf_operators->text_matrix.xy,
1128 pdf_operators->text_matrix.yy,
1129 pdf_operators->text_matrix.x0,
1130 pdf_operators->text_matrix.y0);
1132 pdf_operators->cairo_to_pdftext = *matrix;
1133 status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
1134 assert (status == CAIRO_STATUS_SUCCESS);
1135 cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext,
1136 &pdf_operators->cairo_to_pdf,
1137 &pdf_operators->cairo_to_pdftext);
1139 return _cairo_output_stream_get_status (pdf_operators->stream);
1142 #define TEXT_MATRIX_TOLERANCE 1e-6
1144 /* Set the translation components of the PDF text matrix to x, y. The
1145 * 'Td' operator is used to transform the text matrix.
1147 static cairo_status_t
1148 _cairo_pdf_operators_set_text_position (cairo_pdf_operators_t *pdf_operators,
1152 cairo_matrix_t translate, inverse;
1153 cairo_status_t status;
1155 /* The Td operator transforms the text_matrix with:
1157 * text_matrix' = T x text_matrix
1159 * where T is a translation matrix with the translation components
1160 * set to the Td operands tx and ty.
1162 inverse = pdf_operators->text_matrix;
1163 status = cairo_matrix_invert (&inverse);
1164 assert (status == CAIRO_STATUS_SUCCESS);
1165 pdf_operators->text_matrix.x0 = x;
1166 pdf_operators->text_matrix.y0 = y;
1167 cairo_matrix_multiply (&translate, &pdf_operators->text_matrix, &inverse);
1168 if (fabs(translate.x0) < TEXT_MATRIX_TOLERANCE)
1170 if (fabs(translate.y0) < TEXT_MATRIX_TOLERANCE)
1172 _cairo_output_stream_printf (pdf_operators->stream,
1176 pdf_operators->cur_x = 0;
1177 pdf_operators->cur_y = 0;
1178 pdf_operators->glyph_buf_x_pos = 0;
1180 pdf_operators->cairo_to_pdftext = pdf_operators->text_matrix;
1181 status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
1182 assert (status == CAIRO_STATUS_SUCCESS);
1183 cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext,
1184 &pdf_operators->cairo_to_pdf,
1185 &pdf_operators->cairo_to_pdftext);
1187 return _cairo_output_stream_get_status (pdf_operators->stream);
1190 /* Select the font using the 'Tf' operator. The font size is set to 1
1191 * as we use the 'Tm' operator to set the font scale.
1193 static cairo_status_t
1194 _cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t *pdf_operators,
1195 cairo_scaled_font_subsets_glyph_t *subset_glyph)
1197 cairo_status_t status;
1199 _cairo_output_stream_printf (pdf_operators->stream,
1201 subset_glyph->font_id,
1202 subset_glyph->subset_id);
1203 if (pdf_operators->use_font_subset) {
1204 status = pdf_operators->use_font_subset (subset_glyph->font_id,
1205 subset_glyph->subset_id,
1206 pdf_operators->use_font_subset_closure);
1207 if (unlikely (status))
1210 pdf_operators->font_id = subset_glyph->font_id;
1211 pdf_operators->subset_id = subset_glyph->subset_id;
1212 pdf_operators->is_latin = subset_glyph->is_latin;
1214 if (subset_glyph->is_composite)
1215 pdf_operators->hex_width = 4;
1217 pdf_operators->hex_width = 2;
1219 return CAIRO_STATUS_SUCCESS;
1222 static cairo_status_t
1223 _cairo_pdf_operators_begin_text (cairo_pdf_operators_t *pdf_operators)
1225 _cairo_output_stream_printf (pdf_operators->stream, "BT\n");
1227 pdf_operators->in_text_object = TRUE;
1228 pdf_operators->num_glyphs = 0;
1229 pdf_operators->glyph_buf_x_pos = 0;
1231 return _cairo_output_stream_get_status (pdf_operators->stream);
1234 static cairo_status_t
1235 _cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators)
1237 cairo_status_t status;
1239 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1240 if (unlikely (status))
1243 _cairo_output_stream_printf (pdf_operators->stream, "ET\n");
1245 pdf_operators->in_text_object = FALSE;
1247 return _cairo_output_stream_get_status (pdf_operators->stream);
1250 /* Compare the scale components of two matrices. The translation
1251 * components are ignored. */
1253 _cairo_matrix_scale_equal (cairo_matrix_t *a, cairo_matrix_t *b)
1255 return (a->xx == b->xx &&
1261 static cairo_status_t
1262 _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators,
1268 cairo_status_t status;
1271 _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff");
1273 status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len);
1274 if (unlikely (status))
1277 for (i = 0; i < utf16_len; i++) {
1278 _cairo_output_stream_printf (pdf_operators->stream,
1279 "%04x", (int) (utf16[i]));
1283 _cairo_output_stream_printf (pdf_operators->stream, "> >> BDC\n");
1285 return _cairo_output_stream_get_status (pdf_operators->stream);
1288 static cairo_status_t
1289 _cairo_pdf_operators_end_actualtext (cairo_pdf_operators_t *pdf_operators)
1291 _cairo_output_stream_printf (pdf_operators->stream, "EMC\n");
1293 return _cairo_output_stream_get_status (pdf_operators->stream);
1296 static cairo_status_t
1297 _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operators,
1298 cairo_glyph_t *glyph,
1299 cairo_scaled_font_subsets_glyph_t *subset_glyph)
1302 cairo_status_t status;
1304 if (pdf_operators->is_new_text_object ||
1305 pdf_operators->font_id != subset_glyph->font_id ||
1306 pdf_operators->subset_id != subset_glyph->subset_id)
1308 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1309 if (unlikely (status))
1312 status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph);
1313 if (unlikely (status))
1316 pdf_operators->is_new_text_object = FALSE;
1321 cairo_matrix_transform_point (&pdf_operators->cairo_to_pdftext, &x, &y);
1323 /* The TJ operator for displaying text strings can only set
1324 * the horizontal position of the glyphs. If the y position
1325 * (in text space) changes, use the Td operator to change the
1326 * current position to the next glyph. We also use the Td
1327 * operator to move the current position if the horizontal
1328 * position changes by more than 10 (in text space
1329 * units). This is becauses the horizontal glyph positioning
1330 * in the TJ operator is intended for kerning and there may be
1331 * PDF consumers that do not handle very large position
1332 * adjustments in TJ.
1334 if (fabs(x - pdf_operators->glyph_buf_x_pos) > 10 ||
1335 fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE)
1337 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1338 if (unlikely (status))
1343 cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
1344 status = _cairo_pdf_operators_set_text_position (pdf_operators, x, y);
1345 if (unlikely (status))
1352 status = _cairo_pdf_operators_add_glyph (pdf_operators,
1358 /* A utf8_len of -1 indicates no unicode text. A utf8_len = 0 is an
1361 static cairo_int_status_t
1362 _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators,
1365 cairo_glyph_t *glyphs,
1367 cairo_text_cluster_flags_t cluster_flags,
1368 cairo_scaled_font_t *scaled_font)
1370 cairo_scaled_font_subsets_glyph_t subset_glyph;
1371 cairo_glyph_t *cur_glyph;
1372 cairo_status_t status = CAIRO_STATUS_SUCCESS;
1375 /* If the cluster maps 1 glyph to 1 or more unicode characters, we
1376 * first try _map_glyph() with the unicode string to see if it can
1377 * use toUnicode to map our glyph to the unicode. This will fail
1378 * if the glyph is already mapped to a different unicode string.
1380 * We also go through this path if no unicode mapping was
1381 * supplied (utf8_len < 0).
1383 * Mapping a glyph to a zero length unicode string requires the
1384 * use of ActualText.
1386 if (num_glyphs == 1 && utf8_len != 0) {
1387 status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
1393 if (unlikely (status))
1396 if (subset_glyph.utf8_is_mapped || utf8_len < 0) {
1397 status = _cairo_pdf_operators_emit_glyph (pdf_operators,
1400 if (unlikely (status))
1403 return CAIRO_STATUS_SUCCESS;
1407 if (pdf_operators->use_actual_text) {
1408 /* Fallback to using ActualText to map zero or more glyphs to a
1409 * unicode string. */
1410 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1411 if (unlikely (status))
1414 status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len);
1415 if (unlikely (status))
1421 * If no glyphs, we should put *something* here for the text to be selectable. */
1422 for (i = 0; i < num_glyphs; i++) {
1423 status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
1428 if (unlikely (status))
1431 status = _cairo_pdf_operators_emit_glyph (pdf_operators,
1434 if (unlikely (status))
1437 if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
1443 if (pdf_operators->use_actual_text) {
1444 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1445 if (unlikely (status))
1448 status = _cairo_pdf_operators_end_actualtext (pdf_operators);
1455 _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators,
1458 cairo_glyph_t *glyphs,
1460 const cairo_text_cluster_t *clusters,
1462 cairo_text_cluster_flags_t cluster_flags,
1463 cairo_scaled_font_t *scaled_font)
1465 cairo_status_t status;
1467 cairo_matrix_t text_matrix, invert_y_axis;
1469 const char *cur_text;
1470 cairo_glyph_t *cur_glyph;
1472 pdf_operators->font_matrix_inverse = scaled_font->font_matrix;
1473 status = cairo_matrix_invert (&pdf_operators->font_matrix_inverse);
1474 if (status == CAIRO_STATUS_INVALID_MATRIX)
1475 return CAIRO_STATUS_SUCCESS;
1476 assert (status == CAIRO_STATUS_SUCCESS);
1478 pdf_operators->is_new_text_object = FALSE;
1479 if (pdf_operators->in_text_object == FALSE) {
1480 status = _cairo_pdf_operators_begin_text (pdf_operators);
1481 if (unlikely (status))
1484 /* Force Tm and Tf to be emitted when starting a new text
1486 pdf_operators->is_new_text_object = TRUE;
1489 cairo_matrix_init_scale (&invert_y_axis, 1, -1);
1490 text_matrix = scaled_font->scale;
1492 /* Invert y axis in font space */
1493 cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis);
1495 /* Invert y axis in device space */
1496 cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix);
1498 if (pdf_operators->is_new_text_object ||
1499 ! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix))
1501 status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
1502 if (unlikely (status))
1507 cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
1510 status = _cairo_pdf_operators_set_text_matrix (pdf_operators, &text_matrix);
1511 if (status == CAIRO_STATUS_INVALID_MATRIX)
1512 return CAIRO_STATUS_SUCCESS;
1513 if (unlikely (status))
1517 if (num_clusters > 0) {
1519 if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
1520 cur_glyph = glyphs + num_glyphs;
1523 for (i = 0; i < num_clusters; i++) {
1524 if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
1525 cur_glyph -= clusters[i].num_glyphs;
1526 status = _cairo_pdf_operators_emit_cluster (pdf_operators,
1528 clusters[i].num_bytes,
1530 clusters[i].num_glyphs,
1533 if (unlikely (status))
1536 cur_text += clusters[i].num_bytes;
1537 if (!(cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
1538 cur_glyph += clusters[i].num_glyphs;
1541 for (i = 0; i < num_glyphs; i++) {
1542 status = _cairo_pdf_operators_emit_cluster (pdf_operators,
1544 -1, /* no unicode string available */
1549 if (unlikely (status))
1554 return _cairo_output_stream_get_status (pdf_operators->stream);
1557 #endif /* CAIRO_HAS_PDF_OPERATORS */