Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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
  3.  *
  4.  * Copyright © 2004 Red Hat, Inc
  5.  * Copyright © 2006 Red Hat, Inc
  6.  * Copyright © 2007, 2008 Adrian Johnson
  7.  *
  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.
  15.  *
  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
  21.  *
  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/
  26.  *
  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.
  30.  *
  31.  * The Original Code is the cairo graphics library.
  32.  *
  33.  * The Initial Developer of the Original Code is University of Southern
  34.  * California.
  35.  *
  36.  * Contributor(s):
  37.  *      Kristian Høgsberg <krh@redhat.com>
  38.  *      Carl Worth <cworth@cworth.org>
  39.  *      Adrian Johnson <ajohnson@redneon.com>
  40.  */
  41.  
  42. #include "cairoint.h"
  43.  
  44. #if CAIRO_HAS_PDF_OPERATORS
  45.  
  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"
  51.  
  52. static cairo_status_t
  53. _cairo_pdf_operators_end_text (cairo_pdf_operators_t    *pdf_operators);
  54.  
  55.  
  56. void
  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)
  61. {
  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;
  71. }
  72.  
  73. cairo_status_t
  74. _cairo_pdf_operators_fini (cairo_pdf_operators_t        *pdf_operators)
  75. {
  76.     return _cairo_pdf_operators_flush (pdf_operators);
  77. }
  78.  
  79. void
  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,
  82.                                                 void                                 *closure)
  83. {
  84.     pdf_operators->use_font_subset = use_font_subset;
  85.     pdf_operators->use_font_subset_closure = closure;
  86. }
  87.  
  88. /* Change the output stream to a different stream.
  89.  * _cairo_pdf_operators_flush() should always be called before calling
  90.  * this function.
  91.  */
  92. void
  93. _cairo_pdf_operators_set_stream (cairo_pdf_operators_t   *pdf_operators,
  94.                                  cairo_output_stream_t   *stream)
  95. {
  96.     pdf_operators->stream = stream;
  97.     pdf_operators->has_line_style = FALSE;
  98. }
  99.  
  100. void
  101. _cairo_pdf_operators_set_cairo_to_pdf_matrix (cairo_pdf_operators_t *pdf_operators,
  102.                                               cairo_matrix_t        *cairo_to_pdf)
  103. {
  104.     pdf_operators->cairo_to_pdf = *cairo_to_pdf;
  105.     pdf_operators->has_line_style = FALSE;
  106. }
  107.  
  108. cairo_private void
  109. _cairo_pdf_operators_enable_actual_text (cairo_pdf_operators_t *pdf_operators,
  110.                                          cairo_bool_t           enable)
  111. {
  112.     pdf_operators->use_actual_text = enable;
  113. }
  114.  
  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.
  118.  *
  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).
  124.  *
  125.  */
  126. cairo_status_t
  127. _cairo_pdf_operators_flush (cairo_pdf_operators_t        *pdf_operators)
  128. {
  129.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  130.  
  131.     if (pdf_operators->in_text_object)
  132.         status = _cairo_pdf_operators_end_text (pdf_operators);
  133.  
  134.     return status;
  135. }
  136.  
  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
  141.  * operatations.
  142.  *
  143.  * This should be called when starting a new stream or after emitting
  144.  * the 'Q' operator (where pdf-operators functions were called inside
  145.  * the q/Q pair).
  146.  */
  147. void
  148. _cairo_pdf_operators_reset (cairo_pdf_operators_t *pdf_operators)
  149. {
  150.     pdf_operators->has_line_style = FALSE;
  151. }
  152.  
  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.
  158.  *
  159.  * The stream is careful to maintain integrity for words that cross
  160.  * the boundary from one call to write to the next.
  161.  *
  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.
  165.  */
  166.  
  167. typedef enum _cairo_word_wrap_state {
  168.     WRAP_STATE_DELIMITER,
  169.     WRAP_STATE_WORD,
  170.     WRAP_STATE_STRING,
  171.     WRAP_STATE_HEXSTRING
  172. } cairo_word_wrap_state_t;
  173.  
  174.  
  175. typedef struct _word_wrap_stream {
  176.     cairo_output_stream_t base;
  177.     cairo_output_stream_t *output;
  178.     int max_column;
  179.     int column;
  180.     cairo_word_wrap_state_t state;
  181.     cairo_bool_t in_escape;
  182.     int          escape_digits;
  183. } word_wrap_stream_t;
  184.  
  185.  
  186.  
  187. /* Emit word bytes up to the next delimiter character */
  188. static int
  189. _word_wrap_stream_count_word_up_to (word_wrap_stream_t *stream,
  190.                                    const unsigned char *data, int length)
  191. {
  192.     const unsigned char *s = data;
  193.     int count = 0;
  194.  
  195.     while (length--) {
  196.         if (_cairo_isspace (*s) || *s == '<' || *s == '(') {
  197.             stream->state = WRAP_STATE_DELIMITER;
  198.             break;
  199.         }
  200.  
  201.         count++;
  202.         stream->column++;
  203.         s++;
  204.     }
  205.  
  206.     if (count)
  207.         _cairo_output_stream_write (stream->output, data, count);
  208.  
  209.     return count;
  210. }
  211.  
  212.  
  213. /* Emit hexstring bytes up to either the end of the ASCII hexstring or the number
  214.  * of columns remaining.
  215.  */
  216. static int
  217. _word_wrap_stream_count_hexstring_up_to (word_wrap_stream_t *stream,
  218.                                          const unsigned char *data, int length)
  219. {
  220.     const unsigned char *s = data;
  221.     int count = 0;
  222.     cairo_bool_t newline = FALSE;
  223.  
  224.     while (length--) {
  225.         count++;
  226.         stream->column++;
  227.         if (*s == '>') {
  228.             stream->state = WRAP_STATE_DELIMITER;
  229.             break;
  230.         }
  231.  
  232.         if (stream->column > stream->max_column) {
  233.             newline = TRUE;
  234.             break;
  235.         }
  236.         s++;
  237.     }
  238.  
  239.     if (count)
  240.         _cairo_output_stream_write (stream->output, data, count);
  241.  
  242.     if (newline) {
  243.         _cairo_output_stream_printf (stream->output, "\n");
  244.         stream->column = 0;
  245.     }
  246.  
  247.     return count;
  248. }
  249.  
  250. /* Count up to either the end of the string or the number of columns
  251.  * remaining.
  252.  */
  253. static int
  254. _word_wrap_stream_count_string_up_to (word_wrap_stream_t *stream,
  255.                                       const unsigned char *data, int length)
  256. {
  257.     const unsigned char *s = data;
  258.     int count = 0;
  259.     cairo_bool_t newline = FALSE;
  260.  
  261.     while (length--) {
  262.         count++;
  263.         stream->column++;
  264.         if (!stream->in_escape) {
  265.             if (*s == ')') {
  266.                 stream->state = WRAP_STATE_DELIMITER;
  267.                 break;
  268.             }
  269.             if (*s == '\\') {
  270.                 stream->in_escape = TRUE;
  271.                 stream->escape_digits = 0;
  272.             } else if (stream->column > stream->max_column) {
  273.                 newline = TRUE;
  274.                 break;
  275.             }
  276.         } else {
  277.             if (!_cairo_isdigit(*s) || ++stream->escape_digits == 3)
  278.                 stream->in_escape = FALSE;
  279.         }
  280.         s++;
  281.     }
  282.  
  283.     if (count)
  284.         _cairo_output_stream_write (stream->output, data, count);
  285.  
  286.     if (newline) {
  287.         _cairo_output_stream_printf (stream->output, "\\\n");
  288.         stream->column = 0;
  289.     }
  290.  
  291.     return count;
  292. }
  293.  
  294. static cairo_status_t
  295. _word_wrap_stream_write (cairo_output_stream_t  *base,
  296.                          const unsigned char    *data,
  297.                          unsigned int            length)
  298. {
  299.     word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
  300.     int count;
  301.  
  302.     while (length) {
  303.         switch (stream->state) {
  304.         case WRAP_STATE_WORD:
  305.             count = _word_wrap_stream_count_word_up_to (stream, data, length);
  306.             break;
  307.         case WRAP_STATE_HEXSTRING:
  308.             count = _word_wrap_stream_count_hexstring_up_to (stream, data, length);
  309.             break;
  310.         case WRAP_STATE_STRING:
  311.             count = _word_wrap_stream_count_string_up_to (stream, data, length);
  312.             break;
  313.         case WRAP_STATE_DELIMITER:
  314.             count = 1;
  315.             stream->column++;
  316.             if (*data == '\n' || stream->column >= stream->max_column) {
  317.                 _cairo_output_stream_printf (stream->output, "\n");
  318.                 stream->column = 0;
  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;
  325.             }
  326.             if (*data != '\n')
  327.                 _cairo_output_stream_write (stream->output, data, 1);
  328.             break;
  329.  
  330.         default:
  331.             ASSERT_NOT_REACHED;
  332.             count = length;
  333.             break;
  334.         }
  335.         data += count;
  336.         length -= count;
  337.     }
  338.  
  339.     return _cairo_output_stream_get_status (stream->output);
  340. }
  341.  
  342. static cairo_status_t
  343. _word_wrap_stream_close (cairo_output_stream_t *base)
  344. {
  345.     word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
  346.  
  347.     return _cairo_output_stream_get_status (stream->output);
  348. }
  349.  
  350. static cairo_output_stream_t *
  351. _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
  352. {
  353.     word_wrap_stream_t *stream;
  354.  
  355.     if (output->status)
  356.         return _cairo_output_stream_create_in_error (output->status);
  357.  
  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;
  362.     }
  363.  
  364.     _cairo_output_stream_init (&stream->base,
  365.                                _word_wrap_stream_write,
  366.                                NULL,
  367.                                _word_wrap_stream_close);
  368.     stream->output = output;
  369.     stream->max_column = max_column;
  370.     stream->column = 0;
  371.     stream->state = WRAP_STATE_DELIMITER;
  372.     stream->in_escape = FALSE;
  373.     stream->escape_digits = 0;
  374.  
  375.     return &stream->base;
  376. }
  377.  
  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;
  384. } pdf_path_info_t;
  385.  
  386. static cairo_status_t
  387. _cairo_pdf_path_move_to (void *closure,
  388.                          const cairo_point_t *point)
  389. {
  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);
  393.  
  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,
  398.                                  "%g %g m ", x, y);
  399.  
  400.     return _cairo_output_stream_get_status (info->output);
  401. }
  402.  
  403. static cairo_status_t
  404. _cairo_pdf_path_line_to (void *closure,
  405.                          const cairo_point_t *point)
  406. {
  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);
  410.  
  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)
  415.     {
  416.         return CAIRO_STATUS_SUCCESS;
  417.     }
  418.  
  419.     info->has_sub_path = TRUE;
  420.     cairo_matrix_transform_point (info->path_transform, &x, &y);
  421.     _cairo_output_stream_printf (info->output,
  422.                                  "%g %g l ", x, y);
  423.  
  424.     return _cairo_output_stream_get_status (info->output);
  425. }
  426.  
  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)
  432. {
  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);
  440.  
  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);
  449. }
  450.  
  451. static cairo_status_t
  452. _cairo_pdf_path_close_path (void *closure)
  453. {
  454.     pdf_path_info_t *info = closure;
  455.  
  456.     if (info->line_cap != CAIRO_LINE_CAP_ROUND &&
  457.         ! info->has_sub_path)
  458.     {
  459.         return CAIRO_STATUS_SUCCESS;
  460.     }
  461.  
  462.     _cairo_output_stream_printf (info->output,
  463.                                  "h\n");
  464.  
  465.     return _cairo_output_stream_get_status (info->output);
  466. }
  467.  
  468. static cairo_status_t
  469. _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
  470. {
  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);
  475.  
  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,
  479.                                  "%g %g %g %g re ",
  480.                                  x1, y1, x2 - x1, y2 - y1);
  481.  
  482.     return _cairo_output_stream_get_status (info->output);
  483. }
  484.  
  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).
  489.  *
  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.
  493.  */
  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)
  499. {
  500.     cairo_output_stream_t *word_wrap;
  501.     cairo_status_t status, status2;
  502.     pdf_path_info_t info;
  503.     cairo_box_t box;
  504.  
  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);
  509.  
  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);
  515.     } else {
  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,
  521.                                               &info);
  522.     }
  523.  
  524.     status2 = _cairo_output_stream_destroy (word_wrap);
  525.     if (status == CAIRO_STATUS_SUCCESS)
  526.         status = status2;
  527.  
  528.     return status;
  529. }
  530.  
  531. cairo_int_status_t
  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)
  535. {
  536.     const char *pdf_operator;
  537.     cairo_status_t status;
  538.  
  539.     if (pdf_operators->in_text_object) {
  540.         status = _cairo_pdf_operators_end_text (pdf_operators);
  541.         if (unlikely (status))
  542.             return status;
  543.     }
  544.  
  545.     if (! path->has_current_point) {
  546.         /* construct an empty path */
  547.         _cairo_output_stream_printf (pdf_operators->stream, "0 0 m ");
  548.     } else {
  549.         status = _cairo_pdf_operators_emit_path (pdf_operators,
  550.                                                  path,
  551.                                                  &pdf_operators->cairo_to_pdf,
  552.                                                  CAIRO_LINE_CAP_ROUND);
  553.         if (unlikely (status))
  554.             return status;
  555.     }
  556.  
  557.     switch (fill_rule) {
  558.     default:
  559.         ASSERT_NOT_REACHED;
  560.     case CAIRO_FILL_RULE_WINDING:
  561.         pdf_operator = "W";
  562.         break;
  563.     case CAIRO_FILL_RULE_EVEN_ODD:
  564.         pdf_operator = "W*";
  565.         break;
  566.     }
  567.  
  568.     _cairo_output_stream_printf (pdf_operators->stream,
  569.                                  "%s n\n",
  570.                                  pdf_operator);
  571.  
  572.     return _cairo_output_stream_get_status (pdf_operators->stream);
  573. }
  574.  
  575. static int
  576. _cairo_pdf_line_cap (cairo_line_cap_t cap)
  577. {
  578.     switch (cap) {
  579.     case CAIRO_LINE_CAP_BUTT:
  580.         return 0;
  581.     case CAIRO_LINE_CAP_ROUND:
  582.         return 1;
  583.     case CAIRO_LINE_CAP_SQUARE:
  584.         return 2;
  585.     default:
  586.         ASSERT_NOT_REACHED;
  587.         return 0;
  588.     }
  589. }
  590.  
  591. static int
  592. _cairo_pdf_line_join (cairo_line_join_t join)
  593. {
  594.     switch (join) {
  595.     case CAIRO_LINE_JOIN_MITER:
  596.         return 0;
  597.     case CAIRO_LINE_JOIN_ROUND:
  598.         return 1;
  599.     case CAIRO_LINE_JOIN_BEVEL:
  600.         return 2;
  601.     default:
  602.         ASSERT_NOT_REACHED;
  603.         return 0;
  604.     }
  605. }
  606.  
  607. cairo_int_status_t
  608. _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t           *pdf_operators,
  609.                                         const cairo_stroke_style_t      *style,
  610.                                         double                           scale)
  611. {
  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;
  616.  
  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.
  623.      */
  624.     if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
  625.         int i;
  626.  
  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.
  631.          */
  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);
  636.  
  637.             memcpy (dash, style->dash, num_dashes * sizeof (double));
  638.             memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
  639.  
  640.             num_dashes *= 2;
  641.         }
  642.  
  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.
  647.                  */
  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));
  653.                 }
  654.  
  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.
  660.                  */
  661.                 if (i == 0) {
  662.                     double last_two[2];
  663.  
  664.                     if (num_dashes == 2) {
  665.                         free (dash);
  666.                         return CAIRO_INT_STATUS_NOTHING_TO_DO;
  667.                     }
  668.  
  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];
  676.                     i = 2;
  677.                 }
  678.                 dash[i-1] += dash[i+1];
  679.                 num_dashes -= 2;
  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. */
  684.                 if (i == 2)
  685.                     i = -2;
  686.             }
  687.         }
  688.     }
  689.  
  690.     if (!pdf_operators->has_line_style || pdf_operators->line_width != line_width) {
  691.         _cairo_output_stream_printf (pdf_operators->stream,
  692.                                      "%f w\n",
  693.                                      line_width);
  694.         pdf_operators->line_width = line_width;
  695.     }
  696.  
  697.     if (!pdf_operators->has_line_style || pdf_operators->line_cap != style->line_cap) {
  698.         _cairo_output_stream_printf (pdf_operators->stream,
  699.                                      "%d J\n",
  700.                                      _cairo_pdf_line_cap (style->line_cap));
  701.         pdf_operators->line_cap = style->line_cap;
  702.     }
  703.  
  704.     if (!pdf_operators->has_line_style || pdf_operators->line_join != style->line_join) {
  705.         _cairo_output_stream_printf (pdf_operators->stream,
  706.                                      "%d j\n",
  707.                                      _cairo_pdf_line_join (style->line_join));
  708.         pdf_operators->line_join = style->line_join;
  709.     }
  710.  
  711.     if (num_dashes) {
  712.         int d;
  713.  
  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;
  723.     }
  724.     if (dash != style->dash)
  725.         free (dash);
  726.  
  727.     if (!pdf_operators->has_line_style || pdf_operators->miter_limit != style->miter_limit) {
  728.         _cairo_output_stream_printf (pdf_operators->stream,
  729.                                      "%f M ",
  730.                                      style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
  731.         pdf_operators->miter_limit = style->miter_limit;
  732.     }
  733.     pdf_operators->has_line_style = TRUE;
  734.  
  735.     return _cairo_output_stream_get_status (pdf_operators->stream);
  736. }
  737.  
  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.
  741.  *
  742.  * eg the matrix  [ 100  0  0  50   20   10  ]
  743.  *
  744.  * is rescaled to [  1   0  0  0.5  0.2  0.1 ]
  745.  * and the scale returned is 100
  746.  */
  747. static void
  748. _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
  749. {
  750.     double s;
  751.  
  752.     s = fabs (m->xx);
  753.     if (fabs (m->xy) > s)
  754.         s = fabs (m->xy);
  755.     if (fabs (m->yx) > s)
  756.         s = fabs (m->yx);
  757.     if (fabs (m->yy) > s)
  758.         s = fabs (m->yy);
  759.     *scale = s;
  760.     s = 1.0/s;
  761.     cairo_matrix_scale (m, s, s);
  762. }
  763.  
  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)
  771. {
  772.     cairo_int_status_t status;
  773.     cairo_matrix_t m, path_transform;
  774.     cairo_bool_t has_ctm = TRUE;
  775.     double scale = 1.0;
  776.  
  777.     if (pdf_operators->in_text_object) {
  778.         status = _cairo_pdf_operators_end_text (pdf_operators);
  779.         if (unlikely (status))
  780.             return status;
  781.     }
  782.  
  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.
  786.      */
  787.     if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 &&
  788.         fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0)
  789.     {
  790.         has_ctm = FALSE;
  791.     }
  792.  
  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).
  800.      *
  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.
  807.      */
  808.     if (has_ctm) {
  809.         m = *ctm;
  810.         /* Zero out the translation since it does not affect the pen
  811.          * shape however it may cause unnecessary digits to be emitted.
  812.          */
  813.         m.x0 = 0.0;
  814.         m.y0 = 0.0;
  815.         _cairo_matrix_factor_out_scale (&m, &scale);
  816.         path_transform = m;
  817.         status = cairo_matrix_invert (&path_transform);
  818.         if (unlikely (status))
  819.             return status;
  820.  
  821.         cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
  822.     }
  823.  
  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))
  828.         return status;
  829.  
  830.     if (has_ctm) {
  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,
  834.                                      m.x0, m.y0);
  835.     } else {
  836.         path_transform = pdf_operators->cairo_to_pdf;
  837.     }
  838.  
  839.     status = _cairo_pdf_operators_emit_path (pdf_operators,
  840.                                              path,
  841.                                              &path_transform,
  842.                                              style->line_cap);
  843.     if (unlikely (status))
  844.         return status;
  845.  
  846.     _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
  847.     if (has_ctm)
  848.         _cairo_output_stream_printf (pdf_operators->stream, " Q");
  849.  
  850.     _cairo_output_stream_printf (pdf_operators->stream, "\n");
  851.  
  852.     return _cairo_output_stream_get_status (pdf_operators->stream);
  853. }
  854.  
  855. cairo_int_status_t
  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)
  861. {
  862.     return _cairo_pdf_operators_emit_stroke (pdf_operators,
  863.                                              path,
  864.                                              style,
  865.                                              ctm,
  866.                                              ctm_inverse,
  867.                                              "S");
  868. }
  869.  
  870. cairo_int_status_t
  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)
  874. {
  875.     const char *pdf_operator;
  876.     cairo_status_t status;
  877.  
  878.     if (pdf_operators->in_text_object) {
  879.         status = _cairo_pdf_operators_end_text (pdf_operators);
  880.         if (unlikely (status))
  881.             return status;
  882.     }
  883.  
  884.     status = _cairo_pdf_operators_emit_path (pdf_operators,
  885.                                              path,
  886.                                              &pdf_operators->cairo_to_pdf,
  887.                                              CAIRO_LINE_CAP_ROUND);
  888.     if (unlikely (status))
  889.         return status;
  890.  
  891.     switch (fill_rule) {
  892.     default:
  893.         ASSERT_NOT_REACHED;
  894.     case CAIRO_FILL_RULE_WINDING:
  895.         pdf_operator = "f";
  896.         break;
  897.     case CAIRO_FILL_RULE_EVEN_ODD:
  898.         pdf_operator = "f*";
  899.         break;
  900.     }
  901.  
  902.     _cairo_output_stream_printf (pdf_operators->stream,
  903.                                  "%s\n",
  904.                                  pdf_operator);
  905.  
  906.     return _cairo_output_stream_get_status (pdf_operators->stream);
  907. }
  908.  
  909. cairo_int_status_t
  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)
  916. {
  917.     const char *operator;
  918.  
  919.     switch (fill_rule) {
  920.     default:
  921.         ASSERT_NOT_REACHED;
  922.     case CAIRO_FILL_RULE_WINDING:
  923.         operator = "B";
  924.         break;
  925.     case CAIRO_FILL_RULE_EVEN_ODD:
  926.         operator = "B*";
  927.         break;
  928.     }
  929.  
  930.     return _cairo_pdf_operators_emit_stroke (pdf_operators,
  931.                                              path,
  932.                                              style,
  933.                                              ctm,
  934.                                              ctm_inverse,
  935.                                              operator);
  936. }
  937.  
  938. static void
  939. _cairo_pdf_operators_emit_glyph_index (cairo_pdf_operators_t *pdf_operators,
  940.                                        cairo_output_stream_t *stream,
  941.                                        unsigned int           glyph)
  942. {
  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);
  948.         else
  949.             _cairo_output_stream_printf (stream, "\\%03o", glyph);
  950.     } else {
  951.         _cairo_output_stream_printf (stream,
  952.                                      "%0*x",
  953.                                      pdf_operators->hex_width,
  954.                                      glyph);
  955.     }
  956. }
  957.  
  958. #define GLYPH_POSITION_TOLERANCE 0.001
  959.  
  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)
  965. {
  966.     int i;
  967.  
  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,
  971.                                                stream,
  972.                                                pdf_operators->glyphs[i].glyph_index);
  973.         pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
  974.     }
  975.     _cairo_output_stream_printf (stream, "%sTj\n", pdf_operators->is_latin ? ")" : ">");
  976.  
  977.     return _cairo_output_stream_get_status (stream);
  978. }
  979.  
  980. /* Emit the string of glyphs using the 'TJ' operator.
  981.  *
  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.
  987.  */
  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)
  992. {
  993.     int i;
  994.  
  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)
  998.         {
  999.             double delta = pdf_operators->glyphs[i].x_position - pdf_operators->cur_x;
  1000.             int rounded_delta;
  1001.  
  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.
  1009.              */
  1010.             rounded_delta = _cairo_lround (delta);
  1011.             if (abs(rounded_delta) < 3)
  1012.                 rounded_delta = 0;
  1013.             if (rounded_delta != 0) {
  1014.                 if (pdf_operators->is_latin) {
  1015.                     _cairo_output_stream_printf (stream,
  1016.                                                  ")%d(",
  1017.                                                  rounded_delta);
  1018.                 } else {
  1019.                     _cairo_output_stream_printf (stream,
  1020.                                                  ">%d<",
  1021.                                                  rounded_delta);
  1022.                 }
  1023.             }
  1024.  
  1025.             /* Convert the rounded delta back to text
  1026.              * space before adding to the current text
  1027.              * position. */
  1028.             delta = rounded_delta/-1000.0;
  1029.             pdf_operators->cur_x += delta;
  1030.         }
  1031.  
  1032.         _cairo_pdf_operators_emit_glyph_index (pdf_operators,
  1033.                                                stream,
  1034.                                                pdf_operators->glyphs[i].glyph_index);
  1035.         pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
  1036.     }
  1037.     _cairo_output_stream_printf (stream, "%s]TJ\n", pdf_operators->is_latin ? ")" : ">");
  1038.  
  1039.     return _cairo_output_stream_get_status (stream);
  1040. }
  1041.  
  1042. static cairo_status_t
  1043. _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t    *pdf_operators)
  1044. {
  1045.     cairo_output_stream_t *word_wrap_stream;
  1046.     cairo_status_t status, status2;
  1047.     int i;
  1048.     double x;
  1049.  
  1050.     if (pdf_operators->num_glyphs == 0)
  1051.         return CAIRO_STATUS_SUCCESS;
  1052.  
  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);
  1057.  
  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)
  1062.             break;
  1063.         x += pdf_operators->glyphs[i].x_advance;
  1064.     }
  1065.     if (i == pdf_operators->num_glyphs) {
  1066.         status = _cairo_pdf_operators_emit_glyph_string (pdf_operators,
  1067.                                                          word_wrap_stream);
  1068.     } else {
  1069.         status = _cairo_pdf_operators_emit_glyph_string_with_positioning (
  1070.             pdf_operators, word_wrap_stream);
  1071.     }
  1072.  
  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)
  1077.         status = status2;
  1078.  
  1079.     return status;
  1080. }
  1081.  
  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,
  1085.                                 double                             x_position)
  1086. {
  1087.     double x, y;
  1088.  
  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);
  1093.  
  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);
  1101.  
  1102.     return CAIRO_STATUS_SUCCESS;
  1103. }
  1104.  
  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)
  1109. {
  1110.     cairo_matrix_t inverse;
  1111.     cairo_status_t status;
  1112.  
  1113.     /* We require the matrix to be invertable. */
  1114.     inverse = *matrix;
  1115.     status = cairo_matrix_invert (&inverse);
  1116.     if (unlikely (status))
  1117.         return status;
  1118.  
  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);
  1131.  
  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);
  1138.  
  1139.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1140. }
  1141.  
  1142. #define TEXT_MATRIX_TOLERANCE 1e-6
  1143.  
  1144. /* Set the translation components of the PDF text matrix to x, y. The
  1145.  * 'Td' operator is used to transform the text matrix.
  1146.  */
  1147. static cairo_status_t
  1148. _cairo_pdf_operators_set_text_position (cairo_pdf_operators_t  *pdf_operators,
  1149.                                         double                  x,
  1150.                                         double                  y)
  1151. {
  1152.     cairo_matrix_t translate, inverse;
  1153.     cairo_status_t status;
  1154.  
  1155.     /* The Td operator transforms the text_matrix with:
  1156.      *
  1157.      *   text_matrix' = T x text_matrix
  1158.      *
  1159.      * where T is a translation matrix with the translation components
  1160.      * set to the Td operands tx and ty.
  1161.      */
  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)
  1169.         translate.x0 = 0.0;
  1170.     if (fabs(translate.y0) < TEXT_MATRIX_TOLERANCE)
  1171.         translate.y0 = 0.0;
  1172.     _cairo_output_stream_printf (pdf_operators->stream,
  1173.                                  "%f %f Td\n",
  1174.                                  translate.x0,
  1175.                                  translate.y0);
  1176.     pdf_operators->cur_x = 0;
  1177.     pdf_operators->cur_y = 0;
  1178.     pdf_operators->glyph_buf_x_pos = 0;
  1179.  
  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);
  1186.  
  1187.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1188. }
  1189.  
  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.
  1192.  */
  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)
  1196. {
  1197.     cairo_status_t status;
  1198.  
  1199.     _cairo_output_stream_printf (pdf_operators->stream,
  1200.                                  "/f-%d-%d 1 Tf\n",
  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))
  1208.             return status;
  1209.     }
  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;
  1213.  
  1214.     if (subset_glyph->is_composite)
  1215.         pdf_operators->hex_width = 4;
  1216.     else
  1217.         pdf_operators->hex_width = 2;
  1218.  
  1219.     return CAIRO_STATUS_SUCCESS;
  1220. }
  1221.  
  1222. static cairo_status_t
  1223. _cairo_pdf_operators_begin_text (cairo_pdf_operators_t    *pdf_operators)
  1224. {
  1225.     _cairo_output_stream_printf (pdf_operators->stream, "BT\n");
  1226.  
  1227.     pdf_operators->in_text_object = TRUE;
  1228.     pdf_operators->num_glyphs = 0;
  1229.     pdf_operators->glyph_buf_x_pos = 0;
  1230.  
  1231.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1232. }
  1233.  
  1234. static cairo_status_t
  1235. _cairo_pdf_operators_end_text (cairo_pdf_operators_t    *pdf_operators)
  1236. {
  1237.     cairo_status_t status;
  1238.  
  1239.     status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1240.     if (unlikely (status))
  1241.         return status;
  1242.  
  1243.     _cairo_output_stream_printf (pdf_operators->stream, "ET\n");
  1244.  
  1245.     pdf_operators->in_text_object = FALSE;
  1246.  
  1247.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1248. }
  1249.  
  1250. /* Compare the scale components of two matrices. The translation
  1251.  * components are ignored. */
  1252. static cairo_bool_t
  1253. _cairo_matrix_scale_equal (cairo_matrix_t *a, cairo_matrix_t *b)
  1254. {
  1255.     return (a->xx == b->xx &&
  1256.             a->xy == b->xy &&
  1257.             a->yx == b->yx &&
  1258.             a->yy == b->yy);
  1259. }
  1260.  
  1261. static cairo_status_t
  1262. _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators,
  1263.                                        const char            *utf8,
  1264.                                        int                    utf8_len)
  1265. {
  1266.     uint16_t *utf16;
  1267.     int utf16_len;
  1268.     cairo_status_t status;
  1269.     int i;
  1270.  
  1271.     _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff");
  1272.     if (utf8_len) {
  1273.         status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len);
  1274.         if (unlikely (status))
  1275.             return status;
  1276.  
  1277.         for (i = 0; i < utf16_len; i++) {
  1278.             _cairo_output_stream_printf (pdf_operators->stream,
  1279.                                          "%04x", (int) (utf16[i]));
  1280.         }
  1281.         free (utf16);
  1282.     }
  1283.     _cairo_output_stream_printf (pdf_operators->stream, "> >> BDC\n");
  1284.  
  1285.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1286. }
  1287.  
  1288. static cairo_status_t
  1289. _cairo_pdf_operators_end_actualtext (cairo_pdf_operators_t    *pdf_operators)
  1290. {
  1291.     _cairo_output_stream_printf (pdf_operators->stream, "EMC\n");
  1292.  
  1293.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1294. }
  1295.  
  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)
  1300. {
  1301.     double x, y;
  1302.     cairo_status_t status;
  1303.  
  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)
  1307.     {
  1308.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1309.         if (unlikely (status))
  1310.             return status;
  1311.  
  1312.         status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph);
  1313.         if (unlikely (status))
  1314.             return status;
  1315.  
  1316.         pdf_operators->is_new_text_object = FALSE;
  1317.     }
  1318.  
  1319.     x = glyph->x;
  1320.     y = glyph->y;
  1321.     cairo_matrix_transform_point (&pdf_operators->cairo_to_pdftext, &x, &y);
  1322.  
  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.
  1333.      */
  1334.     if (fabs(x - pdf_operators->glyph_buf_x_pos) > 10 ||
  1335.         fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE)
  1336.     {
  1337.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1338.         if (unlikely (status))
  1339.             return status;
  1340.  
  1341.         x = glyph->x;
  1342.         y = glyph->y;
  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))
  1346.             return status;
  1347.  
  1348.         x = 0.0;
  1349.         y = 0.0;
  1350.     }
  1351.  
  1352.     status = _cairo_pdf_operators_add_glyph (pdf_operators,
  1353.                                              subset_glyph,
  1354.                                              x);
  1355.     return status;
  1356. }
  1357.  
  1358. /* A utf8_len of -1 indicates no unicode text. A utf8_len = 0 is an
  1359.  * empty string.
  1360.  */
  1361. static cairo_int_status_t
  1362. _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t      *pdf_operators,
  1363.                                    const char                 *utf8,
  1364.                                    int                         utf8_len,
  1365.                                    cairo_glyph_t              *glyphs,
  1366.                                    int                         num_glyphs,
  1367.                                    cairo_text_cluster_flags_t  cluster_flags,
  1368.                                    cairo_scaled_font_t        *scaled_font)
  1369. {
  1370.     cairo_scaled_font_subsets_glyph_t subset_glyph;
  1371.     cairo_glyph_t *cur_glyph;
  1372.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  1373.     int i;
  1374.  
  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.
  1379.      *
  1380.      * We also go through this path if no unicode mapping was
  1381.      * supplied (utf8_len < 0).
  1382.      *
  1383.      * Mapping a glyph to a zero length unicode string requires the
  1384.      * use of ActualText.
  1385.      */
  1386.     if (num_glyphs == 1 && utf8_len != 0) {
  1387.         status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
  1388.                                                        scaled_font,
  1389.                                                        glyphs->index,
  1390.                                                        utf8,
  1391.                                                        utf8_len,
  1392.                                                        &subset_glyph);
  1393.         if (unlikely (status))
  1394.             return status;
  1395.  
  1396.         if (subset_glyph.utf8_is_mapped || utf8_len < 0) {
  1397.             status = _cairo_pdf_operators_emit_glyph (pdf_operators,
  1398.                                                       glyphs,
  1399.                                                       &subset_glyph);
  1400.             if (unlikely (status))
  1401.                 return status;
  1402.  
  1403.             return CAIRO_STATUS_SUCCESS;
  1404.         }
  1405.     }
  1406.  
  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))
  1412.             return status;
  1413.  
  1414.         status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len);
  1415.         if (unlikely (status))
  1416.             return status;
  1417.     }
  1418.  
  1419.     cur_glyph = glyphs;
  1420.     /* XXX
  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,
  1424.                                                        scaled_font,
  1425.                                                        cur_glyph->index,
  1426.                                                        NULL, -1,
  1427.                                                        &subset_glyph);
  1428.         if (unlikely (status))
  1429.             return status;
  1430.  
  1431.         status = _cairo_pdf_operators_emit_glyph (pdf_operators,
  1432.                                                   cur_glyph,
  1433.                                                   &subset_glyph);
  1434.         if (unlikely (status))
  1435.             return status;
  1436.  
  1437.         if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1438.             cur_glyph--;
  1439.         else
  1440.             cur_glyph++;
  1441.     }
  1442.  
  1443.     if (pdf_operators->use_actual_text) {
  1444.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1445.         if (unlikely (status))
  1446.             return status;
  1447.  
  1448.         status = _cairo_pdf_operators_end_actualtext (pdf_operators);
  1449.     }
  1450.  
  1451.     return status;
  1452. }
  1453.  
  1454. cairo_int_status_t
  1455. _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t      *pdf_operators,
  1456.                                        const char                 *utf8,
  1457.                                        int                         utf8_len,
  1458.                                        cairo_glyph_t              *glyphs,
  1459.                                        int                         num_glyphs,
  1460.                                        const cairo_text_cluster_t *clusters,
  1461.                                        int                         num_clusters,
  1462.                                        cairo_text_cluster_flags_t  cluster_flags,
  1463.                                        cairo_scaled_font_t        *scaled_font)
  1464. {
  1465.     cairo_status_t status;
  1466.     int i;
  1467.     cairo_matrix_t text_matrix, invert_y_axis;
  1468.     double x, y;
  1469.     const char *cur_text;
  1470.     cairo_glyph_t *cur_glyph;
  1471.  
  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);
  1477.  
  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))
  1482.             return status;
  1483.  
  1484.         /* Force Tm and Tf to be emitted when starting a new text
  1485.          * object.*/
  1486.         pdf_operators->is_new_text_object = TRUE;
  1487.     }
  1488.  
  1489.     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
  1490.     text_matrix = scaled_font->scale;
  1491.  
  1492.     /* Invert y axis in font space  */
  1493.     cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis);
  1494.  
  1495.     /* Invert y axis in device space  */
  1496.     cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix);
  1497.  
  1498.     if (pdf_operators->is_new_text_object ||
  1499.         ! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix))
  1500.     {
  1501.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1502.         if (unlikely (status))
  1503.             return status;
  1504.  
  1505.         x = glyphs[0].x;
  1506.         y = glyphs[0].y;
  1507.         cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
  1508.         text_matrix.x0 = x;
  1509.         text_matrix.y0 = 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))
  1514.             return status;
  1515.     }
  1516.  
  1517.     if (num_clusters > 0) {
  1518.         cur_text = utf8;
  1519.         if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1520.             cur_glyph = glyphs + num_glyphs;
  1521.         else
  1522.             cur_glyph = 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,
  1527.                                                         cur_text,
  1528.                                                         clusters[i].num_bytes,
  1529.                                                         cur_glyph,
  1530.                                                         clusters[i].num_glyphs,
  1531.                                                         cluster_flags,
  1532.                                                         scaled_font);
  1533.             if (unlikely (status))
  1534.                 return status;
  1535.  
  1536.             cur_text += clusters[i].num_bytes;
  1537.             if (!(cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1538.                 cur_glyph += clusters[i].num_glyphs;
  1539.         }
  1540.     } else {
  1541.         for (i = 0; i < num_glyphs; i++) {
  1542.             status = _cairo_pdf_operators_emit_cluster (pdf_operators,
  1543.                                                         NULL,
  1544.                                                         -1, /* no unicode string available */
  1545.                                                         &glyphs[i],
  1546.                                                         1,
  1547.                                                         FALSE,
  1548.                                                         scaled_font);
  1549.             if (unlikely (status))
  1550.                 return status;
  1551.         }
  1552.     }
  1553.  
  1554.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1555. }
  1556.  
  1557. #endif /* CAIRO_HAS_PDF_OPERATORS */
  1558.