Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | 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. typedef struct _word_wrap_stream {
  167.     cairo_output_stream_t base;
  168.     cairo_output_stream_t *output;
  169.     int max_column;
  170.     int column;
  171.     cairo_bool_t last_write_was_space;
  172.     cairo_bool_t in_hexstring;
  173.     cairo_bool_t empty_hexstring;
  174. } word_wrap_stream_t;
  175.  
  176. static int
  177. _count_word_up_to (const unsigned char *s, int length)
  178. {
  179.     int word = 0;
  180.  
  181.     while (length--) {
  182.         if (! (_cairo_isspace (*s) || *s == '<')) {
  183.             s++;
  184.             word++;
  185.         } else {
  186.             return word;
  187.         }
  188.     }
  189.  
  190.     return word;
  191. }
  192.  
  193.  
  194. /* Count up to either the end of the ASCII hexstring or the number
  195.  * of columns remaining.
  196.  */
  197. static int
  198. _count_hexstring_up_to (const unsigned char *s, int length, int columns)
  199. {
  200.     int word = 0;
  201.  
  202.     while (length--) {
  203.         if (*s++ != '>')
  204.             word++;
  205.         else
  206.             return word;
  207.  
  208.         columns--;
  209.         if (columns < 0 && word > 1)
  210.             return word;
  211.     }
  212.  
  213.     return word;
  214. }
  215.  
  216. static cairo_status_t
  217. _word_wrap_stream_write (cairo_output_stream_t  *base,
  218.                          const unsigned char    *data,
  219.                          unsigned int            length)
  220. {
  221.     word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
  222.     cairo_bool_t newline;
  223.     int word;
  224.  
  225.     while (length) {
  226.         if (*data == '<') {
  227.             stream->in_hexstring = TRUE;
  228.             stream->empty_hexstring = TRUE;
  229.             stream->last_write_was_space = FALSE;
  230.             data++;
  231.             length--;
  232.             _cairo_output_stream_printf (stream->output, "<");
  233.             stream->column++;
  234.         } else if (*data == '>') {
  235.             stream->in_hexstring = FALSE;
  236.             stream->last_write_was_space = FALSE;
  237.             data++;
  238.             length--;
  239.             _cairo_output_stream_printf (stream->output, ">");
  240.             stream->column++;
  241.         } else if (_cairo_isspace (*data)) {
  242.             newline =  (*data == '\n' || *data == '\r');
  243.             if (! newline && stream->column >= stream->max_column) {
  244.                 _cairo_output_stream_printf (stream->output, "\n");
  245.                 stream->column = 0;
  246.             }
  247.             _cairo_output_stream_write (stream->output, data, 1);
  248.             data++;
  249.             length--;
  250.             if (newline) {
  251.                 stream->column = 0;
  252.             }
  253.             else
  254.                 stream->column++;
  255.             stream->last_write_was_space = TRUE;
  256.         } else {
  257.             if (stream->in_hexstring) {
  258.                 word = _count_hexstring_up_to (data, length,
  259.                                                MAX (stream->max_column - stream->column, 0));
  260.             } else {
  261.                 word = _count_word_up_to (data, length);
  262.             }
  263.             /* Don't wrap if this word is a continuation of a non hex
  264.              * string word from a previous call to write. */
  265.             if (stream->column + word >= stream->max_column) {
  266.                 if (stream->last_write_was_space ||
  267.                     (stream->in_hexstring && !stream->empty_hexstring))
  268.                 {
  269.                     _cairo_output_stream_printf (stream->output, "\n");
  270.                     stream->column = 0;
  271.                 }
  272.             }
  273.             _cairo_output_stream_write (stream->output, data, word);
  274.             data += word;
  275.             length -= word;
  276.             stream->column += word;
  277.             stream->last_write_was_space = FALSE;
  278.             if (stream->in_hexstring)
  279.                 stream->empty_hexstring = FALSE;
  280.         }
  281.     }
  282.  
  283.     return _cairo_output_stream_get_status (stream->output);
  284. }
  285.  
  286. static cairo_status_t
  287. _word_wrap_stream_close (cairo_output_stream_t *base)
  288. {
  289.     word_wrap_stream_t *stream = (word_wrap_stream_t *) base;
  290.  
  291.     return _cairo_output_stream_get_status (stream->output);
  292. }
  293.  
  294. static cairo_output_stream_t *
  295. _word_wrap_stream_create (cairo_output_stream_t *output, int max_column)
  296. {
  297.     word_wrap_stream_t *stream;
  298.  
  299.     if (output->status)
  300.         return _cairo_output_stream_create_in_error (output->status);
  301.  
  302.     stream = malloc (sizeof (word_wrap_stream_t));
  303.     if (unlikely (stream == NULL)) {
  304.         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
  305.         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
  306.     }
  307.  
  308.     _cairo_output_stream_init (&stream->base,
  309.                                _word_wrap_stream_write,
  310.                                NULL,
  311.                                _word_wrap_stream_close);
  312.     stream->output = output;
  313.     stream->max_column = max_column;
  314.     stream->column = 0;
  315.     stream->last_write_was_space = FALSE;
  316.     stream->in_hexstring = FALSE;
  317.     stream->empty_hexstring = TRUE;
  318.  
  319.     return &stream->base;
  320. }
  321.  
  322. typedef struct _pdf_path_info {
  323.     cairo_output_stream_t   *output;
  324.     cairo_matrix_t          *path_transform;
  325.     cairo_line_cap_t         line_cap;
  326.     cairo_point_t            last_move_to_point;
  327.     cairo_bool_t             has_sub_path;
  328. } pdf_path_info_t;
  329.  
  330. static cairo_status_t
  331. _cairo_pdf_path_move_to (void *closure,
  332.                          const cairo_point_t *point)
  333. {
  334.     pdf_path_info_t *info = closure;
  335.     double x = _cairo_fixed_to_double (point->x);
  336.     double y = _cairo_fixed_to_double (point->y);
  337.  
  338.     info->last_move_to_point = *point;
  339.     info->has_sub_path = FALSE;
  340.     cairo_matrix_transform_point (info->path_transform, &x, &y);
  341.     _cairo_output_stream_printf (info->output,
  342.                                  "%g %g m ", x, y);
  343.  
  344.     return _cairo_output_stream_get_status (info->output);
  345. }
  346.  
  347. static cairo_status_t
  348. _cairo_pdf_path_line_to (void *closure,
  349.                          const cairo_point_t *point)
  350. {
  351.     pdf_path_info_t *info = closure;
  352.     double x = _cairo_fixed_to_double (point->x);
  353.     double y = _cairo_fixed_to_double (point->y);
  354.  
  355.     if (info->line_cap != CAIRO_LINE_CAP_ROUND &&
  356.         ! info->has_sub_path &&
  357.         point->x == info->last_move_to_point.x &&
  358.         point->y == info->last_move_to_point.y)
  359.     {
  360.         return CAIRO_STATUS_SUCCESS;
  361.     }
  362.  
  363.     info->has_sub_path = TRUE;
  364.     cairo_matrix_transform_point (info->path_transform, &x, &y);
  365.     _cairo_output_stream_printf (info->output,
  366.                                  "%g %g l ", x, y);
  367.  
  368.     return _cairo_output_stream_get_status (info->output);
  369. }
  370.  
  371. static cairo_status_t
  372. _cairo_pdf_path_curve_to (void          *closure,
  373.                           const cairo_point_t *b,
  374.                           const cairo_point_t *c,
  375.                           const cairo_point_t *d)
  376. {
  377.     pdf_path_info_t *info = closure;
  378.     double bx = _cairo_fixed_to_double (b->x);
  379.     double by = _cairo_fixed_to_double (b->y);
  380.     double cx = _cairo_fixed_to_double (c->x);
  381.     double cy = _cairo_fixed_to_double (c->y);
  382.     double dx = _cairo_fixed_to_double (d->x);
  383.     double dy = _cairo_fixed_to_double (d->y);
  384.  
  385.     info->has_sub_path = TRUE;
  386.     cairo_matrix_transform_point (info->path_transform, &bx, &by);
  387.     cairo_matrix_transform_point (info->path_transform, &cx, &cy);
  388.     cairo_matrix_transform_point (info->path_transform, &dx, &dy);
  389.     _cairo_output_stream_printf (info->output,
  390.                                  "%g %g %g %g %g %g c ",
  391.                                  bx, by, cx, cy, dx, dy);
  392.     return _cairo_output_stream_get_status (info->output);
  393. }
  394.  
  395. static cairo_status_t
  396. _cairo_pdf_path_close_path (void *closure)
  397. {
  398.     pdf_path_info_t *info = closure;
  399.  
  400.     if (info->line_cap != CAIRO_LINE_CAP_ROUND &&
  401.         ! info->has_sub_path)
  402.     {
  403.         return CAIRO_STATUS_SUCCESS;
  404.     }
  405.  
  406.     _cairo_output_stream_printf (info->output,
  407.                                  "h\n");
  408.  
  409.     return _cairo_output_stream_get_status (info->output);
  410. }
  411.  
  412. static cairo_status_t
  413. _cairo_pdf_path_rectangle (pdf_path_info_t *info, cairo_box_t *box)
  414. {
  415.     double x1 = _cairo_fixed_to_double (box->p1.x);
  416.     double y1 = _cairo_fixed_to_double (box->p1.y);
  417.     double x2 = _cairo_fixed_to_double (box->p2.x);
  418.     double y2 = _cairo_fixed_to_double (box->p2.y);
  419.  
  420.     cairo_matrix_transform_point (info->path_transform, &x1, &y1);
  421.     cairo_matrix_transform_point (info->path_transform, &x2, &y2);
  422.     _cairo_output_stream_printf (info->output,
  423.                                  "%g %g %g %g re ",
  424.                                  x1, y1, x2 - x1, y2 - y1);
  425.  
  426.     return _cairo_output_stream_get_status (info->output);
  427. }
  428.  
  429. /* The line cap value is needed to workaround the fact that PostScript
  430.  * and PDF semantics for stroking degenerate sub-paths do not match
  431.  * cairo semantics. (PostScript draws something for any line cap
  432.  * value, while cairo draws something only for round caps).
  433.  *
  434.  * When using this function to emit a path to be filled, rather than
  435.  * stroked, simply pass %CAIRO_LINE_CAP_ROUND which will guarantee that
  436.  * the stroke workaround will not modify the path being emitted.
  437.  */
  438. static cairo_status_t
  439. _cairo_pdf_operators_emit_path (cairo_pdf_operators_t   *pdf_operators,
  440.                                 cairo_path_fixed_t      *path,
  441.                                 cairo_matrix_t          *path_transform,
  442.                                 cairo_line_cap_t         line_cap)
  443. {
  444.     cairo_output_stream_t *word_wrap;
  445.     cairo_status_t status, status2;
  446.     pdf_path_info_t info;
  447.     cairo_box_t box;
  448.  
  449.     word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72);
  450.     status = _cairo_output_stream_get_status (word_wrap);
  451.     if (unlikely (status))
  452.         return _cairo_output_stream_destroy (word_wrap);
  453.  
  454.     info.output = word_wrap;
  455.     info.path_transform = path_transform;
  456.     info.line_cap = line_cap;
  457.     if (_cairo_path_fixed_is_rectangle (path, &box)) {
  458.         status = _cairo_pdf_path_rectangle (&info, &box);
  459.     } else {
  460.         status = _cairo_path_fixed_interpret (path,
  461.                                               CAIRO_DIRECTION_FORWARD,
  462.                                               _cairo_pdf_path_move_to,
  463.                                               _cairo_pdf_path_line_to,
  464.                                               _cairo_pdf_path_curve_to,
  465.                                               _cairo_pdf_path_close_path,
  466.                                               &info);
  467.     }
  468.  
  469.     status2 = _cairo_output_stream_destroy (word_wrap);
  470.     if (status == CAIRO_STATUS_SUCCESS)
  471.         status = status2;
  472.  
  473.     return status;
  474. }
  475.  
  476. cairo_int_status_t
  477. _cairo_pdf_operators_clip (cairo_pdf_operators_t        *pdf_operators,
  478.                            cairo_path_fixed_t           *path,
  479.                            cairo_fill_rule_t             fill_rule)
  480. {
  481.     const char *pdf_operator;
  482.     cairo_status_t status;
  483.  
  484.     if (pdf_operators->in_text_object) {
  485.         status = _cairo_pdf_operators_end_text (pdf_operators);
  486.         if (unlikely (status))
  487.             return status;
  488.     }
  489.  
  490.     if (! path->has_current_point) {
  491.         /* construct an empty path */
  492.         _cairo_output_stream_printf (pdf_operators->stream, "0 0 m ");
  493.     } else {
  494.         status = _cairo_pdf_operators_emit_path (pdf_operators,
  495.                                                  path,
  496.                                                  &pdf_operators->cairo_to_pdf,
  497.                                                  CAIRO_LINE_CAP_ROUND);
  498.         if (unlikely (status))
  499.             return status;
  500.     }
  501.  
  502.     switch (fill_rule) {
  503.     default:
  504.         ASSERT_NOT_REACHED;
  505.     case CAIRO_FILL_RULE_WINDING:
  506.         pdf_operator = "W";
  507.         break;
  508.     case CAIRO_FILL_RULE_EVEN_ODD:
  509.         pdf_operator = "W*";
  510.         break;
  511.     }
  512.  
  513.     _cairo_output_stream_printf (pdf_operators->stream,
  514.                                  "%s n\n",
  515.                                  pdf_operator);
  516.  
  517.     return _cairo_output_stream_get_status (pdf_operators->stream);
  518. }
  519.  
  520. static int
  521. _cairo_pdf_line_cap (cairo_line_cap_t cap)
  522. {
  523.     switch (cap) {
  524.     case CAIRO_LINE_CAP_BUTT:
  525.         return 0;
  526.     case CAIRO_LINE_CAP_ROUND:
  527.         return 1;
  528.     case CAIRO_LINE_CAP_SQUARE:
  529.         return 2;
  530.     default:
  531.         ASSERT_NOT_REACHED;
  532.         return 0;
  533.     }
  534. }
  535.  
  536. static int
  537. _cairo_pdf_line_join (cairo_line_join_t join)
  538. {
  539.     switch (join) {
  540.     case CAIRO_LINE_JOIN_MITER:
  541.         return 0;
  542.     case CAIRO_LINE_JOIN_ROUND:
  543.         return 1;
  544.     case CAIRO_LINE_JOIN_BEVEL:
  545.         return 2;
  546.     default:
  547.         ASSERT_NOT_REACHED;
  548.         return 0;
  549.     }
  550. }
  551.  
  552. cairo_int_status_t
  553. _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t           *pdf_operators,
  554.                                         const cairo_stroke_style_t      *style,
  555.                                         double                           scale)
  556. {
  557.     double *dash = style->dash;
  558.     int num_dashes = style->num_dashes;
  559.     double dash_offset = style->dash_offset;
  560.     double line_width = style->line_width * scale;
  561.  
  562.     /* PostScript has "special needs" when it comes to zero-length
  563.      * dash segments with butt caps. It apparently (at least
  564.      * according to ghostscript) draws hairlines for this
  565.      * case. That's not what the cairo semantics want, so we first
  566.      * touch up the array to eliminate any 0.0 values that will
  567.      * result in "on" segments.
  568.      */
  569.     if (num_dashes && style->line_cap == CAIRO_LINE_CAP_BUTT) {
  570.         int i;
  571.  
  572.         /* If there's an odd number of dash values they will each get
  573.          * interpreted as both on and off. So we first explicitly
  574.          * expand the array to remove the duplicate usage so that we
  575.          * can modify some of the values.
  576.          */
  577.         if (num_dashes % 2) {
  578.             dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double));
  579.             if (unlikely (dash == NULL))
  580.                 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  581.  
  582.             memcpy (dash, style->dash, num_dashes * sizeof (double));
  583.             memcpy (dash + num_dashes, style->dash, num_dashes * sizeof (double));
  584.  
  585.             num_dashes *= 2;
  586.         }
  587.  
  588.         for (i = 0; i < num_dashes; i += 2) {
  589.             if (dash[i] == 0.0) {
  590.                 /* Do not modify the dashes in-place, as we may need to also
  591.                  * replay this stroke to an image fallback.
  592.                  */
  593.                 if (dash == style->dash) {
  594.                     dash = _cairo_malloc_ab (num_dashes, sizeof (double));
  595.                     if (unlikely (dash == NULL))
  596.                         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  597.                     memcpy (dash, style->dash, num_dashes * sizeof (double));
  598.                 }
  599.  
  600.                 /* If we're at the front of the list, we first rotate
  601.                  * two elements from the end of the list to the front
  602.                  * of the list before folding away the 0.0. Or, if
  603.                  * there are only two dash elements, then there is
  604.                  * nothing at all to draw.
  605.                  */
  606.                 if (i == 0) {
  607.                     double last_two[2];
  608.  
  609.                     if (num_dashes == 2) {
  610.                         free (dash);
  611.                         return CAIRO_INT_STATUS_NOTHING_TO_DO;
  612.                     }
  613.  
  614.                     /* The cases of num_dashes == 0, 1, or 3 elements
  615.                      * cannot exist, so the rotation of 2 elements
  616.                      * will always be safe */
  617.                     memcpy (last_two, dash + num_dashes - 2, sizeof (last_two));
  618.                     memmove (dash + 2, dash, (num_dashes - 2) * sizeof (double));
  619.                     memcpy (dash, last_two, sizeof (last_two));
  620.                     dash_offset += dash[0] + dash[1];
  621.                     i = 2;
  622.                 }
  623.                 dash[i-1] += dash[i+1];
  624.                 num_dashes -= 2;
  625.                 memmove (dash + i, dash + i + 2, (num_dashes - i) * sizeof (double));
  626.                 /* If we might have just rotated, it's possible that
  627.                  * we rotated a 0.0 value to the front of the list.
  628.                  * Set i to -2 so it will get incremented to 0. */
  629.                 if (i == 2)
  630.                     i = -2;
  631.             }
  632.         }
  633.     }
  634.  
  635.     if (!pdf_operators->has_line_style || pdf_operators->line_width != line_width) {
  636.         _cairo_output_stream_printf (pdf_operators->stream,
  637.                                      "%f w\n",
  638.                                      line_width);
  639.         pdf_operators->line_width = line_width;
  640.     }
  641.  
  642.     if (!pdf_operators->has_line_style || pdf_operators->line_cap != style->line_cap) {
  643.         _cairo_output_stream_printf (pdf_operators->stream,
  644.                                      "%d J\n",
  645.                                      _cairo_pdf_line_cap (style->line_cap));
  646.         pdf_operators->line_cap = style->line_cap;
  647.     }
  648.  
  649.     if (!pdf_operators->has_line_style || pdf_operators->line_join != style->line_join) {
  650.         _cairo_output_stream_printf (pdf_operators->stream,
  651.                                      "%d j\n",
  652.                                      _cairo_pdf_line_join (style->line_join));
  653.         pdf_operators->line_join = style->line_join;
  654.     }
  655.  
  656.     if (num_dashes) {
  657.         int d;
  658.  
  659.         _cairo_output_stream_printf (pdf_operators->stream, "[");
  660.         for (d = 0; d < num_dashes; d++)
  661.             _cairo_output_stream_printf (pdf_operators->stream, " %f", dash[d] * scale);
  662.         _cairo_output_stream_printf (pdf_operators->stream, "] %f d\n",
  663.                                      dash_offset * scale);
  664.         pdf_operators->has_dashes = TRUE;
  665.     } else if (!pdf_operators->has_line_style || pdf_operators->has_dashes) {
  666.         _cairo_output_stream_printf (pdf_operators->stream, "[] 0.0 d\n");
  667.         pdf_operators->has_dashes = FALSE;
  668.     }
  669.     if (dash != style->dash)
  670.         free (dash);
  671.  
  672.     if (!pdf_operators->has_line_style || pdf_operators->miter_limit != style->miter_limit) {
  673.         _cairo_output_stream_printf (pdf_operators->stream,
  674.                                      "%f M ",
  675.                                      style->miter_limit < 1.0 ? 1.0 : style->miter_limit);
  676.         pdf_operators->miter_limit = style->miter_limit;
  677.     }
  678.     pdf_operators->has_line_style = TRUE;
  679.  
  680.     return _cairo_output_stream_get_status (pdf_operators->stream);
  681. }
  682.  
  683. /* Scale the matrix so the largest absolute value of the non
  684.  * translation components is 1.0. Return the scale required to restore
  685.  * the matrix to the original values.
  686.  *
  687.  * eg the matrix  [ 100  0  0  50   20   10  ]
  688.  *
  689.  * is rescaled to [  1   0  0  0.5  0.2  0.1 ]
  690.  * and the scale returned is 100
  691.  */
  692. static void
  693. _cairo_matrix_factor_out_scale (cairo_matrix_t *m, double *scale)
  694. {
  695.     double s;
  696.  
  697.     s = fabs (m->xx);
  698.     if (fabs (m->xy) > s)
  699.         s = fabs (m->xy);
  700.     if (fabs (m->yx) > s)
  701.         s = fabs (m->yx);
  702.     if (fabs (m->yy) > s)
  703.         s = fabs (m->yy);
  704.     *scale = s;
  705.     s = 1.0/s;
  706.     cairo_matrix_scale (m, s, s);
  707. }
  708.  
  709. static cairo_int_status_t
  710. _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t         *pdf_operators,
  711.                                   cairo_path_fixed_t            *path,
  712.                                   const cairo_stroke_style_t    *style,
  713.                                   const cairo_matrix_t          *ctm,
  714.                                   const cairo_matrix_t          *ctm_inverse,
  715.                                   const char                    *pdf_operator)
  716. {
  717.     cairo_status_t status;
  718.     cairo_matrix_t m, path_transform;
  719.     cairo_bool_t has_ctm = TRUE;
  720.     double scale = 1.0;
  721.  
  722.     if (pdf_operators->in_text_object) {
  723.         status = _cairo_pdf_operators_end_text (pdf_operators);
  724.         if (unlikely (status))
  725.             return status;
  726.     }
  727.  
  728.     /* Optimize away the stroke ctm when it does not affect the
  729.      * stroke. There are other ctm cases that could be optimized
  730.      * however this is the most common.
  731.      */
  732.     if (fabs(ctm->xx) == 1.0 && fabs(ctm->yy) == 1.0 &&
  733.         fabs(ctm->xy) == 0.0 && fabs(ctm->yx) == 0.0)
  734.     {
  735.         has_ctm = FALSE;
  736.     }
  737.  
  738.     /* The PDF CTM is transformed to the user space CTM when stroking
  739.      * so the corect pen shape will be used. This also requires that
  740.      * the path be transformed to user space when emitted. The
  741.      * conversion of path coordinates to user space may cause rounding
  742.      * errors. For example the device space point (1.234, 3.142) when
  743.      * transformed to a user space CTM of [100 0 0 100 0 0] will be
  744.      * emitted as (0.012, 0.031).
  745.      *
  746.      * To avoid the rounding problem we scale the user space CTM
  747.      * matrix so that all the non translation components of the matrix
  748.      * are <= 1. The line width and and dashes are scaled by the
  749.      * inverse of the scale applied to the CTM. This maintains the
  750.      * shape of the stroke pen while keeping the user space CTM within
  751.      * the range that maximizes the precision of the emitted path.
  752.      */
  753.     if (has_ctm) {
  754.         m = *ctm;
  755.         /* Zero out the translation since it does not affect the pen
  756.          * shape however it may cause unnecessary digits to be emitted.
  757.          */
  758.         m.x0 = 0.0;
  759.         m.y0 = 0.0;
  760.         _cairo_matrix_factor_out_scale (&m, &scale);
  761.         path_transform = m;
  762.         status = cairo_matrix_invert (&path_transform);
  763.         if (unlikely (status))
  764.             return status;
  765.  
  766.         cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf);
  767.     }
  768.  
  769.     status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale);
  770.     if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
  771.         return CAIRO_STATUS_SUCCESS;
  772.     if (unlikely (status))
  773.         return status;
  774.  
  775.     if (has_ctm) {
  776.         _cairo_output_stream_printf (pdf_operators->stream,
  777.                                      "q %f %f %f %f %f %f cm\n",
  778.                                      m.xx, m.yx, m.xy, m.yy,
  779.                                      m.x0, m.y0);
  780.     } else {
  781.         path_transform = pdf_operators->cairo_to_pdf;
  782.     }
  783.  
  784.     status = _cairo_pdf_operators_emit_path (pdf_operators,
  785.                                              path,
  786.                                              &path_transform,
  787.                                              style->line_cap);
  788.     if (unlikely (status))
  789.         return status;
  790.  
  791.     _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator);
  792.     if (has_ctm)
  793.         _cairo_output_stream_printf (pdf_operators->stream, " Q");
  794.  
  795.     _cairo_output_stream_printf (pdf_operators->stream, "\n");
  796.  
  797.     return _cairo_output_stream_get_status (pdf_operators->stream);
  798. }
  799.  
  800. cairo_int_status_t
  801. _cairo_pdf_operators_stroke (cairo_pdf_operators_t              *pdf_operators,
  802.                              cairo_path_fixed_t                 *path,
  803.                              const cairo_stroke_style_t         *style,
  804.                              const cairo_matrix_t               *ctm,
  805.                              const cairo_matrix_t               *ctm_inverse)
  806. {
  807.     return _cairo_pdf_operators_emit_stroke (pdf_operators,
  808.                                              path,
  809.                                              style,
  810.                                              ctm,
  811.                                              ctm_inverse,
  812.                                              "S");
  813. }
  814.  
  815. cairo_int_status_t
  816. _cairo_pdf_operators_fill (cairo_pdf_operators_t        *pdf_operators,
  817.                            cairo_path_fixed_t           *path,
  818.                            cairo_fill_rule_t            fill_rule)
  819. {
  820.     const char *pdf_operator;
  821.     cairo_status_t status;
  822.  
  823.     if (pdf_operators->in_text_object) {
  824.         status = _cairo_pdf_operators_end_text (pdf_operators);
  825.         if (unlikely (status))
  826.             return status;
  827.     }
  828.  
  829.     status = _cairo_pdf_operators_emit_path (pdf_operators,
  830.                                              path,
  831.                                              &pdf_operators->cairo_to_pdf,
  832.                                              CAIRO_LINE_CAP_ROUND);
  833.     if (unlikely (status))
  834.         return status;
  835.  
  836.     switch (fill_rule) {
  837.     default:
  838.         ASSERT_NOT_REACHED;
  839.     case CAIRO_FILL_RULE_WINDING:
  840.         pdf_operator = "f";
  841.         break;
  842.     case CAIRO_FILL_RULE_EVEN_ODD:
  843.         pdf_operator = "f*";
  844.         break;
  845.     }
  846.  
  847.     _cairo_output_stream_printf (pdf_operators->stream,
  848.                                  "%s\n",
  849.                                  pdf_operator);
  850.  
  851.     return _cairo_output_stream_get_status (pdf_operators->stream);
  852. }
  853.  
  854. cairo_int_status_t
  855. _cairo_pdf_operators_fill_stroke (cairo_pdf_operators_t         *pdf_operators,
  856.                                   cairo_path_fixed_t            *path,
  857.                                   cairo_fill_rule_t              fill_rule,
  858.                                   const cairo_stroke_style_t    *style,
  859.                                   const cairo_matrix_t          *ctm,
  860.                                   const cairo_matrix_t          *ctm_inverse)
  861. {
  862.     const char *operator;
  863.  
  864.     switch (fill_rule) {
  865.     default:
  866.         ASSERT_NOT_REACHED;
  867.     case CAIRO_FILL_RULE_WINDING:
  868.         operator = "B";
  869.         break;
  870.     case CAIRO_FILL_RULE_EVEN_ODD:
  871.         operator = "B*";
  872.         break;
  873.     }
  874.  
  875.     return _cairo_pdf_operators_emit_stroke (pdf_operators,
  876.                                              path,
  877.                                              style,
  878.                                              ctm,
  879.                                              ctm_inverse,
  880.                                              operator);
  881. }
  882.  
  883. #define GLYPH_POSITION_TOLERANCE 0.001
  884.  
  885. /* Emit the string of glyphs using the 'Tj' operator. This requires
  886.  * that the glyphs are positioned at their natural glyph advances. */
  887. static cairo_status_t
  888. _cairo_pdf_operators_emit_glyph_string (cairo_pdf_operators_t   *pdf_operators,
  889.                                         cairo_output_stream_t   *stream)
  890. {
  891.     int i;
  892.  
  893.     _cairo_output_stream_printf (stream, "<");
  894.     for (i = 0; i < pdf_operators->num_glyphs; i++) {
  895.         _cairo_output_stream_printf (stream,
  896.                                      "%0*x",
  897.                                      pdf_operators->hex_width,
  898.                                      pdf_operators->glyphs[i].glyph_index);
  899.         pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
  900.     }
  901.     _cairo_output_stream_printf (stream, ">Tj\n");
  902.  
  903.     return _cairo_output_stream_get_status (stream);
  904. }
  905.  
  906. /* Emit the string of glyphs using the 'TJ' operator.
  907.  *
  908.  * The TJ operator takes an array of strings of glyphs. Each string of
  909.  * glyphs is displayed using the glyph advances of each glyph to
  910.  * position the glyphs. A relative adjustment to the glyph advance may
  911.  * be specified by including the adjustment between two strings. The
  912.  * adjustment is in units of text space * -1000.
  913.  */
  914. static cairo_status_t
  915. _cairo_pdf_operators_emit_glyph_string_with_positioning (
  916.     cairo_pdf_operators_t   *pdf_operators,
  917.     cairo_output_stream_t   *stream)
  918. {
  919.     int i;
  920.  
  921.     _cairo_output_stream_printf (stream, "[<");
  922.     for (i = 0; i < pdf_operators->num_glyphs; i++) {
  923.         if (pdf_operators->glyphs[i].x_position != pdf_operators->cur_x)
  924.         {
  925.             double delta = pdf_operators->glyphs[i].x_position - pdf_operators->cur_x;
  926.             int rounded_delta;
  927.  
  928.             delta = -1000.0*delta;
  929.             /* As the delta is in 1/1000 of a unit of text space,
  930.              * rounding to an integer should still provide sufficient
  931.              * precision. We round the delta before adding to Tm_x so
  932.              * that we keep track of the accumulated rounding error in
  933.              * the PDF interpreter and compensate for it when
  934.              * calculating subsequent deltas.
  935.              */
  936.             rounded_delta = _cairo_lround (delta);
  937.             if (rounded_delta != 0) {
  938.                 _cairo_output_stream_printf (stream,
  939.                                              ">%d<",
  940.                                              rounded_delta);
  941.             }
  942.  
  943.             /* Convert the rounded delta back to text
  944.              * space before adding to the current text
  945.              * position. */
  946.             delta = rounded_delta/-1000.0;
  947.             pdf_operators->cur_x += delta;
  948.         }
  949.  
  950.         _cairo_output_stream_printf (stream,
  951.                                      "%0*x",
  952.                                      pdf_operators->hex_width,
  953.                                      pdf_operators->glyphs[i].glyph_index);
  954.         pdf_operators->cur_x += pdf_operators->glyphs[i].x_advance;
  955.     }
  956.     _cairo_output_stream_printf (stream, ">]TJ\n");
  957.  
  958.     return _cairo_output_stream_get_status (stream);
  959. }
  960.  
  961. static cairo_status_t
  962. _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t    *pdf_operators)
  963. {
  964.     cairo_output_stream_t *word_wrap_stream;
  965.     cairo_status_t status, status2;
  966.     int i;
  967.     double x;
  968.  
  969.     if (pdf_operators->num_glyphs == 0)
  970.         return CAIRO_STATUS_SUCCESS;
  971.  
  972.     word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72);
  973.     status = _cairo_output_stream_get_status (word_wrap_stream);
  974.     if (unlikely (status))
  975.         return _cairo_output_stream_destroy (word_wrap_stream);
  976.  
  977.     /* Check if glyph advance used to position every glyph */
  978.     x = pdf_operators->cur_x;
  979.     for (i = 0; i < pdf_operators->num_glyphs; i++) {
  980.         if (fabs(pdf_operators->glyphs[i].x_position - x) > GLYPH_POSITION_TOLERANCE)
  981.             break;
  982.         x += pdf_operators->glyphs[i].x_advance;
  983.     }
  984.     if (i == pdf_operators->num_glyphs) {
  985.         status = _cairo_pdf_operators_emit_glyph_string (pdf_operators,
  986.                                                          word_wrap_stream);
  987.     } else {
  988.         status = _cairo_pdf_operators_emit_glyph_string_with_positioning (
  989.             pdf_operators, word_wrap_stream);
  990.     }
  991.  
  992.     pdf_operators->num_glyphs = 0;
  993.     pdf_operators->glyph_buf_x_pos = pdf_operators->cur_x;
  994.     status2 = _cairo_output_stream_destroy (word_wrap_stream);
  995.     if (status == CAIRO_STATUS_SUCCESS)
  996.         status = status2;
  997.  
  998.     return status;
  999. }
  1000.  
  1001. static cairo_status_t
  1002. _cairo_pdf_operators_add_glyph (cairo_pdf_operators_t             *pdf_operators,
  1003.                                 cairo_scaled_font_subsets_glyph_t *glyph,
  1004.                                 double                             x_position)
  1005. {
  1006.     double x, y;
  1007.  
  1008.     x = glyph->x_advance;
  1009.     y = glyph->y_advance;
  1010.     if (glyph->is_scaled)
  1011.         cairo_matrix_transform_distance (&pdf_operators->font_matrix_inverse, &x, &y);
  1012.  
  1013.     pdf_operators->glyphs[pdf_operators->num_glyphs].x_position = x_position;
  1014.     pdf_operators->glyphs[pdf_operators->num_glyphs].glyph_index = glyph->subset_glyph_index;
  1015.     pdf_operators->glyphs[pdf_operators->num_glyphs].x_advance = x;
  1016.     pdf_operators->glyph_buf_x_pos += x;
  1017.     pdf_operators->num_glyphs++;
  1018.     if (pdf_operators->num_glyphs == PDF_GLYPH_BUFFER_SIZE)
  1019.         return _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1020.  
  1021.     return CAIRO_STATUS_SUCCESS;
  1022. }
  1023.  
  1024. /* Use 'Tm' operator to set the PDF text matrix. */
  1025. static cairo_status_t
  1026. _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t  *pdf_operators,
  1027.                                       cairo_matrix_t         *matrix)
  1028. {
  1029.     cairo_matrix_t inverse;
  1030.     cairo_status_t status;
  1031.  
  1032.     /* We require the matrix to be invertable. */
  1033.     inverse = *matrix;
  1034.     status = cairo_matrix_invert (&inverse);
  1035.     if (unlikely (status))
  1036.         return status;
  1037.  
  1038.     pdf_operators->text_matrix = *matrix;
  1039.     pdf_operators->cur_x = 0;
  1040.     pdf_operators->cur_y = 0;
  1041.     pdf_operators->glyph_buf_x_pos = 0;
  1042.     _cairo_output_stream_printf (pdf_operators->stream,
  1043.                                  "%f %f %f %f %f %f Tm\n",
  1044.                                  pdf_operators->text_matrix.xx,
  1045.                                  pdf_operators->text_matrix.yx,
  1046.                                  pdf_operators->text_matrix.xy,
  1047.                                  pdf_operators->text_matrix.yy,
  1048.                                  pdf_operators->text_matrix.x0,
  1049.                                  pdf_operators->text_matrix.y0);
  1050.  
  1051.     pdf_operators->cairo_to_pdftext = *matrix;
  1052.     status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
  1053.     assert (status == CAIRO_STATUS_SUCCESS);
  1054.     cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext,
  1055.                            &pdf_operators->cairo_to_pdf,
  1056.                            &pdf_operators->cairo_to_pdftext);
  1057.  
  1058.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1059. }
  1060.  
  1061. #define TEXT_MATRIX_TOLERANCE 1e-6
  1062.  
  1063. /* Set the translation components of the PDF text matrix to x, y. The
  1064.  * 'Td' operator is used to transform the text matrix.
  1065.  */
  1066. static cairo_status_t
  1067. _cairo_pdf_operators_set_text_position (cairo_pdf_operators_t  *pdf_operators,
  1068.                                         double                  x,
  1069.                                         double                  y)
  1070. {
  1071.     cairo_matrix_t translate, inverse;
  1072.     cairo_status_t status;
  1073.  
  1074.     /* The Td operator transforms the text_matrix with:
  1075.      *
  1076.      *   text_matrix' = T x text_matrix
  1077.      *
  1078.      * where T is a translation matrix with the translation components
  1079.      * set to the Td operands tx and ty.
  1080.      */
  1081.     inverse = pdf_operators->text_matrix;
  1082.     status = cairo_matrix_invert (&inverse);
  1083.     assert (status == CAIRO_STATUS_SUCCESS);
  1084.     pdf_operators->text_matrix.x0 = x;
  1085.     pdf_operators->text_matrix.y0 = y;
  1086.     cairo_matrix_multiply (&translate, &pdf_operators->text_matrix, &inverse);
  1087.     if (fabs(translate.x0) < TEXT_MATRIX_TOLERANCE)
  1088.         translate.x0 = 0.0;
  1089.     if (fabs(translate.y0) < TEXT_MATRIX_TOLERANCE)
  1090.         translate.y0 = 0.0;
  1091.     _cairo_output_stream_printf (pdf_operators->stream,
  1092.                                  "%f %f Td\n",
  1093.                                  translate.x0,
  1094.                                  translate.y0);
  1095.     pdf_operators->cur_x = 0;
  1096.     pdf_operators->cur_y = 0;
  1097.     pdf_operators->glyph_buf_x_pos = 0;
  1098.  
  1099.     pdf_operators->cairo_to_pdftext = pdf_operators->text_matrix;
  1100.     status = cairo_matrix_invert (&pdf_operators->cairo_to_pdftext);
  1101.     assert (status == CAIRO_STATUS_SUCCESS);
  1102.     cairo_matrix_multiply (&pdf_operators->cairo_to_pdftext,
  1103.                            &pdf_operators->cairo_to_pdf,
  1104.                            &pdf_operators->cairo_to_pdftext);
  1105.  
  1106.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1107. }
  1108.  
  1109. /* Select the font using the 'Tf' operator. The font size is set to 1
  1110.  * as we use the 'Tm' operator to set the font scale.
  1111.  */
  1112. static cairo_status_t
  1113. _cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t             *pdf_operators,
  1114.                                       cairo_scaled_font_subsets_glyph_t *subset_glyph)
  1115. {
  1116.     cairo_status_t status;
  1117.  
  1118.     _cairo_output_stream_printf (pdf_operators->stream,
  1119.                                  "/f-%d-%d 1 Tf\n",
  1120.                                  subset_glyph->font_id,
  1121.                                  subset_glyph->subset_id);
  1122.     if (pdf_operators->use_font_subset) {
  1123.         status = pdf_operators->use_font_subset (subset_glyph->font_id,
  1124.                                                  subset_glyph->subset_id,
  1125.                                                  pdf_operators->use_font_subset_closure);
  1126.         if (unlikely (status))
  1127.             return status;
  1128.     }
  1129.     pdf_operators->font_id = subset_glyph->font_id;
  1130.     pdf_operators->subset_id = subset_glyph->subset_id;
  1131.  
  1132.     if (subset_glyph->is_composite)
  1133.         pdf_operators->hex_width = 4;
  1134.     else
  1135.         pdf_operators->hex_width = 2;
  1136.  
  1137.     return CAIRO_STATUS_SUCCESS;
  1138. }
  1139.  
  1140. static cairo_status_t
  1141. _cairo_pdf_operators_begin_text (cairo_pdf_operators_t    *pdf_operators)
  1142. {
  1143.     _cairo_output_stream_printf (pdf_operators->stream, "BT\n");
  1144.  
  1145.     pdf_operators->in_text_object = TRUE;
  1146.     pdf_operators->num_glyphs = 0;
  1147.     pdf_operators->glyph_buf_x_pos = 0;
  1148.  
  1149.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1150. }
  1151.  
  1152. static cairo_status_t
  1153. _cairo_pdf_operators_end_text (cairo_pdf_operators_t    *pdf_operators)
  1154. {
  1155.     cairo_status_t status;
  1156.  
  1157.     status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1158.     if (unlikely (status))
  1159.         return status;
  1160.  
  1161.     _cairo_output_stream_printf (pdf_operators->stream, "ET\n");
  1162.  
  1163.     pdf_operators->in_text_object = FALSE;
  1164.  
  1165.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1166. }
  1167.  
  1168. /* Compare the scale components of two matrices. The translation
  1169.  * components are ignored. */
  1170. static cairo_bool_t
  1171. _cairo_matrix_scale_equal (cairo_matrix_t *a, cairo_matrix_t *b)
  1172. {
  1173.     return (a->xx == b->xx &&
  1174.             a->xy == b->xy &&
  1175.             a->yx == b->yx &&
  1176.             a->yy == b->yy);
  1177. }
  1178.  
  1179. static cairo_status_t
  1180. _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators,
  1181.                                        const char            *utf8,
  1182.                                        int                    utf8_len)
  1183. {
  1184.     uint16_t *utf16;
  1185.     int utf16_len;
  1186.     cairo_status_t status;
  1187.     int i;
  1188.  
  1189.     _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff");
  1190.     if (utf8_len) {
  1191.         status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len);
  1192.         if (unlikely (status))
  1193.             return status;
  1194.  
  1195.         for (i = 0; i < utf16_len; i++) {
  1196.             _cairo_output_stream_printf (pdf_operators->stream,
  1197.                                          "%04x", (int) (utf16[i]));
  1198.         }
  1199.         free (utf16);
  1200.     }
  1201.     _cairo_output_stream_printf (pdf_operators->stream, "> >> BDC\n");
  1202.  
  1203.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1204. }
  1205.  
  1206. static cairo_status_t
  1207. _cairo_pdf_operators_end_actualtext (cairo_pdf_operators_t    *pdf_operators)
  1208. {
  1209.     _cairo_output_stream_printf (pdf_operators->stream, "EMC\n");
  1210.  
  1211.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1212. }
  1213.  
  1214. static cairo_status_t
  1215. _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t             *pdf_operators,
  1216.                                  cairo_glyph_t                     *glyph,
  1217.                                  cairo_scaled_font_subsets_glyph_t *subset_glyph)
  1218. {
  1219.     double x, y;
  1220.     cairo_status_t status;
  1221.  
  1222.     if (pdf_operators->is_new_text_object ||
  1223.         pdf_operators->font_id != subset_glyph->font_id ||
  1224.         pdf_operators->subset_id != subset_glyph->subset_id)
  1225.     {
  1226.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1227.         if (unlikely (status))
  1228.             return status;
  1229.  
  1230.         status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph);
  1231.         if (unlikely (status))
  1232.             return status;
  1233.  
  1234.         pdf_operators->is_new_text_object = FALSE;
  1235.     }
  1236.  
  1237.     x = glyph->x;
  1238.     y = glyph->y;
  1239.     cairo_matrix_transform_point (&pdf_operators->cairo_to_pdftext, &x, &y);
  1240.  
  1241.     /* The TJ operator for displaying text strings can only set
  1242.      * the horizontal position of the glyphs. If the y position
  1243.      * (in text space) changes, use the Td operator to change the
  1244.      * current position to the next glyph. We also use the Td
  1245.      * operator to move the current position if the horizontal
  1246.      * position changes by more than 10 (in text space
  1247.      * units). This is becauses the horizontal glyph positioning
  1248.      * in the TJ operator is intended for kerning and there may be
  1249.      * PDF consumers that do not handle very large position
  1250.      * adjustments in TJ.
  1251.      */
  1252.     if (fabs(x - pdf_operators->glyph_buf_x_pos) > 10 ||
  1253.         fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE)
  1254.     {
  1255.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1256.         if (unlikely (status))
  1257.             return status;
  1258.  
  1259.         x = glyph->x;
  1260.         y = glyph->y;
  1261.         cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
  1262.         status = _cairo_pdf_operators_set_text_position (pdf_operators, x, y);
  1263.         if (unlikely (status))
  1264.             return status;
  1265.  
  1266.         x = 0.0;
  1267.         y = 0.0;
  1268.     }
  1269.  
  1270.     status = _cairo_pdf_operators_add_glyph (pdf_operators,
  1271.                                              subset_glyph,
  1272.                                              x);
  1273.     return status;
  1274. }
  1275.  
  1276. /* A utf8_len of -1 indicates no unicode text. A utf8_len = 0 is an
  1277.  * empty string.
  1278.  */
  1279. static cairo_int_status_t
  1280. _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t      *pdf_operators,
  1281.                                    const char                 *utf8,
  1282.                                    int                         utf8_len,
  1283.                                    cairo_glyph_t              *glyphs,
  1284.                                    int                         num_glyphs,
  1285.                                    cairo_text_cluster_flags_t  cluster_flags,
  1286.                                    cairo_scaled_font_t        *scaled_font)
  1287. {
  1288.     cairo_scaled_font_subsets_glyph_t subset_glyph;
  1289.     cairo_glyph_t *cur_glyph;
  1290.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  1291.     int i;
  1292.  
  1293.     /* If the cluster maps 1 glyph to 1 or more unicode characters, we
  1294.      * first try _map_glyph() with the unicode string to see if it can
  1295.      * use toUnicode to map our glyph to the unicode. This will fail
  1296.      * if the glyph is already mapped to a different unicode string.
  1297.      *
  1298.      * We also go through this path if no unicode mapping was
  1299.      * supplied (utf8_len < 0).
  1300.      *
  1301.      * Mapping a glyph to a zero length unicode string requires the
  1302.      * use of ActualText.
  1303.      */
  1304.     if (num_glyphs == 1 && utf8_len != 0) {
  1305.         status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
  1306.                                                        scaled_font,
  1307.                                                        glyphs->index,
  1308.                                                        utf8,
  1309.                                                        utf8_len,
  1310.                                                        &subset_glyph);
  1311.         if (unlikely (status))
  1312.             return status;
  1313.  
  1314.         if (subset_glyph.utf8_is_mapped || utf8_len < 0) {
  1315.             status = _cairo_pdf_operators_emit_glyph (pdf_operators,
  1316.                                                       glyphs,
  1317.                                                       &subset_glyph);
  1318.             if (unlikely (status))
  1319.                 return status;
  1320.  
  1321.             return CAIRO_STATUS_SUCCESS;
  1322.         }
  1323.     }
  1324.  
  1325.     if (pdf_operators->use_actual_text) {
  1326.         /* Fallback to using ActualText to map zero or more glyphs to a
  1327.          * unicode string. */
  1328.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1329.         if (unlikely (status))
  1330.             return status;
  1331.  
  1332.         status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len);
  1333.         if (unlikely (status))
  1334.             return status;
  1335.     }
  1336.  
  1337.     cur_glyph = glyphs;
  1338.     /* XXX
  1339.      * If no glyphs, we should put *something* here for the text to be selectable. */
  1340.     for (i = 0; i < num_glyphs; i++) {
  1341.         status = _cairo_scaled_font_subsets_map_glyph (pdf_operators->font_subsets,
  1342.                                                        scaled_font,
  1343.                                                        cur_glyph->index,
  1344.                                                        NULL, -1,
  1345.                                                        &subset_glyph);
  1346.         if (unlikely (status))
  1347.             return status;
  1348.  
  1349.         status = _cairo_pdf_operators_emit_glyph (pdf_operators,
  1350.                                                   cur_glyph,
  1351.                                                   &subset_glyph);
  1352.         if (unlikely (status))
  1353.             return status;
  1354.  
  1355.         if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1356.             cur_glyph--;
  1357.         else
  1358.             cur_glyph++;
  1359.     }
  1360.  
  1361.     if (pdf_operators->use_actual_text) {
  1362.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1363.         if (unlikely (status))
  1364.             return status;
  1365.  
  1366.         status = _cairo_pdf_operators_end_actualtext (pdf_operators);
  1367.     }
  1368.  
  1369.     return status;
  1370. }
  1371.  
  1372. cairo_int_status_t
  1373. _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t      *pdf_operators,
  1374.                                        const char                 *utf8,
  1375.                                        int                         utf8_len,
  1376.                                        cairo_glyph_t              *glyphs,
  1377.                                        int                         num_glyphs,
  1378.                                        const cairo_text_cluster_t *clusters,
  1379.                                        int                         num_clusters,
  1380.                                        cairo_text_cluster_flags_t  cluster_flags,
  1381.                                        cairo_scaled_font_t        *scaled_font)
  1382. {
  1383.     cairo_status_t status;
  1384.     int i;
  1385.     cairo_matrix_t text_matrix, invert_y_axis;
  1386.     double x, y;
  1387.     const char *cur_text;
  1388.     cairo_glyph_t *cur_glyph;
  1389.  
  1390.     pdf_operators->font_matrix_inverse = scaled_font->font_matrix;
  1391.     status = cairo_matrix_invert (&pdf_operators->font_matrix_inverse);
  1392.     if (status == CAIRO_STATUS_INVALID_MATRIX)
  1393.         return CAIRO_STATUS_SUCCESS;
  1394.     assert (status == CAIRO_STATUS_SUCCESS);
  1395.  
  1396.     pdf_operators->is_new_text_object = FALSE;
  1397.     if (pdf_operators->in_text_object == FALSE) {
  1398.         status = _cairo_pdf_operators_begin_text (pdf_operators);
  1399.         if (unlikely (status))
  1400.             return status;
  1401.  
  1402.         /* Force Tm and Tf to be emitted when starting a new text
  1403.          * object.*/
  1404.         pdf_operators->is_new_text_object = TRUE;
  1405.     }
  1406.  
  1407.     cairo_matrix_init_scale (&invert_y_axis, 1, -1);
  1408.     text_matrix = scaled_font->scale;
  1409.  
  1410.     /* Invert y axis in font space  */
  1411.     cairo_matrix_multiply (&text_matrix, &text_matrix, &invert_y_axis);
  1412.  
  1413.     /* Invert y axis in device space  */
  1414.     cairo_matrix_multiply (&text_matrix, &invert_y_axis, &text_matrix);
  1415.  
  1416.     if (pdf_operators->is_new_text_object ||
  1417.         ! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix))
  1418.     {
  1419.         status = _cairo_pdf_operators_flush_glyphs (pdf_operators);
  1420.         if (unlikely (status))
  1421.             return status;
  1422.  
  1423.         x = glyphs[0].x;
  1424.         y = glyphs[0].y;
  1425.         cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y);
  1426.         text_matrix.x0 = x;
  1427.         text_matrix.y0 = y;
  1428.         status = _cairo_pdf_operators_set_text_matrix (pdf_operators, &text_matrix);
  1429.         if (status == CAIRO_STATUS_INVALID_MATRIX)
  1430.             return CAIRO_STATUS_SUCCESS;
  1431.         if (unlikely (status))
  1432.             return status;
  1433.     }
  1434.  
  1435.     if (num_clusters > 0) {
  1436.         cur_text = utf8;
  1437.         if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1438.             cur_glyph = glyphs + num_glyphs;
  1439.         else
  1440.             cur_glyph = glyphs;
  1441.         for (i = 0; i < num_clusters; i++) {
  1442.             if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1443.                 cur_glyph -= clusters[i].num_glyphs;
  1444.             status = _cairo_pdf_operators_emit_cluster (pdf_operators,
  1445.                                                         cur_text,
  1446.                                                         clusters[i].num_bytes,
  1447.                                                         cur_glyph,
  1448.                                                         clusters[i].num_glyphs,
  1449.                                                         cluster_flags,
  1450.                                                         scaled_font);
  1451.             if (unlikely (status))
  1452.                 return status;
  1453.  
  1454.             cur_text += clusters[i].num_bytes;
  1455.             if (!(cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD))
  1456.                 cur_glyph += clusters[i].num_glyphs;
  1457.         }
  1458.     } else {
  1459.         for (i = 0; i < num_glyphs; i++) {
  1460.             status = _cairo_pdf_operators_emit_cluster (pdf_operators,
  1461.                                                         NULL,
  1462.                                                         -1, /* no unicode string available */
  1463.                                                         &glyphs[i],
  1464.                                                         1,
  1465.                                                         FALSE,
  1466.                                                         scaled_font);
  1467.             if (unlikely (status))
  1468.                 return status;
  1469.         }
  1470.     }
  1471.  
  1472.     return _cairo_output_stream_get_status (pdf_operators->stream);
  1473. }
  1474.  
  1475. #endif /* CAIRO_HAS_PDF_OPERATORS */
  1476.