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 © 2006 Adrian Johnson
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it either under the terms of the GNU Lesser General Public
  8.  * License version 2.1 as published by the Free Software Foundation
  9.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  10.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  11.  * notice, a recipient may use your version of this file under either
  12.  * the MPL or the LGPL.
  13.  *
  14.  * You should have received a copy of the LGPL along with this library
  15.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  16.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  17.  * You should have received a copy of the MPL along with this library
  18.  * in the file COPYING-MPL-1.1
  19.  *
  20.  * The contents of this file are subject to the Mozilla Public License
  21.  * Version 1.1 (the "License"); you may not use this file except in
  22.  * compliance with the License. You may obtain a copy of the License at
  23.  * http://www.mozilla.org/MPL/
  24.  *
  25.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  26.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  27.  * the specific language governing rights and limitations.
  28.  *
  29.  * The Original Code is the cairo graphics library.
  30.  *
  31.  * The Initial Developer of the Original Code is Adrian Johnson.
  32.  *
  33.  * Contributor(s):
  34.  *      Adrian Johnson <ajohnson@redneon.com>
  35.  *      Eugeniy Meshcheryakov <eugen@debian.org>
  36.  */
  37.  
  38. /*
  39.  * Useful links:
  40.  * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf
  41.  * http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5177.Type2.pdf
  42.  */
  43.  
  44. #define _BSD_SOURCE /* for snprintf(), strdup() */
  45. #include "cairoint.h"
  46.  
  47. #include "cairo-array-private.h"
  48. #include "cairo-error-private.h"
  49.  
  50. #if CAIRO_HAS_FONT_SUBSET
  51.  
  52. #include "cairo-scaled-font-subsets-private.h"
  53. #include "cairo-truetype-subset-private.h"
  54. #include <string.h>
  55. #include <locale.h>
  56.  
  57. /* CFF Dict Operators. If the high byte is 0 the command is encoded
  58.  * with a single byte. */
  59. #define BASEFONTNAME_OP  0x0c16
  60. #define CIDCOUNT_OP      0x0c22
  61. #define CHARSET_OP       0x000f
  62. #define CHARSTRINGS_OP   0x0011
  63. #define COPYRIGHT_OP     0x0c00
  64. #define DEFAULTWIDTH_OP  0x0014
  65. #define ENCODING_OP      0x0010
  66. #define FAMILYNAME_OP    0x0003
  67. #define FDARRAY_OP       0x0c24
  68. #define FDSELECT_OP      0x0c25
  69. #define FONTBBOX_OP      0x0005
  70. #define FONTMATRIX_OP    0x0c07
  71. #define FONTNAME_OP      0x0c26
  72. #define FULLNAME_OP      0x0002
  73. #define LOCAL_SUB_OP     0x0013
  74. #define NOMINALWIDTH_OP  0x0015
  75. #define NOTICE_OP        0x0001
  76. #define POSTSCRIPT_OP    0x0c15
  77. #define PRIVATE_OP       0x0012
  78. #define ROS_OP           0x0c1e
  79. #define UNIQUEID_OP      0x000d
  80. #define VERSION_OP       0x0000
  81. #define WEIGHT_OP        0x0004
  82. #define XUID_OP          0x000e
  83.  
  84. #define NUM_STD_STRINGS 391
  85.  
  86. /* Type 2 Charstring operators */
  87. #define TYPE2_hstem     0x0001
  88. #define TYPE2_vstem     0x0003
  89. #define TYPE2_callsubr  0x000a
  90.  
  91. #define TYPE2_return    0x000b
  92. #define TYPE2_endchar   0x000e
  93.  
  94. #define TYPE2_hstemhm   0x0012
  95. #define TYPE2_hintmask  0x0013
  96. #define TYPE2_cntrmask  0x0014
  97. #define TYPE2_vstemhm   0x0017
  98. #define TYPE2_callgsubr 0x001d
  99.  
  100. #define TYPE2_rmoveto   0x0015
  101. #define TYPE2_hmoveto   0x0016
  102. #define TYPE2_vmoveto   0x0004
  103.  
  104.  
  105. #define MAX_SUBROUTINE_NESTING 10 /* From Type2 Charstring spec */
  106.  
  107.  
  108. typedef struct _cff_header {
  109.     uint8_t major;
  110.     uint8_t minor;
  111.     uint8_t header_size;
  112.     uint8_t offset_size;
  113. } cff_header_t;
  114.  
  115. typedef struct _cff_index_element {
  116.     cairo_bool_t   is_copy;
  117.     unsigned char *data;
  118.     int            length;
  119. } cff_index_element_t;
  120.  
  121. typedef struct _cff_dict_operator {
  122.     cairo_hash_entry_t base;
  123.  
  124.     unsigned short operator;
  125.     unsigned char *operand;
  126.     int            operand_length;
  127.     int            operand_offset;
  128. } cff_dict_operator_t;
  129.  
  130. typedef struct _cairo_cff_font {
  131.  
  132.     cairo_scaled_font_subset_t *scaled_font_subset;
  133.     const cairo_scaled_font_backend_t *backend;
  134.  
  135.     /* Font Data */
  136.     unsigned char       *data;
  137.     unsigned long        data_length;
  138.     unsigned char       *current_ptr;
  139.     unsigned char       *data_end;
  140.     cff_header_t        *header;
  141.     char                *font_name;
  142.     char                *ps_name;
  143.     cairo_hash_table_t  *top_dict;
  144.     cairo_hash_table_t  *private_dict;
  145.     cairo_array_t        strings_index;
  146.     cairo_array_t        charstrings_index;
  147.     cairo_array_t        global_sub_index;
  148.     cairo_array_t        local_sub_index;
  149.     unsigned char       *charset;
  150.     int                  num_glyphs;
  151.     cairo_bool_t         is_cid;
  152.     cairo_bool_t         is_opentype;
  153.     int                  units_per_em;
  154.     int                  global_sub_bias;
  155.     int                  local_sub_bias;
  156.     double               default_width;
  157.     double               nominal_width;
  158.  
  159.     /* CID Font Data */
  160.     int                 *fdselect;
  161.     unsigned int         num_fontdicts;
  162.     cairo_hash_table_t **fd_dict;
  163.     cairo_hash_table_t **fd_private_dict;
  164.     cairo_array_t       *fd_local_sub_index;
  165.     int                 *fd_local_sub_bias;
  166.     double              *fd_default_width;
  167.     double              *fd_nominal_width;
  168.  
  169.     /* Subsetted Font Data */
  170.     char                *subset_font_name;
  171.     cairo_array_t        charstrings_subset_index;
  172.     cairo_array_t        strings_subset_index;
  173.     int                  euro_sid;
  174.     int                 *fdselect_subset;
  175.     unsigned int         num_subset_fontdicts;
  176.     int                 *fd_subset_map;
  177.     int                 *private_dict_offset;
  178.     cairo_bool_t         subset_subroutines;
  179.     cairo_bool_t        *global_subs_used;
  180.     cairo_bool_t        *local_subs_used;
  181.     cairo_bool_t       **fd_local_subs_used;
  182.     cairo_array_t        output;
  183.  
  184.     /* Subset Metrics */
  185.     int                 *widths;
  186.     int                  x_min, y_min, x_max, y_max;
  187.     int                  ascent, descent;
  188.  
  189.     /* Type 2 charstring data */
  190.     int                  type2_stack_size;
  191.     int                  type2_stack_top_value;
  192.     cairo_bool_t         type2_stack_top_is_int;
  193.     int                  type2_num_hints;
  194.     int                  type2_hintmask_bytes;
  195.     int                  type2_nesting_level;
  196.     cairo_bool_t         type2_seen_first_int;
  197.     cairo_bool_t         type2_find_width;
  198.     cairo_bool_t         type2_found_width;
  199.     int                  type2_width;
  200.     cairo_bool_t         type2_has_path;
  201.  
  202. } cairo_cff_font_t;
  203.  
  204. /* Encoded integer using maximum sized encoding. This is required for
  205.  * operands that are later modified after encoding. */
  206. static unsigned char *
  207. encode_integer_max (unsigned char *p, int i)
  208. {
  209.     *p++ = 29;
  210.     *p++ = i >> 24;
  211.     *p++ = (i >> 16) & 0xff;
  212.     *p++ = (i >> 8)  & 0xff;
  213.     *p++ = i & 0xff;
  214.     return p;
  215. }
  216.  
  217. static unsigned char *
  218. encode_integer (unsigned char *p, int i)
  219. {
  220.     if (i >= -107 && i <= 107) {
  221.         *p++ = i + 139;
  222.     } else if (i >= 108 && i <= 1131) {
  223.         i -= 108;
  224.         *p++ = (i >> 8)+ 247;
  225.         *p++ = i & 0xff;
  226.     } else if (i >= -1131 && i <= -108) {
  227.         i = -i - 108;
  228.         *p++ = (i >> 8)+ 251;
  229.         *p++ = i & 0xff;
  230.     } else if (i >= -32768 && i <= 32767) {
  231.         *p++ = 28;
  232.         *p++ = (i >> 8)  & 0xff;
  233.         *p++ = i & 0xff;
  234.     } else {
  235.         p = encode_integer_max (p, i);
  236.     }
  237.     return p;
  238. }
  239.  
  240. static unsigned char *
  241. decode_integer (unsigned char *p, int *integer)
  242. {
  243.     if (*p == 28) {
  244.         *integer = (int)(p[1]<<8 | p[2]);
  245.         p += 3;
  246.     } else if (*p == 29) {
  247.         *integer = (int)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]);
  248.         p += 5;
  249.     } else if (*p >= 32 && *p <= 246) {
  250.         *integer = *p++ - 139;
  251.     } else if (*p <= 250) {
  252.         *integer = (p[0] - 247) * 256 + p[1] + 108;
  253.         p += 2;
  254.     } else if (*p <= 254) {
  255.         *integer = -(p[0] - 251) * 256 - p[1] - 108;
  256.         p += 2;
  257.     } else {
  258.         *integer = 0;
  259.         p += 1;
  260.     }
  261.     return p;
  262. }
  263.  
  264. static char *
  265. decode_nibble (int n, char *buf)
  266. {
  267.     switch (n)
  268.     {
  269.     case 0xa:
  270.         *buf++ = '.';
  271.         break;
  272.     case 0xb:
  273.         *buf++ = 'E';
  274.         break;
  275.     case 0xc:
  276.         *buf++ = 'E';
  277.         *buf++ = '-';
  278.         break;
  279.     case 0xd:
  280.         *buf++ = '-';
  281.         break;
  282.     case 0xe:
  283.         *buf++ = '-';
  284.         break;
  285.     case 0xf:
  286.         break;
  287.     default:
  288.         *buf++ = '0' + n;
  289.         break;
  290.     }
  291.  
  292.     return buf;
  293. }
  294.  
  295. static unsigned char *
  296. decode_real (unsigned char *p, double *real)
  297. {
  298.     struct lconv *locale_data;
  299.     const char *decimal_point;
  300.     int decimal_point_len;
  301.     int n;
  302.     char buffer[100];
  303.     char buffer2[200];
  304.     char *q;
  305.     char *buf = buffer;
  306.     char *buf_end = buffer + sizeof (buffer);
  307.  
  308.     locale_data = localeconv ();
  309.     decimal_point = locale_data->decimal_point;
  310.     decimal_point_len = strlen (decimal_point);
  311.  
  312.     assert (decimal_point_len != 0);
  313.     assert (sizeof(buffer) + decimal_point_len < sizeof(buffer2));
  314.  
  315.     p++;
  316.     while (buf + 2 < buf_end) {
  317.         n = *p >> 4;
  318.         buf = decode_nibble (n, buf);
  319.         n = *p & 0x0f;
  320.         buf = decode_nibble (n, buf);
  321.         if ((*p & 0x0f) == 0x0f) {
  322.             p++;
  323.             break;
  324.         }
  325.         p++;
  326.     };
  327.     *buf = 0;
  328.  
  329.     buf = buffer;
  330.     if (strchr (buffer, '.')) {
  331.          q = strchr (buffer, '.');
  332.          strncpy (buffer2, buffer, q - buffer);
  333.          buf = buffer2 + (q - buffer);
  334.          strncpy (buf, decimal_point, decimal_point_len);
  335.          buf += decimal_point_len;
  336.          strcpy (buf, q + 1);
  337.          buf = buffer2;
  338.     }
  339.  
  340.     if (sscanf(buf, "%lf", real) != 1)
  341.         *real = 0.0;
  342.  
  343.     return p;
  344. }
  345.  
  346. static unsigned char *
  347. decode_number (unsigned char *p, double *number)
  348. {
  349.     if (*p == 30) {
  350.         p = decode_real (p, number);
  351.     } else {
  352.         int i;
  353.         p = decode_integer (p, &i);
  354.         *number = i;
  355.     }
  356.     return p;
  357. }
  358.  
  359. static unsigned char *
  360. decode_operator (unsigned char *p, unsigned short *operator)
  361. {
  362.     unsigned short op = 0;
  363.  
  364.     op = *p++;
  365.     if (op == 12) {
  366.         op <<= 8;
  367.         op |= *p++;
  368.     }
  369.     *operator = op;
  370.     return p;
  371. }
  372.  
  373. /* return 0 if not an operand */
  374. static int
  375. operand_length (unsigned char *p)
  376. {
  377.     unsigned char *begin = p;
  378.  
  379.     if (*p == 28)
  380.         return 3;
  381.  
  382.     if (*p == 29)
  383.         return 5;
  384.  
  385.     if (*p >= 32 && *p <= 246)
  386.         return 1;
  387.  
  388.     if (*p >= 247 && *p <= 254)
  389.         return 2;
  390.  
  391.     if (*p == 30) {
  392.         while ((*p & 0x0f) != 0x0f)
  393.             p++;
  394.         return p - begin + 1;
  395.     }
  396.  
  397.     return 0;
  398. }
  399.  
  400. static unsigned char *
  401. encode_index_offset (unsigned char *p, int offset_size, unsigned long offset)
  402. {
  403.     while (--offset_size >= 0) {
  404.         p[offset_size] = (unsigned char) (offset & 0xff);
  405.         offset >>= 8;
  406.     }
  407.     return p + offset_size;
  408. }
  409.  
  410. static unsigned long
  411. decode_index_offset(unsigned char *p, int off_size)
  412. {
  413.     unsigned long offset = 0;
  414.  
  415.     while (off_size-- > 0)
  416.         offset = offset*256 + *p++;
  417.     return offset;
  418. }
  419.  
  420. static void
  421. cff_index_init (cairo_array_t *index)
  422. {
  423.     _cairo_array_init (index, sizeof (cff_index_element_t));
  424. }
  425.  
  426. static cairo_int_status_t
  427. cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_ptr)
  428. {
  429.     cff_index_element_t element;
  430.     unsigned char *data, *p;
  431.     cairo_status_t status;
  432.     int offset_size, count, start, i;
  433.     int end = 0;
  434.  
  435.     p = *ptr;
  436.     if (p + 2 > end_ptr)
  437.         return CAIRO_INT_STATUS_UNSUPPORTED;
  438.     count = be16_to_cpu( *((uint16_t *)p) );
  439.     p += 2;
  440.     if (count > 0) {
  441.         offset_size = *p++;
  442.         if (p + (count + 1)*offset_size > end_ptr)
  443.             return CAIRO_INT_STATUS_UNSUPPORTED;
  444.         data = p + offset_size*(count + 1) - 1;
  445.         start = decode_index_offset (p, offset_size);
  446.         p += offset_size;
  447.         for (i = 0; i < count; i++) {
  448.             end = decode_index_offset (p, offset_size);
  449.             p += offset_size;
  450.             if (p > end_ptr)
  451.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  452.             element.length = end - start;
  453.             element.is_copy = FALSE;
  454.             element.data = data + start;
  455.             status = _cairo_array_append (index, &element);
  456.             if (unlikely (status))
  457.                 return status;
  458.             start = end;
  459.         }
  460.         p = data + end;
  461.     }
  462.     *ptr = p;
  463.  
  464.     return CAIRO_STATUS_SUCCESS;
  465. }
  466.  
  467. static cairo_status_t
  468. cff_index_write (cairo_array_t *index, cairo_array_t *output)
  469. {
  470.     int offset_size;
  471.     int offset;
  472.     int num_elem;
  473.     int i;
  474.     cff_index_element_t *element;
  475.     uint16_t count;
  476.     unsigned char buf[5];
  477.     cairo_status_t status;
  478.  
  479.     num_elem = _cairo_array_num_elements (index);
  480.     count = cpu_to_be16 ((uint16_t) num_elem);
  481.     status = _cairo_array_append_multiple (output, &count, 2);
  482.     if (unlikely (status))
  483.         return status;
  484.  
  485.     if (num_elem == 0)
  486.         return CAIRO_STATUS_SUCCESS;
  487.  
  488.     /* Find maximum offset to determine offset size */
  489.     offset = 1;
  490.     for (i = 0; i < num_elem; i++) {
  491.         element = _cairo_array_index (index, i);
  492.         offset += element->length;
  493.     }
  494.     if (offset < 0x100)
  495.         offset_size = 1;
  496.     else if (offset < 0x10000)
  497.         offset_size = 2;
  498.     else if (offset < 0x1000000)
  499.         offset_size = 3;
  500.     else
  501.         offset_size = 4;
  502.  
  503.     buf[0] = (unsigned char) offset_size;
  504.     status = _cairo_array_append (output, buf);
  505.     if (unlikely (status))
  506.         return status;
  507.  
  508.     offset = 1;
  509.     encode_index_offset (buf, offset_size, offset);
  510.     status = _cairo_array_append_multiple (output, buf, offset_size);
  511.     if (unlikely (status))
  512.         return status;
  513.  
  514.     for (i = 0; i < num_elem; i++) {
  515.         element = _cairo_array_index (index, i);
  516.         offset += element->length;
  517.         encode_index_offset (buf, offset_size, offset);
  518.         status = _cairo_array_append_multiple (output, buf, offset_size);
  519.         if (unlikely (status))
  520.             return status;
  521.     }
  522.  
  523.     for (i = 0; i < num_elem; i++) {
  524.         element = _cairo_array_index (index, i);
  525.         if (element->length > 0) {
  526.             status = _cairo_array_append_multiple (output,
  527.                                                    element->data,
  528.                                                    element->length);
  529.         }
  530.         if (unlikely (status))
  531.             return status;
  532.     }
  533.     return CAIRO_STATUS_SUCCESS;
  534. }
  535.  
  536. static void
  537. cff_index_set_object (cairo_array_t *index, int obj_index,
  538.                       unsigned char *object , int length)
  539. {
  540.     cff_index_element_t *element;
  541.  
  542.     element = _cairo_array_index (index, obj_index);
  543.     if (element->is_copy)
  544.         free (element->data);
  545.  
  546.     element->data = object;
  547.     element->length = length;
  548.     element->is_copy = FALSE;
  549. }
  550.  
  551. static cairo_status_t
  552. cff_index_append (cairo_array_t *index, unsigned char *object , int length)
  553. {
  554.     cff_index_element_t element;
  555.  
  556.     element.length = length;
  557.     element.is_copy = FALSE;
  558.     element.data = object;
  559.  
  560.     return _cairo_array_append (index, &element);
  561. }
  562.  
  563. static cairo_status_t
  564. cff_index_append_copy (cairo_array_t *index,
  565.                        const unsigned char *object,
  566.                        unsigned int length)
  567. {
  568.     cff_index_element_t element;
  569.     cairo_status_t status;
  570.  
  571.     element.length = length;
  572.     element.is_copy = TRUE;
  573.     element.data = malloc (element.length);
  574.     if (unlikely (element.data == NULL))
  575.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  576.  
  577.     memcpy (element.data, object, element.length);
  578.  
  579.     status = _cairo_array_append (index, &element);
  580.     if (unlikely (status)) {
  581.         free (element.data);
  582.         return status;
  583.     }
  584.  
  585.     return CAIRO_STATUS_SUCCESS;
  586. }
  587.  
  588. static void
  589. cff_index_fini (cairo_array_t *index)
  590. {
  591.     cff_index_element_t *element;
  592.     unsigned int i;
  593.  
  594.     for (i = 0; i < _cairo_array_num_elements (index); i++) {
  595.         element = _cairo_array_index (index, i);
  596.         if (element->is_copy && element->data)
  597.             free (element->data);
  598.     }
  599.     _cairo_array_fini (index);
  600. }
  601.  
  602. static cairo_bool_t
  603. _cairo_cff_dict_equal (const void *key_a, const void *key_b)
  604. {
  605.     const cff_dict_operator_t *op_a = key_a;
  606.     const cff_dict_operator_t *op_b = key_b;
  607.  
  608.     return op_a->operator == op_b->operator;
  609. }
  610.  
  611. static cairo_status_t
  612. cff_dict_init (cairo_hash_table_t **dict)
  613. {
  614.     *dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
  615.     if (unlikely (*dict == NULL))
  616.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  617.  
  618.     return CAIRO_STATUS_SUCCESS;
  619. }
  620.  
  621. static void
  622. _cairo_dict_init_key (cff_dict_operator_t *key, int operator)
  623. {
  624.     key->base.hash = (unsigned long) operator;
  625.     key->operator = operator;
  626. }
  627.  
  628. static cairo_status_t
  629. cff_dict_create_operator (int            operator,
  630.                           unsigned char *operand,
  631.                           int            size,
  632.                           cff_dict_operator_t **out)
  633. {
  634.     cff_dict_operator_t *op;
  635.  
  636.     op = malloc (sizeof (cff_dict_operator_t));
  637.     if (unlikely (op == NULL))
  638.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  639.  
  640.     _cairo_dict_init_key (op, operator);
  641.     op->operand = malloc (size);
  642.     if (unlikely (op->operand == NULL)) {
  643.         free (op);
  644.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  645.     }
  646.  
  647.     memcpy (op->operand, operand, size);
  648.     op->operand_length = size;
  649.     op->operand_offset = -1;
  650.  
  651.     *out = op;
  652.     return CAIRO_STATUS_SUCCESS;
  653. }
  654.  
  655. static cairo_status_t
  656. cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
  657. {
  658.     unsigned char *end;
  659.     cairo_array_t operands;
  660.     cff_dict_operator_t *op;
  661.     unsigned short operator;
  662.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  663.     int size;
  664.  
  665.     end = p + dict_size;
  666.     _cairo_array_init (&operands, 1);
  667.     while (p < end) {
  668.         size = operand_length (p);
  669.         if (size != 0) {
  670.             status = _cairo_array_append_multiple (&operands, p, size);
  671.             if (unlikely (status))
  672.                 goto fail;
  673.  
  674.             p += size;
  675.         } else {
  676.             p = decode_operator (p, &operator);
  677.             status = cff_dict_create_operator (operator,
  678.                                           _cairo_array_index (&operands, 0),
  679.                                           _cairo_array_num_elements (&operands),
  680.                                           &op);
  681.             if (unlikely (status))
  682.                 goto fail;
  683.  
  684.             status = _cairo_hash_table_insert (dict, &op->base);
  685.             if (unlikely (status))
  686.                 goto fail;
  687.  
  688.             _cairo_array_truncate (&operands, 0);
  689.         }
  690.     }
  691.  
  692. fail:
  693.     _cairo_array_fini (&operands);
  694.  
  695.     return status;
  696. }
  697.  
  698. static void
  699. cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
  700. {
  701.     cff_dict_operator_t key, *op;
  702.  
  703.     _cairo_dict_init_key (&key, operator);
  704.     op = _cairo_hash_table_lookup (dict, &key.base);
  705.     if (op != NULL) {
  706.         free (op->operand);
  707.         _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
  708.         free (op);
  709.     }
  710. }
  711.  
  712. static unsigned char *
  713. cff_dict_get_operands (cairo_hash_table_t *dict,
  714.                        unsigned short      operator,
  715.                        int                *size)
  716. {
  717.     cff_dict_operator_t key, *op;
  718.  
  719.     _cairo_dict_init_key (&key, operator);
  720.     op = _cairo_hash_table_lookup (dict, &key.base);
  721.     if (op != NULL) {
  722.         *size = op->operand_length;
  723.         return op->operand;
  724.     }
  725.  
  726.     return NULL;
  727. }
  728.  
  729. static cairo_status_t
  730. cff_dict_set_operands (cairo_hash_table_t *dict,
  731.                        unsigned short      operator,
  732.                        unsigned char      *operand,
  733.                        int                 size)
  734. {
  735.     cff_dict_operator_t key, *op;
  736.     cairo_status_t status;
  737.  
  738.     _cairo_dict_init_key (&key, operator);
  739.     op = _cairo_hash_table_lookup (dict, &key.base);
  740.     if (op != NULL) {
  741.         free (op->operand);
  742.         op->operand = malloc (size);
  743.         if (unlikely (op->operand == NULL))
  744.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  745.  
  746.         memcpy (op->operand, operand, size);
  747.         op->operand_length = size;
  748.     }
  749.     else
  750.     {
  751.         status = cff_dict_create_operator (operator, operand, size, &op);
  752.         if (unlikely (status))
  753.             return status;
  754.  
  755.         status = _cairo_hash_table_insert (dict, &op->base);
  756.         if (unlikely (status))
  757.             return status;
  758.     }
  759.  
  760.     return CAIRO_STATUS_SUCCESS;
  761. }
  762.  
  763. static int
  764. cff_dict_get_location (cairo_hash_table_t *dict,
  765.                        unsigned short      operator,
  766.                        int                *size)
  767. {
  768.     cff_dict_operator_t key, *op;
  769.  
  770.     _cairo_dict_init_key (&key, operator);
  771.     op = _cairo_hash_table_lookup (dict, &key.base);
  772.     if (op != NULL) {
  773.         *size = op->operand_length;
  774.         return op->operand_offset;
  775.     }
  776.  
  777.     return -1;
  778. }
  779.  
  780. typedef struct _dict_write_info {
  781.     cairo_array_t *output;
  782.     cairo_status_t status;
  783. } dict_write_info_t;
  784.  
  785. static void
  786. cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
  787. {
  788.     unsigned char data;
  789.  
  790.     op->operand_offset = _cairo_array_num_elements (write_info->output);
  791.     write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length);
  792.     if (write_info->status)
  793.         return;
  794.  
  795.     if (op->operator & 0xff00) {
  796.         data = op->operator >> 8;
  797.         write_info->status = _cairo_array_append (write_info->output, &data);
  798.         if (write_info->status)
  799.             return;
  800.     }
  801.     data = op->operator & 0xff;
  802.     write_info->status = _cairo_array_append (write_info->output, &data);
  803. }
  804.  
  805. static void
  806. _cairo_dict_collect (void *entry, void *closure)
  807. {
  808.     dict_write_info_t   *write_info = closure;
  809.     cff_dict_operator_t *op = entry;
  810.  
  811.     if (write_info->status)
  812.         return;
  813.  
  814.     /* The ROS operator is handled separately in cff_dict_write() */
  815.     if (op->operator != ROS_OP)
  816.         cairo_dict_write_operator (op, write_info);
  817. }
  818.  
  819. static cairo_status_t
  820. cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
  821. {
  822.     dict_write_info_t write_info;
  823.     cff_dict_operator_t key, *op;
  824.  
  825.     write_info.output = output;
  826.     write_info.status = CAIRO_STATUS_SUCCESS;
  827.  
  828.     /* The CFF specification requires that the Top Dict of CID fonts
  829.      * begin with the ROS operator. */
  830.     _cairo_dict_init_key (&key, ROS_OP);
  831.     op = _cairo_hash_table_lookup (dict, &key.base);
  832.     if (op != NULL)
  833.         cairo_dict_write_operator (op, &write_info);
  834.  
  835.     _cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
  836.  
  837.     return write_info.status;
  838. }
  839.  
  840. static void
  841. _cff_dict_entry_pluck (void *_entry, void *dict)
  842. {
  843.     cff_dict_operator_t *entry = _entry;
  844.  
  845.     _cairo_hash_table_remove (dict, &entry->base);
  846.     free (entry->operand);
  847.     free (entry);
  848. }
  849.  
  850. static void
  851. cff_dict_fini (cairo_hash_table_t *dict)
  852. {
  853.     _cairo_hash_table_foreach (dict, _cff_dict_entry_pluck, dict);
  854.     _cairo_hash_table_destroy (dict);
  855. }
  856.  
  857. static cairo_int_status_t
  858. cairo_cff_font_read_header (cairo_cff_font_t *font)
  859. {
  860.     if (font->data_length < sizeof (cff_header_t))
  861.         return CAIRO_INT_STATUS_UNSUPPORTED;
  862.  
  863.  
  864.     font->header = (cff_header_t *) font->data;
  865.     font->current_ptr = font->data + font->header->header_size;
  866.  
  867.     return CAIRO_STATUS_SUCCESS;
  868. }
  869.  
  870. static cairo_int_status_t
  871. cairo_cff_font_read_name (cairo_cff_font_t *font)
  872. {
  873.     cairo_array_t index;
  874.     cairo_int_status_t status;
  875.     cff_index_element_t *element;
  876.     unsigned char *p;
  877.     int i, len;
  878.  
  879.     cff_index_init (&index);
  880.     status = cff_index_read (&index, &font->current_ptr, font->data_end);
  881.     if (!font->is_opentype) {
  882.         element = _cairo_array_index (&index, 0);
  883.         p = element->data;
  884.         len = element->length;
  885.  
  886.         /* If font name is prefixed with a subset tag, strip it off. */
  887.         if (len > 7 && p[6] == '+') {
  888.             for (i = 0; i < 6; i++)
  889.                 if (p[i] < 'A' || p[i] > 'Z')
  890.                     break;
  891.             if (i == 6) {
  892.                 p += 7;
  893.                 len -= 7;
  894.             }
  895.         }
  896.         font->ps_name = malloc (len + 1);
  897.         if (unlikely (font->ps_name == NULL))
  898.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  899.  
  900.         memcpy (font->ps_name, p, len);
  901.         font->ps_name[len] = 0;
  902.     }
  903.     cff_index_fini (&index);
  904.  
  905.     return status;
  906. }
  907.  
  908. static cairo_int_status_t
  909. cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
  910.                                   cairo_hash_table_t *private_dict,
  911.                                   cairo_array_t      *local_sub_index,
  912.                                   int                *local_sub_bias,
  913.                                   cairo_bool_t      **local_subs_used,
  914.                                   double             *default_width,
  915.                                   double             *nominal_width,
  916.                                   unsigned char      *ptr,
  917.                                   int                 size)
  918. {
  919.     cairo_int_status_t status;
  920.     unsigned char buf[10];
  921.     unsigned char *end_buf;
  922.     int offset;
  923.     int i;
  924.     unsigned char *operand;
  925.     unsigned char *p;
  926.     int num_subs;
  927.  
  928.     status = cff_dict_read (private_dict, ptr, size);
  929.     if (unlikely (status))
  930.         return status;
  931.  
  932.     operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
  933.     if (operand) {
  934.         decode_integer (operand, &offset);
  935.         p = ptr + offset;
  936.         status = cff_index_read (local_sub_index, &p, font->data_end);
  937.         if (unlikely (status))
  938.             return status;
  939.  
  940.         /* Use maximum sized encoding to reserve space for later modification. */
  941.         end_buf = encode_integer_max (buf, 0);
  942.         status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
  943.         if (unlikely (status))
  944.             return status;
  945.     }
  946.  
  947.     *default_width = 0;
  948.     operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i);
  949.     if (operand)
  950.         decode_number (operand, default_width);
  951.  
  952.     *nominal_width = 0;
  953.     operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i);
  954.     if (operand)
  955.          decode_number (operand, nominal_width);
  956.  
  957.     num_subs = _cairo_array_num_elements (local_sub_index);
  958.     *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t));
  959.     if (unlikely (*local_subs_used == NULL))
  960.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  961.  
  962.     if (num_subs < 1240)
  963.         *local_sub_bias = 107;
  964.     else if (num_subs < 33900)
  965.         *local_sub_bias = 1131;
  966.     else
  967.         *local_sub_bias = 32768;
  968.  
  969.     return CAIRO_STATUS_SUCCESS;
  970. }
  971.  
  972. static cairo_int_status_t
  973. cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
  974. {
  975.     int type, num_ranges, first, last, fd, i, j;
  976.  
  977.     font->fdselect = calloc (font->num_glyphs, sizeof (int));
  978.     if (unlikely (font->fdselect == NULL))
  979.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  980.  
  981.     type = *p++;
  982.     if (type == 0)
  983.     {
  984.         for (i = 0; i < font->num_glyphs; i++)
  985.             font->fdselect[i] = *p++;
  986.     } else if (type == 3) {
  987.         num_ranges = be16_to_cpu( *((uint16_t *)p) );
  988.         p += 2;
  989.         for  (i = 0; i < num_ranges; i++)
  990.         {
  991.             first = be16_to_cpu( *((uint16_t *)p) );
  992.             p += 2;
  993.             fd = *p++;
  994.             last = be16_to_cpu( *((uint16_t *)p) );
  995.             for (j = first; j < last; j++)
  996.                 font->fdselect[j] = fd;
  997.         }
  998.     } else {
  999.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1000.     }
  1001.  
  1002.     return CAIRO_STATUS_SUCCESS;
  1003. }
  1004.  
  1005. static cairo_int_status_t
  1006. cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
  1007. {
  1008.     cairo_array_t index;
  1009.     cff_index_element_t *element;
  1010.     unsigned int i;
  1011.     int size;
  1012.     unsigned char *operand;
  1013.     int offset;
  1014.     cairo_int_status_t status;
  1015.     unsigned char buf[100];
  1016.     unsigned char *end_buf;
  1017.  
  1018.     cff_index_init (&index);
  1019.     status = cff_index_read (&index, &ptr, font->data_end);
  1020.     if (unlikely (status))
  1021.         goto fail;
  1022.  
  1023.     font->num_fontdicts = _cairo_array_num_elements (&index);
  1024.  
  1025.     font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
  1026.     if (unlikely (font->fd_dict == NULL)) {
  1027.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1028.         goto fail;
  1029.     }
  1030.  
  1031.     font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
  1032.     if (unlikely (font->fd_private_dict == NULL)) {
  1033.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1034.         goto fail;
  1035.     }
  1036.  
  1037.     font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
  1038.     if (unlikely (font->fd_local_sub_index == NULL)) {
  1039.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1040.         goto fail;
  1041.     }
  1042.  
  1043.     font->fd_local_sub_bias = calloc (sizeof (int), font->num_fontdicts);
  1044.     if (unlikely (font->fd_local_sub_bias == NULL)) {
  1045.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1046.         goto fail;
  1047.     }
  1048.  
  1049.     font->fd_local_subs_used = calloc (sizeof (cairo_bool_t *), font->num_fontdicts);
  1050.     if (unlikely (font->fd_local_subs_used == NULL)) {
  1051.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1052.         goto fail;
  1053.     }
  1054.  
  1055.     font->fd_default_width = calloc (font->num_fontdicts, sizeof (double));
  1056.     if (unlikely (font->fd_default_width == NULL)) {
  1057.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1058.         goto fail;
  1059.     }
  1060.  
  1061.     font->fd_nominal_width = calloc (font->num_fontdicts, sizeof (double));
  1062.     if (unlikely (font->fd_nominal_width == NULL)) {
  1063.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1064.         goto fail;
  1065.     }
  1066.  
  1067.     for (i = 0; i < font->num_fontdicts; i++) {
  1068.         status = cff_dict_init (&font->fd_dict[i]);
  1069.         if (unlikely (status))
  1070.             goto fail;
  1071.  
  1072.         element = _cairo_array_index (&index, i);
  1073.         status = cff_dict_read (font->fd_dict[i], element->data, element->length);
  1074.         if (unlikely (status))
  1075.             goto fail;
  1076.  
  1077.         operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
  1078.         if (operand == NULL) {
  1079.             status = CAIRO_INT_STATUS_UNSUPPORTED;
  1080.             goto fail;
  1081.         }
  1082.         operand = decode_integer (operand, &size);
  1083.         decode_integer (operand, &offset);
  1084.         status = cff_dict_init (&font->fd_private_dict[i]);
  1085.         if (unlikely (status))
  1086.             goto fail;
  1087.  
  1088.         cff_index_init (&font->fd_local_sub_index[i]);
  1089.         status = cairo_cff_font_read_private_dict (font,
  1090.                                                    font->fd_private_dict[i],
  1091.                                                    &font->fd_local_sub_index[i],
  1092.                                                    &font->fd_local_sub_bias[i],
  1093.                                                    &font->fd_local_subs_used[i],
  1094.                                                    &font->fd_default_width[i],
  1095.                                                    &font->fd_nominal_width[i],
  1096.                                                    font->data + offset,
  1097.                                                    size);
  1098.         if (unlikely (status))
  1099.             goto fail;
  1100.  
  1101.         /* Set integer operand to max value to use max size encoding to reserve
  1102.          * space for any value later */
  1103.         end_buf = encode_integer_max (buf, 0);
  1104.         end_buf = encode_integer_max (end_buf, 0);
  1105.         status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
  1106.         if (unlikely (status))
  1107.             goto fail;
  1108.     }
  1109.  
  1110.     return CAIRO_STATUS_SUCCESS;
  1111.  
  1112. fail:
  1113.     cff_index_fini (&index);
  1114.  
  1115.     return status;
  1116. }
  1117.  
  1118. static void
  1119. cairo_cff_font_read_font_metrics (cairo_cff_font_t *font, cairo_hash_table_t  *top_dict)
  1120. {
  1121.     unsigned char *p;
  1122.     unsigned char *end;
  1123.     int size;
  1124.     double x_min, y_min, x_max, y_max;
  1125.     double xx, yx, xy, yy;
  1126.  
  1127.     x_min = 0.0;
  1128.     y_min = 0.0;
  1129.     x_max = 0.0;
  1130.     y_max = 0.0;
  1131.     p = cff_dict_get_operands (font->top_dict, FONTBBOX_OP, &size);
  1132.     if (p) {
  1133.         end = p + size;
  1134.         if (p < end)
  1135.             p = decode_number (p, &x_min);
  1136.         if (p < end)
  1137.             p = decode_number (p, &y_min);
  1138.         if (p < end)
  1139.             p = decode_number (p, &x_max);
  1140.         if (p < end)
  1141.             p = decode_number (p, &y_max);
  1142.     }
  1143.     font->x_min = floor (x_min);
  1144.     font->y_min = floor (y_min);
  1145.     font->x_max = floor (x_max);
  1146.     font->y_max = floor (y_max);
  1147.     font->ascent = font->y_max;
  1148.     font->descent = font->y_min;
  1149.  
  1150.     xx = 0.001;
  1151.     yx = 0.0;
  1152.     xy = 0.0;
  1153.     yy = 0.001;
  1154.     p = cff_dict_get_operands (font->top_dict, FONTMATRIX_OP, &size);
  1155.     if (p) {
  1156.         end = p + size;
  1157.         if (p < end)
  1158.             p = decode_number (p, &xx);
  1159.         if (p < end)
  1160.             p = decode_number (p, &yx);
  1161.         if (p < end)
  1162.             p = decode_number (p, &xy);
  1163.         if (p < end)
  1164.             p = decode_number (p, &yy);
  1165.     }
  1166.     /* Freetype uses 1/yy to get units per EM */
  1167.     font->units_per_em = _cairo_round(1.0/yy);
  1168. }
  1169.  
  1170. static cairo_int_status_t
  1171. cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
  1172. {
  1173.     cairo_array_t index;
  1174.     cff_index_element_t *element;
  1175.     unsigned char buf[20];
  1176.     unsigned char *end_buf;
  1177.     unsigned char *operand;
  1178.     cairo_int_status_t status;
  1179.     unsigned char *p;
  1180.     int size;
  1181.     int offset;
  1182.  
  1183.     cff_index_init (&index);
  1184.     status = cff_index_read (&index, &font->current_ptr, font->data_end);
  1185.     if (unlikely (status))
  1186.         goto fail;
  1187.  
  1188.     element = _cairo_array_index (&index, 0);
  1189.     status = cff_dict_read (font->top_dict, element->data, element->length);
  1190.     if (unlikely (status))
  1191.         goto fail;
  1192.  
  1193.     if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
  1194.         font->is_cid = TRUE;
  1195.     else
  1196.         font->is_cid = FALSE;
  1197.  
  1198.     operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
  1199.     decode_integer (operand, &offset);
  1200.     p = font->data + offset;
  1201.     status = cff_index_read (&font->charstrings_index, &p, font->data_end);
  1202.     if (unlikely (status))
  1203.         goto fail;
  1204.     font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
  1205.  
  1206.     if (font->is_cid) {
  1207.          operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
  1208.          if (!operand)
  1209.               return CAIRO_INT_STATUS_UNSUPPORTED;
  1210.  
  1211.          decode_integer (operand, &offset);
  1212.          font->charset = font->data + offset;
  1213.          if (font->charset >= font->data_end)
  1214.               return CAIRO_INT_STATUS_UNSUPPORTED;
  1215.     }
  1216.  
  1217.     if (!font->is_opentype)
  1218.         cairo_cff_font_read_font_metrics (font, font->top_dict);
  1219.  
  1220.     if (font->is_cid) {
  1221.         operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
  1222.         decode_integer (operand, &offset);
  1223.         status = cairo_cff_font_read_fdselect (font, font->data + offset);
  1224.         if (unlikely (status))
  1225.             goto fail;
  1226.  
  1227.         operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
  1228.         decode_integer (operand, &offset);
  1229.         status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
  1230.         if (unlikely (status))
  1231.             goto fail;
  1232.     } else {
  1233.         operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
  1234.         operand = decode_integer (operand, &size);
  1235.         decode_integer (operand, &offset);
  1236.         status = cairo_cff_font_read_private_dict (font,
  1237.                                                    font->private_dict,
  1238.                                                    &font->local_sub_index,
  1239.                                                    &font->local_sub_bias,
  1240.                                                    &font->local_subs_used,
  1241.                                                    &font->default_width,
  1242.                                                    &font->nominal_width,
  1243.                                                    font->data + offset,
  1244.                                                    size);
  1245.         if (unlikely (status))
  1246.             goto fail;
  1247.     }
  1248.  
  1249.     /* Use maximum sized encoding to reserve space for later modification. */
  1250.     end_buf = encode_integer_max (buf, 0);
  1251.     status = cff_dict_set_operands (font->top_dict,
  1252.                                     CHARSTRINGS_OP, buf, end_buf - buf);
  1253.     if (unlikely (status))
  1254.         goto fail;
  1255.  
  1256.     status = cff_dict_set_operands (font->top_dict,
  1257.                                     CHARSET_OP, buf, end_buf - buf);
  1258.     if (unlikely (status))
  1259.         goto fail;
  1260.  
  1261.     if (font->scaled_font_subset->is_latin) {
  1262.         status = cff_dict_set_operands (font->top_dict,
  1263.                                         ENCODING_OP, buf, end_buf - buf);
  1264.         if (unlikely (status))
  1265.             goto fail;
  1266.  
  1267.         /* Private has two operands - size and offset */
  1268.         end_buf = encode_integer_max (end_buf, 0);
  1269.         cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf - buf);
  1270.         if (unlikely (status))
  1271.             goto fail;
  1272.  
  1273.     } else {
  1274.         status = cff_dict_set_operands (font->top_dict,
  1275.                                         FDSELECT_OP, buf, end_buf - buf);
  1276.         if (unlikely (status))
  1277.             goto fail;
  1278.  
  1279.         status = cff_dict_set_operands (font->top_dict,
  1280.                                         FDARRAY_OP, buf, end_buf - buf);
  1281.         if (unlikely (status))
  1282.             goto fail;
  1283.  
  1284.         cff_dict_remove (font->top_dict, ENCODING_OP);
  1285.         cff_dict_remove (font->top_dict, PRIVATE_OP);
  1286.     }
  1287.  
  1288.     /* Remove the unique identifier operators as the subsetted font is
  1289.      * not the same is the original font. */
  1290.     cff_dict_remove (font->top_dict, UNIQUEID_OP);
  1291.     cff_dict_remove (font->top_dict, XUID_OP);
  1292.  
  1293. fail:
  1294.     cff_index_fini (&index);
  1295.  
  1296.     return status;
  1297. }
  1298.  
  1299. static cairo_int_status_t
  1300. cairo_cff_font_read_strings (cairo_cff_font_t *font)
  1301. {
  1302.     return cff_index_read (&font->strings_index, &font->current_ptr, font->data_end);
  1303. }
  1304.  
  1305. static cairo_int_status_t
  1306. cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
  1307. {
  1308.     cairo_int_status_t status;
  1309.     int num_subs;
  1310.  
  1311.     status = cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
  1312.     if (unlikely (status))
  1313.         return status;
  1314.  
  1315.     num_subs = _cairo_array_num_elements (&font->global_sub_index);
  1316.     font->global_subs_used = calloc (num_subs, sizeof(cairo_bool_t));
  1317.     if (unlikely (font->global_subs_used == NULL))
  1318.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1319.  
  1320.     if (num_subs < 1240)
  1321.         font->global_sub_bias = 107;
  1322.     else if (num_subs < 33900)
  1323.         font->global_sub_bias = 1131;
  1324.     else
  1325.         font->global_sub_bias = 32768;
  1326.  
  1327.     return CAIRO_STATUS_SUCCESS;
  1328. }
  1329.  
  1330. typedef cairo_int_status_t
  1331. (*font_read_t) (cairo_cff_font_t *font);
  1332.  
  1333. static const font_read_t font_read_funcs[] = {
  1334.     cairo_cff_font_read_header,
  1335.     cairo_cff_font_read_name,
  1336.     cairo_cff_font_read_top_dict,
  1337.     cairo_cff_font_read_strings,
  1338.     cairo_cff_font_read_global_subroutines,
  1339. };
  1340.  
  1341. static cairo_int_status_t
  1342. cairo_cff_font_read_font (cairo_cff_font_t *font)
  1343. {
  1344.     cairo_int_status_t status;
  1345.     unsigned int i;
  1346.  
  1347.     for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
  1348.         status = font_read_funcs[i] (font);
  1349.         if (unlikely (status))
  1350.             return status;
  1351.     }
  1352.  
  1353.     return CAIRO_STATUS_SUCCESS;
  1354. }
  1355.  
  1356. static cairo_status_t
  1357. cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
  1358. {
  1359.     cairo_status_t status;
  1360.     unsigned char buf[30];
  1361.     unsigned char *p;
  1362.     int sid1, sid2;
  1363.     const char *registry = "Adobe";
  1364.     const char *ordering = "Identity";
  1365.  
  1366.     sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1367.     status = cff_index_append_copy (&font->strings_subset_index,
  1368.                                     (unsigned char *)registry,
  1369.                                     strlen(registry));
  1370.     if (unlikely (status))
  1371.         return status;
  1372.  
  1373.     sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1374.     status = cff_index_append_copy (&font->strings_subset_index,
  1375.                                     (unsigned char *)ordering,
  1376.                                     strlen(ordering));
  1377.     if (unlikely (status))
  1378.         return status;
  1379.  
  1380.     p = encode_integer (buf, sid1);
  1381.     p = encode_integer (p, sid2);
  1382.     p = encode_integer (p, 0);
  1383.     status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
  1384.     if (unlikely (status))
  1385.         return status;
  1386.  
  1387.     p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
  1388.     status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
  1389.     if (unlikely (status))
  1390.         return status;
  1391.  
  1392.     return CAIRO_STATUS_SUCCESS;
  1393. }
  1394.  
  1395. static cairo_status_t
  1396. cairo_cff_font_subset_dict_string(cairo_cff_font_t   *font,
  1397.                                   cairo_hash_table_t *dict,
  1398.                                   int                 operator)
  1399. {
  1400.     int size;
  1401.     unsigned char *p;
  1402.     int sid;
  1403.     unsigned char buf[100];
  1404.     cff_index_element_t *element;
  1405.     cairo_status_t status;
  1406.  
  1407.     p = cff_dict_get_operands (dict, operator, &size);
  1408.     if (!p)
  1409.         return CAIRO_STATUS_SUCCESS;
  1410.  
  1411.     decode_integer (p, &sid);
  1412.     if (sid < NUM_STD_STRINGS)
  1413.         return CAIRO_STATUS_SUCCESS;
  1414.  
  1415.     element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS);
  1416.     sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1417.     status = cff_index_append (&font->strings_subset_index, element->data, element->length);
  1418.     if (unlikely (status))
  1419.         return status;
  1420.  
  1421.     p = encode_integer (buf, sid);
  1422.     status = cff_dict_set_operands (dict, operator, buf, p - buf);
  1423.     if (unlikely (status))
  1424.         return status;
  1425.  
  1426.     return CAIRO_STATUS_SUCCESS;
  1427. }
  1428.  
  1429. static const int dict_strings[] = {
  1430.     VERSION_OP,
  1431.     NOTICE_OP,
  1432.     COPYRIGHT_OP,
  1433.     FULLNAME_OP,
  1434.     FAMILYNAME_OP,
  1435.     WEIGHT_OP,
  1436.     POSTSCRIPT_OP,
  1437.     BASEFONTNAME_OP,
  1438.     FONTNAME_OP,
  1439. };
  1440.  
  1441. static cairo_status_t
  1442. cairo_cff_font_subset_dict_strings (cairo_cff_font_t   *font,
  1443.                                     cairo_hash_table_t *dict)
  1444. {
  1445.     cairo_status_t status;
  1446.     unsigned int i;
  1447.  
  1448.     for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
  1449.         status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
  1450.         if (unlikely (status))
  1451.             return status;
  1452.     }
  1453.  
  1454.     return CAIRO_STATUS_SUCCESS;
  1455. }
  1456.  
  1457. static unsigned char *
  1458. type2_decode_integer (unsigned char *p, int *integer)
  1459. {
  1460.     if (*p == 28) {
  1461.         *integer = p[1] << 8 | p[2];
  1462.         p += 3;
  1463.     } else if (*p <= 246) {
  1464.         *integer = *p++ - 139;
  1465.     } else if (*p <= 250) {
  1466.         *integer = (p[0] - 247) * 256 + p[1] + 108;
  1467.         p += 2;
  1468.     } else if (*p <= 254) {
  1469.         *integer = -(p[0] - 251) * 256 - p[1] - 108;
  1470.         p += 2;
  1471.     } else { /* *p == 255 */
  1472.          /* 16.16 fixed-point number. The fraction is ignored. */
  1473.          *integer = (int16_t)((p[1] << 8) | p[2]);
  1474.         p += 5;
  1475.     }
  1476.     return p;
  1477. }
  1478.  
  1479. /* Type 2 charstring parser for finding calls to local or global
  1480.  * subroutines. For non Opentype CFF fonts it also gets the glyph
  1481.  * widths.
  1482.  *
  1483.  * When we find a subroutine operator, the subroutine is marked as in
  1484.  * use and recursively followed. The subroutine number is the value on
  1485.  * the top of the stack when the subroutine operator is executed. In
  1486.  * most fonts the subroutine number is encoded in an integer
  1487.  * immediately preceding the subroutine operator. However it is
  1488.  * possible for the subroutine number on the stack to be the result of
  1489.  * a computation (in which case there will be an operator preceding
  1490.  * the subroutine operator). If this occurs, subroutine subsetting is
  1491.  * disabled since we can't easily determine which subroutines are
  1492.  * used.
  1493.  *
  1494.  * The width, if present, is the first integer in the charstring. The
  1495.  * only way to confirm if the integer at the start of the charstring is
  1496.  * the width is when the first stack clearing operator is parsed,
  1497.  * check if there is an extra integer left over on the stack.
  1498.  *
  1499.  * When the first stack clearing operator is encountered
  1500.  * type2_find_width is set to FALSE and type2_found_width is set to
  1501.  * TRUE if an extra argument is found, otherwise FALSE.
  1502.  */
  1503. static cairo_status_t
  1504. cairo_cff_parse_charstring (cairo_cff_font_t *font,
  1505.                             unsigned char *charstring, int length,
  1506.                             int glyph_id,
  1507.                             cairo_bool_t need_width)
  1508. {
  1509.     unsigned char *p = charstring;
  1510.     unsigned char *end = charstring + length;
  1511.     int integer;
  1512.     int hint_bytes;
  1513.     int sub_num;
  1514.     cff_index_element_t *element;
  1515.     int fd;
  1516.  
  1517.     while (p < end) {
  1518.         if (*p == 28 || *p >= 32) {
  1519.             /* Integer value */
  1520.             p = type2_decode_integer (p, &integer);
  1521.             font->type2_stack_size++;
  1522.             font->type2_stack_top_value = integer;
  1523.             font->type2_stack_top_is_int = TRUE;
  1524.             if (!font->type2_seen_first_int) {
  1525.                 font->type2_width = integer;
  1526.                 font->type2_seen_first_int = TRUE;
  1527.             }
  1528.         } else if (*p == TYPE2_hstem || *p == TYPE2_vstem ||
  1529.                    *p == TYPE2_hstemhm || *p == TYPE2_vstemhm) {
  1530.             /* Hint operator. The number of hints declared by the
  1531.              * operator depends on the size of the stack. */
  1532.             font->type2_stack_top_is_int = FALSE;
  1533.             font->type2_num_hints += font->type2_stack_size/2;
  1534.             if (font->type2_find_width && font->type2_stack_size % 2)
  1535.                 font->type2_found_width = TRUE;
  1536.  
  1537.             font->type2_stack_size = 0;
  1538.             font->type2_find_width = FALSE;
  1539.             p++;
  1540.         } else if (*p == TYPE2_hintmask || *p == TYPE2_cntrmask) {
  1541.             /* Hintmask operator. These operators are followed by a
  1542.              * variable length mask where the length depends on the
  1543.              * number of hints declared. The first time this is called
  1544.              * it is also an implicit vstem if there are arguments on
  1545.              * the stack. */
  1546.             if (font->type2_hintmask_bytes == 0) {
  1547.                 font->type2_stack_top_is_int = FALSE;
  1548.                 font->type2_num_hints += font->type2_stack_size/2;
  1549.                 if (font->type2_find_width && font->type2_stack_size % 2)
  1550.                     font->type2_found_width = TRUE;
  1551.  
  1552.                 font->type2_stack_size = 0;
  1553.                 font->type2_find_width = FALSE;
  1554.                 font->type2_hintmask_bytes = (font->type2_num_hints+7)/8;
  1555.             }
  1556.  
  1557.             hint_bytes = font->type2_hintmask_bytes;
  1558.             p++;
  1559.             p += hint_bytes;
  1560.         } else if (*p == TYPE2_rmoveto) {
  1561.             if (font->type2_find_width && font->type2_stack_size > 2)
  1562.                 font->type2_found_width = TRUE;
  1563.  
  1564.             font->type2_stack_size = 0;
  1565.             font->type2_find_width = FALSE;
  1566.             font->type2_has_path = TRUE;
  1567.             p++;
  1568.         } else if (*p == TYPE2_hmoveto || *p == TYPE2_vmoveto) {
  1569.             if (font->type2_find_width && font->type2_stack_size > 1)
  1570.                 font->type2_found_width = TRUE;
  1571.  
  1572.             font->type2_stack_size = 0;
  1573.             font->type2_find_width = FALSE;
  1574.             font->type2_has_path = TRUE;
  1575.             p++;
  1576.         } else if (*p == TYPE2_endchar) {
  1577.             if (!font->type2_has_path && font->type2_stack_size > 3)
  1578.                 return CAIRO_INT_STATUS_UNSUPPORTED; /* seac (Ref Appendix C of Type 2 Charstring Format */
  1579.  
  1580.             if (font->type2_find_width && font->type2_stack_size > 0)
  1581.                 font->type2_found_width = TRUE;
  1582.  
  1583.             return CAIRO_STATUS_SUCCESS;
  1584.         } else if (*p == TYPE2_callsubr) {
  1585.             /* call to local subroutine */
  1586.             if (! font->type2_stack_top_is_int)
  1587.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  1588.  
  1589.             if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
  1590.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  1591.  
  1592.             p++;
  1593.             font->type2_stack_top_is_int = FALSE;
  1594.             font->type2_stack_size--;
  1595.             if (font->type2_find_width && font->type2_stack_size == 0)
  1596.                 font->type2_seen_first_int = FALSE;
  1597.  
  1598.             if (font->is_cid) {
  1599.                 fd = font->fdselect[glyph_id];
  1600.                 sub_num = font->type2_stack_top_value + font->fd_local_sub_bias[fd];
  1601.                 element = _cairo_array_index (&font->fd_local_sub_index[fd], sub_num);
  1602.                 if (! font->fd_local_subs_used[fd][sub_num]) {
  1603.                     font->fd_local_subs_used[fd][sub_num] = TRUE;
  1604.                     cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
  1605.                 }
  1606.             } else {
  1607.                 sub_num = font->type2_stack_top_value + font->local_sub_bias;
  1608.                 element = _cairo_array_index (&font->local_sub_index, sub_num);
  1609.                 if (! font->local_subs_used[sub_num] ||
  1610.                     (need_width && !font->type2_found_width))
  1611.                 {
  1612.                     font->local_subs_used[sub_num] = TRUE;
  1613.                     cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
  1614.                 }
  1615.             }
  1616.             font->type2_nesting_level--;
  1617.         } else if (*p == TYPE2_callgsubr) {
  1618.             /* call to global subroutine */
  1619.             if (! font->type2_stack_top_is_int)
  1620.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  1621.  
  1622.             if (++font->type2_nesting_level > MAX_SUBROUTINE_NESTING)
  1623.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  1624.  
  1625.             p++;
  1626.             font->type2_stack_size--;
  1627.             font->type2_stack_top_is_int = FALSE;
  1628.             if (font->type2_find_width && font->type2_stack_size == 0)
  1629.                 font->type2_seen_first_int = FALSE;
  1630.  
  1631.             sub_num = font->type2_stack_top_value + font->global_sub_bias;
  1632.             element = _cairo_array_index (&font->global_sub_index, sub_num);
  1633.             if (! font->global_subs_used[sub_num] ||
  1634.                 (need_width && !font->type2_found_width))
  1635.             {
  1636.                 font->global_subs_used[sub_num] = TRUE;
  1637.                 cairo_cff_parse_charstring (font, element->data, element->length, glyph_id, need_width);
  1638.             }
  1639.             font->type2_nesting_level--;
  1640.         } else if (*p == 12) {
  1641.             /* 2 byte instruction */
  1642.  
  1643.             /* All the 2 byte operators are either not valid before a
  1644.              * stack clearing operator or they are one of the
  1645.              * arithmetic, storage, or conditional operators. */
  1646.             if (need_width && font->type2_find_width)
  1647.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  1648.  
  1649.             p += 2;
  1650.             font->type2_stack_top_is_int = FALSE;
  1651.         } else {
  1652.             /* 1 byte instruction */
  1653.             p++;
  1654.             font->type2_stack_top_is_int = FALSE;
  1655.         }
  1656.     }
  1657.  
  1658.     return CAIRO_STATUS_SUCCESS;
  1659. }
  1660.  
  1661. static cairo_status_t
  1662. cairo_cff_find_width_and_subroutines_used (cairo_cff_font_t  *font,
  1663.                                            unsigned char *charstring, int length,
  1664.                                            int glyph_id, int subset_id)
  1665. {
  1666.     cairo_status_t status;
  1667.     int width;
  1668.     int fd;
  1669.  
  1670.     font->type2_stack_size = 0;
  1671.     font->type2_stack_top_value = 0;;
  1672.     font->type2_stack_top_is_int = FALSE;
  1673.     font->type2_num_hints = 0;
  1674.     font->type2_hintmask_bytes = 0;
  1675.     font->type2_nesting_level = 0;
  1676.     font->type2_seen_first_int = FALSE;
  1677.     font->type2_find_width = TRUE;
  1678.     font->type2_found_width = FALSE;
  1679.     font->type2_width = 0;
  1680.     font->type2_has_path = FALSE;
  1681.  
  1682.     status = cairo_cff_parse_charstring (font, charstring, length, glyph_id, TRUE);
  1683.     if (status)
  1684.         return status;
  1685.  
  1686.     if (!font->is_opentype) {
  1687.         if (font->is_cid) {
  1688.             fd = font->fdselect[glyph_id];
  1689.             if (font->type2_found_width)
  1690.                 width = font->fd_nominal_width[fd] + font->type2_width;
  1691.             else
  1692.                 width = font->fd_default_width[fd];
  1693.         } else {
  1694.             if (font->type2_found_width)
  1695.                 width = font->nominal_width + font->type2_width;
  1696.             else
  1697.                 width = font->default_width;
  1698.         }
  1699.         font->widths[subset_id] = width;
  1700.     }
  1701.  
  1702.     return CAIRO_STATUS_SUCCESS;
  1703. }
  1704.  
  1705. static cairo_int_status_t
  1706. cairo_cff_font_get_gid_for_cid (cairo_cff_font_t  *font, unsigned long cid, unsigned long *gid)
  1707. {
  1708.     unsigned char *p;
  1709.     unsigned long first_gid;
  1710.     unsigned long first_cid;
  1711.     int num_left;
  1712.     unsigned long c, g;
  1713.  
  1714.     if (cid == 0) {
  1715.         *gid = 0;
  1716.         return CAIRO_STATUS_SUCCESS;
  1717.     }
  1718.  
  1719.     switch (font->charset[0]) {
  1720.         /* Format 0 */
  1721.         case 0:
  1722.             p = font->charset + 1;
  1723.             g = 1;
  1724.             while (g <= (unsigned)font->num_glyphs && p < font->data_end) {
  1725.                 c = be16_to_cpu( *((uint16_t *)p) );
  1726.                 if (c == cid) {
  1727.                     *gid = g;
  1728.                     return CAIRO_STATUS_SUCCESS;
  1729.                 }
  1730.                 g++;
  1731.                 p += 2;
  1732.             }
  1733.             break;
  1734.  
  1735.         /* Format 1 */
  1736.         case 1:
  1737.             first_gid = 1;
  1738.             p = font->charset + 1;
  1739.             while (first_gid <= (unsigned)font->num_glyphs && p + 2 < font->data_end) {
  1740.                 first_cid = be16_to_cpu( *((uint16_t *)p) );
  1741.                 num_left = p[2];
  1742.                 if (cid >= first_cid && cid <= first_cid + num_left) {
  1743.                     *gid = first_gid + cid - first_cid;
  1744.                     return CAIRO_STATUS_SUCCESS;
  1745.                 }
  1746.                 first_gid += num_left + 1;
  1747.                 p += 3;
  1748.             }
  1749.             break;
  1750.  
  1751.         /* Format 2 */
  1752.         case 2:
  1753.             first_gid = 1;
  1754.             p = font->charset + 1;
  1755.             while (first_gid <= (unsigned)font->num_glyphs && p + 3 < font->data_end) {
  1756.                 first_cid = be16_to_cpu( *((uint16_t *)p) );
  1757.                 num_left = be16_to_cpu( *((uint16_t *)(p+2)) );
  1758.                 if (cid >= first_cid && cid <= first_cid + num_left) {
  1759.                     *gid = first_gid + cid - first_cid;
  1760.                     return CAIRO_STATUS_SUCCESS;
  1761.                 }
  1762.                 first_gid += num_left + 1;
  1763.                 p += 4;
  1764.             }
  1765.             break;
  1766.  
  1767.         default:
  1768.             break;
  1769.     }
  1770.     return CAIRO_INT_STATUS_UNSUPPORTED;
  1771. }
  1772.  
  1773. static cairo_int_status_t
  1774. cairo_cff_font_subset_charstrings_and_subroutines (cairo_cff_font_t  *font)
  1775. {
  1776.     cff_index_element_t *element;
  1777.     unsigned int i;
  1778.     cairo_int_status_t status;
  1779.     unsigned long glyph, cid;
  1780.  
  1781.     font->subset_subroutines = TRUE;
  1782.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1783.         if (font->is_cid) {
  1784.             cid = font->scaled_font_subset->glyphs[i];
  1785.             status = cairo_cff_font_get_gid_for_cid (font, cid, &glyph);
  1786.             if (unlikely (status))
  1787.                 return status;
  1788.         } else {
  1789.             glyph = font->scaled_font_subset->glyphs[i];
  1790.         }
  1791.         element = _cairo_array_index (&font->charstrings_index, glyph);
  1792.         status = cff_index_append (&font->charstrings_subset_index,
  1793.                                    element->data,
  1794.                                    element->length);
  1795.         if (unlikely (status))
  1796.             return status;
  1797.  
  1798.         if (font->subset_subroutines) {
  1799.             status = cairo_cff_find_width_and_subroutines_used (font,
  1800.                                                                 element->data, element->length,
  1801.                                                                 glyph, i);
  1802.             if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
  1803.                 /* If parsing the charstrings fails we embed all the
  1804.                  * subroutines. But if the font is not opentype we
  1805.                  * need to successfully parse all charstrings to get
  1806.                  * the widths. */
  1807.                 font->subset_subroutines = FALSE;
  1808.                 if (!font->is_opentype)
  1809.                     return status;
  1810.             } else if (unlikely (status)) {
  1811.                 return status;
  1812.             }
  1813.         }
  1814.     }
  1815.  
  1816.     return CAIRO_STATUS_SUCCESS;
  1817. }
  1818.  
  1819. static cairo_status_t
  1820. cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
  1821. {
  1822.     unsigned int i;
  1823.     int fd;
  1824.     int *reverse_map;
  1825.     unsigned long cid, gid;
  1826.     cairo_int_status_t status;
  1827.  
  1828.     font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
  1829.                                      sizeof (int));
  1830.     if (unlikely (font->fdselect_subset == NULL))
  1831.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1832.  
  1833.     font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
  1834.     if (unlikely (font->fd_subset_map == NULL))
  1835.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1836.  
  1837.     font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
  1838.     if (unlikely (font->private_dict_offset == NULL))
  1839.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1840.  
  1841.     reverse_map = calloc (font->num_fontdicts, sizeof (int));
  1842.     if (unlikely (reverse_map == NULL))
  1843.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1844.  
  1845.     for (i = 0; i < font->num_fontdicts; i++)
  1846.         reverse_map[i] = -1;
  1847.  
  1848.     font->num_subset_fontdicts = 0;
  1849.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1850.         cid = font->scaled_font_subset->glyphs[i];
  1851.         status = cairo_cff_font_get_gid_for_cid (font, cid, &gid);
  1852.         if (unlikely (status))
  1853.             return status;
  1854.  
  1855.         fd = font->fdselect[gid];
  1856.         if (reverse_map[fd] < 0) {
  1857.             font->fd_subset_map[font->num_subset_fontdicts] = fd;
  1858.             reverse_map[fd] = font->num_subset_fontdicts++;
  1859.         }
  1860.         font->fdselect_subset[i] = reverse_map[fd];
  1861.     }
  1862.  
  1863.     free (reverse_map);
  1864.  
  1865.     return CAIRO_STATUS_SUCCESS;
  1866. }
  1867.  
  1868. static cairo_status_t
  1869. cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
  1870. {
  1871.     unsigned char buf[100];
  1872.     unsigned char *end_buf;
  1873.     cairo_status_t status;
  1874.  
  1875.     font->num_fontdicts = 1;
  1876.     font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
  1877.     if (unlikely (font->fd_dict == NULL))
  1878.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1879.  
  1880.     if (cff_dict_init (&font->fd_dict[0])) {
  1881.         free (font->fd_dict);
  1882.         font->fd_dict = NULL;
  1883.         font->num_fontdicts = 0;
  1884.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1885.     }
  1886.  
  1887.     font->fd_subset_map = malloc (sizeof (int));
  1888.     if (unlikely (font->fd_subset_map == NULL))
  1889.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1890.  
  1891.     font->private_dict_offset = malloc (sizeof (int));
  1892.     if (unlikely (font->private_dict_offset == NULL))
  1893.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1894.  
  1895.     font->fd_subset_map[0] = 0;
  1896.     font->num_subset_fontdicts = 1;
  1897.  
  1898.     /* Set integer operand to max value to use max size encoding to reserve
  1899.      * space for any value later */
  1900.     end_buf = encode_integer_max (buf, 0);
  1901.     end_buf = encode_integer_max (end_buf, 0);
  1902.     status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
  1903.     if (unlikely (status))
  1904.         return status;
  1905.  
  1906.     return CAIRO_STATUS_SUCCESS;
  1907. }
  1908.  
  1909. static cairo_status_t
  1910. cairo_cff_font_subset_strings (cairo_cff_font_t *font)
  1911. {
  1912.     cairo_status_t status;
  1913.     unsigned int i;
  1914.  
  1915.     status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
  1916.     if (unlikely (status))
  1917.         return status;
  1918.  
  1919.     if (font->is_cid) {
  1920.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  1921.             status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
  1922.             if (unlikely (status))
  1923.                 return status;
  1924.  
  1925.             status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
  1926.             if (unlikely (status))
  1927.                 return status;
  1928.         }
  1929.     } else {
  1930.         status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
  1931.     }
  1932.  
  1933.     return status;
  1934. }
  1935.  
  1936. /* The Euro is the only the only character in the winansi encoding
  1937.  * with a glyph name that is not a CFF standard string. As the strings
  1938.  * are written before the charset, we need to check during the
  1939.  * subsetting phase if the Euro glyph is required and add the
  1940.  * glyphname to the list of strings to write out.
  1941.  */
  1942. static cairo_status_t
  1943. cairo_cff_font_add_euro_charset_string (cairo_cff_font_t *font)
  1944. {
  1945.     cairo_status_t status;
  1946.     unsigned int i;
  1947.     int ch;
  1948.     const char *euro = "Euro";
  1949.  
  1950.     for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
  1951.         ch = font->scaled_font_subset->to_latin_char[i];
  1952.         if (ch == 128) {
  1953.             font->euro_sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1954.             status = cff_index_append_copy (&font->strings_subset_index,
  1955.                                             (unsigned char *)euro, strlen(euro));
  1956.             return status;
  1957.         }
  1958.     }
  1959.  
  1960.     return CAIRO_STATUS_SUCCESS;
  1961. }
  1962.  
  1963. static cairo_status_t
  1964. cairo_cff_font_subset_font (cairo_cff_font_t  *font)
  1965. {
  1966.     cairo_status_t status;
  1967.  
  1968.     if (!font->scaled_font_subset->is_latin) {
  1969.         status = cairo_cff_font_set_ros_strings (font);
  1970.         if (unlikely (status))
  1971.             return status;
  1972.     }
  1973.  
  1974.     status = cairo_cff_font_subset_charstrings_and_subroutines (font);
  1975.     if (unlikely (status))
  1976.         return status;
  1977.  
  1978.     if (!font->scaled_font_subset->is_latin) {
  1979.         if (font->is_cid)
  1980.             status = cairo_cff_font_subset_fontdict (font);
  1981.         else
  1982.             status = cairo_cff_font_create_cid_fontdict (font);
  1983.         if (unlikely (status))
  1984.             return status;
  1985.     }  else {
  1986.         font->private_dict_offset = malloc (sizeof (int));
  1987.         if (unlikely (font->private_dict_offset == NULL))
  1988.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1989.     }
  1990.  
  1991.     status = cairo_cff_font_subset_strings (font);
  1992.     if (unlikely (status))
  1993.         return status;
  1994.  
  1995.     if (font->scaled_font_subset->is_latin)
  1996.         status = cairo_cff_font_add_euro_charset_string (font);
  1997.  
  1998.     return status;
  1999. }
  2000.  
  2001. /* Set the operand of the specified operator in the (already written)
  2002.  * top dict to point to the current position in the output
  2003.  * array. Operands updated with this function must have previously
  2004.  * been encoded with the 5-byte (max) integer encoding. */
  2005. static void
  2006. cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t  *font,
  2007.                                                 int                operator)
  2008. {
  2009.     int cur_pos;
  2010.     int offset;
  2011.     int size;
  2012.     unsigned char buf[10];
  2013.     unsigned char *buf_end;
  2014.     unsigned char *op_ptr;
  2015.  
  2016.     cur_pos = _cairo_array_num_elements (&font->output);
  2017.     buf_end = encode_integer_max (buf, cur_pos);
  2018.     offset = cff_dict_get_location (font->top_dict, operator, &size);
  2019.     assert (offset > 0);
  2020.     op_ptr = _cairo_array_index (&font->output, offset);
  2021.     memcpy (op_ptr, buf, buf_end - buf);
  2022. }
  2023.  
  2024. static cairo_status_t
  2025. cairo_cff_font_write_header (cairo_cff_font_t *font)
  2026. {
  2027.     return _cairo_array_append_multiple (&font->output,
  2028.                                          font->header,
  2029.                                          font->header->header_size);
  2030. }
  2031.  
  2032. static cairo_status_t
  2033. cairo_cff_font_write_name (cairo_cff_font_t *font)
  2034. {
  2035.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  2036.     cairo_array_t index;
  2037.  
  2038.     cff_index_init (&index);
  2039.  
  2040.     status = cff_index_append_copy (&index,
  2041.                                     (unsigned char *) font->ps_name,
  2042.                                     strlen(font->ps_name));
  2043.     if (unlikely (status))
  2044.         goto FAIL;
  2045.  
  2046.     status = cff_index_write (&index, &font->output);
  2047.     if (unlikely (status))
  2048.         goto FAIL;
  2049.  
  2050. FAIL:
  2051.     cff_index_fini (&index);
  2052.  
  2053.     return status;
  2054. }
  2055.  
  2056. static cairo_status_t
  2057. cairo_cff_font_write_top_dict (cairo_cff_font_t *font)
  2058. {
  2059.     uint16_t count;
  2060.     unsigned char buf[10];
  2061.     unsigned char *p;
  2062.     int offset_index;
  2063.     int dict_start, dict_size;
  2064.     int offset_size = 4;
  2065.     cairo_status_t status;
  2066.  
  2067.     /* Write an index containing the top dict */
  2068.  
  2069.     count = cpu_to_be16 (1);
  2070.     status = _cairo_array_append_multiple (&font->output, &count, 2);
  2071.     if (unlikely (status))
  2072.         return status;
  2073.     buf[0] = offset_size;
  2074.     status = _cairo_array_append (&font->output, buf);
  2075.     if (unlikely (status))
  2076.         return status;
  2077.     encode_index_offset (buf, offset_size, 1);
  2078.     status = _cairo_array_append_multiple (&font->output, buf, offset_size);
  2079.     if (unlikely (status))
  2080.         return status;
  2081.  
  2082.     /* Reserve space for last element of offset array and update after
  2083.      * dict is written */
  2084.     offset_index = _cairo_array_num_elements (&font->output);
  2085.     status = _cairo_array_append_multiple (&font->output, buf, offset_size);
  2086.     if (unlikely (status))
  2087.         return status;
  2088.  
  2089.     dict_start = _cairo_array_num_elements (&font->output);
  2090.     status = cff_dict_write (font->top_dict, &font->output);
  2091.     if (unlikely (status))
  2092.         return status;
  2093.     dict_size = _cairo_array_num_elements (&font->output) - dict_start;
  2094.  
  2095.     encode_index_offset (buf, offset_size, dict_size + 1);
  2096.     p = _cairo_array_index (&font->output, offset_index);
  2097.     memcpy (p, buf, offset_size);
  2098.  
  2099.     return CAIRO_STATUS_SUCCESS;
  2100. }
  2101.  
  2102. static cairo_status_t
  2103. cairo_cff_font_write_strings (cairo_cff_font_t  *font)
  2104. {
  2105.     return cff_index_write (&font->strings_subset_index, &font->output);
  2106. }
  2107.  
  2108. static cairo_status_t
  2109. cairo_cff_font_write_global_subrs (cairo_cff_font_t  *font)
  2110. {
  2111.     unsigned int i;
  2112.     unsigned char return_op = TYPE2_return;
  2113.  
  2114.     /* poppler and fontforge don't like zero length subroutines so we
  2115.      * replace unused subroutines with a 'return' instruction. */
  2116.     if (font->subset_subroutines) {
  2117.         for (i = 0; i < _cairo_array_num_elements (&font->global_sub_index); i++) {
  2118.             if (! font->global_subs_used[i])
  2119.                 cff_index_set_object (&font->global_sub_index, i, &return_op, 1);
  2120.         }
  2121.     }
  2122.  
  2123.     return cff_index_write (&font->global_sub_index, &font->output);
  2124. }
  2125.  
  2126. static cairo_status_t
  2127. cairo_cff_font_write_encoding (cairo_cff_font_t  *font)
  2128. {
  2129.     unsigned char buf[2];
  2130.     cairo_status_t status;
  2131.     unsigned int i;
  2132.  
  2133.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, ENCODING_OP);
  2134.     buf[0] = 0; /* Format 0 */
  2135.     buf[1] = font->scaled_font_subset->num_glyphs - 1;
  2136.     status = _cairo_array_append_multiple (&font->output, buf, 2);
  2137.     if (unlikely (status))
  2138.         return status;
  2139.  
  2140.     for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
  2141.         unsigned char ch = font->scaled_font_subset->to_latin_char[i];
  2142.         status = _cairo_array_append (&font->output, &ch);
  2143.         if (unlikely (status))
  2144.             return status;
  2145.     }
  2146.  
  2147.     return CAIRO_STATUS_SUCCESS;
  2148. }
  2149.  
  2150. static cairo_status_t
  2151. cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
  2152. {
  2153.     unsigned char data;
  2154.     unsigned int i;
  2155.     cairo_int_status_t status;
  2156.  
  2157.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
  2158.  
  2159.     if (font->is_cid) {
  2160.         data = 0;
  2161.         status = _cairo_array_append (&font->output, &data);
  2162.         if (unlikely (status))
  2163.             return status;
  2164.  
  2165.         for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  2166.             data = font->fdselect_subset[i];
  2167.             status = _cairo_array_append (&font->output, &data);
  2168.             if (unlikely (status))
  2169.                 return status;
  2170.         }
  2171.     } else {
  2172.         unsigned char byte;
  2173.         uint16_t word;
  2174.  
  2175.         status = _cairo_array_grow_by (&font->output, 9);
  2176.         if (unlikely (status))
  2177.             return status;
  2178.  
  2179.         byte = 3;
  2180.         status = _cairo_array_append (&font->output, &byte);
  2181.         assert (status == CAIRO_INT_STATUS_SUCCESS);
  2182.  
  2183.         word = cpu_to_be16 (1);
  2184.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  2185.         assert (status == CAIRO_INT_STATUS_SUCCESS);
  2186.  
  2187.         word = cpu_to_be16 (0);
  2188.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  2189.         assert (status == CAIRO_INT_STATUS_SUCCESS);
  2190.  
  2191.         byte = 0;
  2192.         status = _cairo_array_append (&font->output, &byte);
  2193.         assert (status == CAIRO_INT_STATUS_SUCCESS);
  2194.  
  2195.         word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
  2196.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  2197.         assert (status == CAIRO_INT_STATUS_SUCCESS);
  2198.     }
  2199.  
  2200.     return CAIRO_STATUS_SUCCESS;
  2201. }
  2202.  
  2203. /* Winansi to CFF standard strings mapping for characters 128 to 255 */
  2204. static const int winansi_to_cff_std_string[] = {
  2205.         /* 128 */
  2206.       0,   0, 117, 101, 118, 121, 112, 113,
  2207.     126, 122, 192, 107, 142,   0, 199,   0,
  2208.         /* 144 */
  2209.       0,  65,   8, 105, 119, 116, 111, 137,
  2210.     127, 153, 221, 108, 148,   0, 228, 198,
  2211.         /* 160 */
  2212.       0,  96,  97,  98, 103, 100, 160, 102,
  2213.     131, 170, 139, 106, 151,   0, 165, 128,
  2214.         /* 176 */
  2215.     161, 156, 164, 169, 125, 152, 115, 114,
  2216.     133, 150, 143, 120, 158, 155, 163, 123,
  2217.         /* 192 */
  2218.     174, 171, 172, 176, 173, 175, 138, 177,
  2219.     181, 178, 179, 180, 185, 182, 183, 184,
  2220.         /* 208 */
  2221.     154, 186, 190, 187, 188, 191, 189, 168,
  2222.     141, 196, 193, 194, 195, 197, 157, 149,
  2223.         /* 224 */
  2224.     203, 200, 201, 205, 202, 204, 144, 206,
  2225.     210, 207, 208, 209, 214, 211, 212, 213,
  2226.         /* 240 */
  2227.     167, 215, 219, 216, 217, 220, 218, 159,
  2228.     147, 225, 222, 223, 224, 226, 162, 227,
  2229. };
  2230.  
  2231. static int
  2232. cairo_cff_font_get_sid_for_winansi_char (cairo_cff_font_t  *font, int ch)
  2233. {
  2234.     int sid;
  2235.  
  2236.     if (ch == 39) {
  2237.         sid = 104;
  2238.  
  2239.     } else if (ch == 96) {
  2240.         sid = 124;
  2241.  
  2242.     } else if (ch >= 32 && ch <= 126) {
  2243.         sid = ch - 31;
  2244.  
  2245.     } else if (ch == 128) {
  2246.         assert (font->euro_sid >= NUM_STD_STRINGS);
  2247.         sid = font->euro_sid;
  2248.  
  2249.     } else if (ch >= 128 && ch <= 255) {
  2250.         sid = winansi_to_cff_std_string[ch - 128];
  2251.  
  2252.     } else {
  2253.         sid = 0;
  2254.     }
  2255.  
  2256.     return sid;
  2257. }
  2258.  
  2259. static cairo_status_t
  2260. cairo_cff_font_write_type1_charset (cairo_cff_font_t  *font)
  2261. {
  2262.     unsigned char format = 0;
  2263.     unsigned int i;
  2264.     int ch, sid;
  2265.     cairo_status_t status;
  2266.     uint16_t sid_be16;
  2267.  
  2268.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
  2269.     status = _cairo_array_append (&font->output, &format);
  2270.     if (unlikely (status))
  2271.         return status;
  2272.  
  2273.     for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
  2274.         ch = font->scaled_font_subset->to_latin_char[i];
  2275.         sid = cairo_cff_font_get_sid_for_winansi_char (font, ch);
  2276.         if (unlikely (status))
  2277.             return status;
  2278.  
  2279.         sid_be16 = cpu_to_be16(sid);
  2280.         status = _cairo_array_append_multiple (&font->output, &sid_be16, sizeof(sid_be16));
  2281.         if (unlikely (status))
  2282.             return status;
  2283.     }
  2284.  
  2285.     return CAIRO_STATUS_SUCCESS;
  2286. }
  2287.  
  2288. static cairo_status_t
  2289. cairo_cff_font_write_cid_charset (cairo_cff_font_t  *font)
  2290. {
  2291.     unsigned char byte;
  2292.     uint16_t word;
  2293.     cairo_status_t status;
  2294.  
  2295.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
  2296.     status = _cairo_array_grow_by (&font->output, 5);
  2297.     if (unlikely (status))
  2298.         return status;
  2299.  
  2300.     byte = 2;
  2301.     status = _cairo_array_append (&font->output, &byte);
  2302.     assert (status == CAIRO_STATUS_SUCCESS);
  2303.  
  2304.     word = cpu_to_be16 (1);
  2305.     status = _cairo_array_append_multiple (&font->output, &word, 2);
  2306.     assert (status == CAIRO_STATUS_SUCCESS);
  2307.  
  2308.     word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
  2309.     status = _cairo_array_append_multiple (&font->output, &word, 2);
  2310.     assert (status == CAIRO_STATUS_SUCCESS);
  2311.  
  2312.     return CAIRO_STATUS_SUCCESS;
  2313. }
  2314.  
  2315. static cairo_status_t
  2316. cairo_cff_font_write_charstrings (cairo_cff_font_t  *font)
  2317. {
  2318.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
  2319.  
  2320.     return cff_index_write (&font->charstrings_subset_index, &font->output);
  2321. }
  2322.  
  2323. static cairo_status_t
  2324. cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
  2325. {
  2326.     unsigned int i;
  2327.     cairo_int_status_t status;
  2328.     unsigned int offset_array;
  2329.     uint32_t *offset_array_ptr;
  2330.     int offset_base;
  2331.     uint16_t count;
  2332.     uint8_t offset_size = 4;
  2333.  
  2334.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
  2335.     count = cpu_to_be16 (font->num_subset_fontdicts);
  2336.     status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
  2337.     if (unlikely (status))
  2338.         return status;
  2339.     status = _cairo_array_append (&font->output, &offset_size);
  2340.     if (unlikely (status))
  2341.         return status;
  2342.  
  2343.     offset_array = _cairo_array_num_elements (&font->output);
  2344.     status = _cairo_array_allocate (&font->output,
  2345.                                     (font->num_subset_fontdicts + 1)*offset_size,
  2346.                                     (void **) &offset_array_ptr);
  2347.     if (unlikely (status))
  2348.         return status;
  2349.     offset_base = _cairo_array_num_elements (&font->output) - 1;
  2350.     *offset_array_ptr = cpu_to_be32(1);
  2351.     offset_array += sizeof(uint32_t);
  2352.     for (i = 0; i < font->num_subset_fontdicts; i++) {
  2353.         status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
  2354.                                  &font->output);
  2355.         if (unlikely (status))
  2356.             return status;
  2357.  
  2358.         offset_array_ptr = (uint32_t *) _cairo_array_index (&font->output, offset_array);
  2359.         *offset_array_ptr = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
  2360.         offset_array += sizeof(uint32_t);
  2361.     }
  2362.  
  2363.     return CAIRO_STATUS_SUCCESS;
  2364. }
  2365.  
  2366. static cairo_status_t
  2367. cairo_cff_font_write_private_dict (cairo_cff_font_t   *font,
  2368.                                    int                 dict_num,
  2369.                                    cairo_hash_table_t *parent_dict,
  2370.                                    cairo_hash_table_t *private_dict)
  2371. {
  2372.     int offset;
  2373.     int size;
  2374.     unsigned char buf[10];
  2375.     unsigned char *buf_end;
  2376.     unsigned char *p;
  2377.     cairo_status_t status;
  2378.  
  2379.     /* Write private dict and update offset and size in top dict */
  2380.     font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
  2381.     status = cff_dict_write (private_dict, &font->output);
  2382.     if (unlikely (status))
  2383.         return status;
  2384.  
  2385.     size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
  2386.     /* private entry has two operands - size and offset */
  2387.     buf_end = encode_integer_max (buf, size);
  2388.     buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
  2389.     offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
  2390.     assert (offset > 0);
  2391.     p = _cairo_array_index (&font->output, offset);
  2392.     memcpy (p, buf, buf_end - buf);
  2393.  
  2394.     return CAIRO_STATUS_SUCCESS;
  2395. }
  2396.  
  2397. static cairo_status_t
  2398. cairo_cff_font_write_local_sub (cairo_cff_font_t   *font,
  2399.                                 int                 dict_num,
  2400.                                 cairo_hash_table_t *private_dict,
  2401.                                 cairo_array_t      *local_sub_index,
  2402.                                 cairo_bool_t       *local_subs_used)
  2403. {
  2404.     int offset;
  2405.     int size;
  2406.     unsigned char buf[10];
  2407.     unsigned char *buf_end;
  2408.     unsigned char *p;
  2409.     cairo_status_t status;
  2410.     unsigned int i;
  2411.     unsigned char return_op = TYPE2_return;
  2412.  
  2413.     if (_cairo_array_num_elements (local_sub_index) > 0) {
  2414.         /* Write local subroutines and update offset in private
  2415.          * dict. Local subroutines offset is relative to start of
  2416.          * private dict */
  2417.         offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
  2418.         buf_end = encode_integer_max (buf, offset);
  2419.         offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
  2420.         assert (offset > 0);
  2421.         p = _cairo_array_index (&font->output, offset);
  2422.         memcpy (p, buf, buf_end - buf);
  2423.  
  2424.         /* poppler and fontforge don't like zero length subroutines so
  2425.          * we replace unused subroutines with a 'return' instruction.
  2426.          */
  2427.         if (font->subset_subroutines) {
  2428.             for (i = 0; i < _cairo_array_num_elements (local_sub_index); i++) {
  2429.                 if (! local_subs_used[i])
  2430.                     cff_index_set_object (local_sub_index, i, &return_op, 1);
  2431.             }
  2432.         }
  2433.         status = cff_index_write (local_sub_index, &font->output);
  2434.         if (unlikely (status))
  2435.             return status;
  2436.     }
  2437.  
  2438.     return CAIRO_STATUS_SUCCESS;
  2439. }
  2440.  
  2441.  
  2442. static cairo_status_t
  2443. cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t  *font)
  2444. {
  2445.     unsigned int i;
  2446.     cairo_int_status_t status;
  2447.  
  2448.     if (font->is_cid) {
  2449.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  2450.             status = cairo_cff_font_write_private_dict (
  2451.                             font,
  2452.                             i,
  2453.                             font->fd_dict[font->fd_subset_map[i]],
  2454.                             font->fd_private_dict[font->fd_subset_map[i]]);
  2455.             if (unlikely (status))
  2456.                 return status;
  2457.         }
  2458.  
  2459.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  2460.             status = cairo_cff_font_write_local_sub (
  2461.                             font,
  2462.                             i,
  2463.                             font->fd_private_dict[font->fd_subset_map[i]],
  2464.                             &font->fd_local_sub_index[font->fd_subset_map[i]],
  2465.                             font->fd_local_subs_used[font->fd_subset_map[i]]);
  2466.             if (unlikely (status))
  2467.                 return status;
  2468.         }
  2469.     } else {
  2470.         status = cairo_cff_font_write_private_dict (font,
  2471.                                                     0,
  2472.                                                     font->fd_dict[0],
  2473.                                                     font->private_dict);
  2474.         if (unlikely (status))
  2475.             return status;
  2476.  
  2477.         status = cairo_cff_font_write_local_sub (font,
  2478.                                                  0,
  2479.                                                  font->private_dict,
  2480.                                                  &font->local_sub_index,
  2481.                                                  font->local_subs_used);
  2482.         if (unlikely (status))
  2483.             return status;
  2484.     }
  2485.  
  2486.     return CAIRO_STATUS_SUCCESS;
  2487. }
  2488.  
  2489. static cairo_status_t
  2490. cairo_cff_font_write_type1_private_dict_and_local_sub (cairo_cff_font_t  *font)
  2491. {
  2492.     cairo_int_status_t status;
  2493.  
  2494.     status = cairo_cff_font_write_private_dict (font,
  2495.                                                 0,
  2496.                                                 font->top_dict,
  2497.                                                 font->private_dict);
  2498.     if (unlikely (status))
  2499.         return status;
  2500.  
  2501.     status = cairo_cff_font_write_local_sub (font,
  2502.                                              0,
  2503.                                              font->private_dict,
  2504.                                              &font->local_sub_index,
  2505.                                              font->local_subs_used);
  2506.     if (unlikely (status))
  2507.         return status;
  2508.  
  2509.     return CAIRO_STATUS_SUCCESS;
  2510. }
  2511.  
  2512.  
  2513. typedef cairo_status_t
  2514. (*font_write_t) (cairo_cff_font_t *font);
  2515.  
  2516. static const font_write_t font_write_cid_funcs[] = {
  2517.     cairo_cff_font_write_header,
  2518.     cairo_cff_font_write_name,
  2519.     cairo_cff_font_write_top_dict,
  2520.     cairo_cff_font_write_strings,
  2521.     cairo_cff_font_write_global_subrs,
  2522.     cairo_cff_font_write_cid_charset,
  2523.     cairo_cff_font_write_fdselect,
  2524.     cairo_cff_font_write_charstrings,
  2525.     cairo_cff_font_write_cid_fontdict,
  2526.     cairo_cff_font_write_cid_private_dict_and_local_sub,
  2527. };
  2528.  
  2529. static const font_write_t font_write_type1_funcs[] = {
  2530.     cairo_cff_font_write_header,
  2531.     cairo_cff_font_write_name,
  2532.     cairo_cff_font_write_top_dict,
  2533.     cairo_cff_font_write_strings,
  2534.     cairo_cff_font_write_global_subrs,
  2535.     cairo_cff_font_write_encoding,
  2536.     cairo_cff_font_write_type1_charset,
  2537.     cairo_cff_font_write_charstrings,
  2538.     cairo_cff_font_write_type1_private_dict_and_local_sub,
  2539. };
  2540.  
  2541. static cairo_status_t
  2542. cairo_cff_font_write_subset (cairo_cff_font_t *font)
  2543. {
  2544.     cairo_int_status_t status;
  2545.     unsigned int i;
  2546.  
  2547.     if (font->scaled_font_subset->is_latin) {
  2548.         for (i = 0; i < ARRAY_LENGTH (font_write_type1_funcs); i++) {
  2549.             status = font_write_type1_funcs[i] (font);
  2550.             if (unlikely (status))
  2551.                 return status;
  2552.         }
  2553.     } else {
  2554.         for (i = 0; i < ARRAY_LENGTH (font_write_cid_funcs); i++) {
  2555.             status = font_write_cid_funcs[i] (font);
  2556.             if (unlikely (status))
  2557.                 return status;
  2558.         }
  2559.     }
  2560.  
  2561.     return CAIRO_STATUS_SUCCESS;
  2562. }
  2563.  
  2564. static cairo_int_status_t
  2565. cairo_cff_font_generate (cairo_cff_font_t  *font,
  2566.                          const char       **data,
  2567.                          unsigned long     *length)
  2568. {
  2569.     cairo_int_status_t status;
  2570.  
  2571.     status = cairo_cff_font_read_font (font);
  2572.     if (unlikely (status))
  2573.         return status;
  2574.  
  2575.     /* If the PS name is not found, create a CairoFont-x-y name. */
  2576.     if (font->ps_name == NULL) {
  2577.         font->ps_name = malloc (30);
  2578.         if (unlikely (font->ps_name == NULL))
  2579.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2580.  
  2581.         snprintf(font->ps_name, 30, "CairoFont-%u-%u",
  2582.                  font->scaled_font_subset->font_id,
  2583.                  font->scaled_font_subset->subset_id);
  2584.     }
  2585.  
  2586.     status = cairo_cff_font_subset_font (font);
  2587.     if (unlikely (status))
  2588.         return status;
  2589.  
  2590.     status = cairo_cff_font_write_subset (font);
  2591.     if (unlikely (status))
  2592.         return status;
  2593.  
  2594.  
  2595.     *data = _cairo_array_index (&font->output, 0);
  2596.     *length = _cairo_array_num_elements (&font->output);
  2597.  
  2598.     return CAIRO_STATUS_SUCCESS;
  2599. }
  2600.  
  2601. static cairo_int_status_t
  2602. cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
  2603. {
  2604.     unsigned long size;
  2605.     unsigned long long_entry_size;
  2606.     unsigned long short_entry_size;
  2607.     unsigned int i;
  2608.     tt_hhea_t hhea;
  2609.     int num_hmetrics;
  2610.     unsigned char buf[10];
  2611.     int glyph_index;
  2612.     cairo_int_status_t status;
  2613.  
  2614.     size = sizeof (tt_hhea_t);
  2615.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2616.                                                  TT_TAG_hhea, 0,
  2617.                                                  (unsigned char*) &hhea, &size);
  2618.     if (unlikely (status))
  2619.         return status;
  2620.     num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
  2621.  
  2622.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  2623.         glyph_index = font->scaled_font_subset->glyphs[i];
  2624.         long_entry_size = 2 * sizeof (int16_t);
  2625.         short_entry_size = sizeof (int16_t);
  2626.         if (glyph_index < num_hmetrics) {
  2627.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2628.                                                          TT_TAG_hmtx,
  2629.                                                          glyph_index * long_entry_size,
  2630.                                                          buf, &short_entry_size);
  2631.             if (unlikely (status))
  2632.                 return status;
  2633.         }
  2634.         else
  2635.         {
  2636.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2637.                                                          TT_TAG_hmtx,
  2638.                                                          (num_hmetrics - 1) * long_entry_size,
  2639.                                                          buf, &short_entry_size);
  2640.             if (unlikely (status))
  2641.                 return status;
  2642.         }
  2643.         font->widths[i] = be16_to_cpu (*((int16_t*)buf));
  2644.     }
  2645.  
  2646.     return CAIRO_STATUS_SUCCESS;
  2647. }
  2648.  
  2649. static cairo_bool_t
  2650. check_fontdata_is_cff (const unsigned char *data, long length)
  2651. {
  2652.     cff_header_t *header;
  2653.  
  2654.     if (length < (long)sizeof (cff_header_t))
  2655.         return FALSE;
  2656.  
  2657.     header = (cff_header_t *) data;
  2658.     if (header->major == 1 &&
  2659.         header->minor == 0 &&
  2660.         header->header_size == 4)
  2661.     {
  2662.         return TRUE;
  2663.     }
  2664.  
  2665.     return FALSE;
  2666. }
  2667.  
  2668. static cairo_int_status_t
  2669. _cairo_cff_font_load_opentype_cff (cairo_cff_font_t  *font)
  2670. {
  2671.     const cairo_scaled_font_backend_t *backend = font->backend;
  2672.     cairo_status_t status;
  2673.     tt_head_t head;
  2674.     tt_hhea_t hhea;
  2675.     unsigned long size, data_length;
  2676.  
  2677.     if (!backend->load_truetype_table)
  2678.         return CAIRO_INT_STATUS_UNSUPPORTED;
  2679.  
  2680.     data_length = 0;
  2681.     status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2682.                                            TT_TAG_CFF, 0, NULL, &data_length);
  2683.     if (status)
  2684.         return status;
  2685.  
  2686.     size = sizeof (tt_head_t);
  2687.     status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2688.                                            TT_TAG_head, 0,
  2689.                                            (unsigned char *) &head, &size);
  2690.     if (unlikely (status))
  2691.         return status;
  2692.  
  2693.     size = sizeof (tt_hhea_t);
  2694.     status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2695.                                            TT_TAG_hhea, 0,
  2696.                                            (unsigned char *) &hhea, &size);
  2697.     if (unlikely (status))
  2698.         return status;
  2699.  
  2700.     size = 0;
  2701.     status = backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2702.                                            TT_TAG_hmtx, 0, NULL, &size);
  2703.     if (unlikely (status))
  2704.         return status;
  2705.  
  2706.     font->x_min = (int16_t) be16_to_cpu (head.x_min);
  2707.     font->y_min = (int16_t) be16_to_cpu (head.y_min);
  2708.     font->x_max = (int16_t) be16_to_cpu (head.x_max);
  2709.     font->y_max = (int16_t) be16_to_cpu (head.y_max);
  2710.     font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
  2711.     font->descent = (int16_t) be16_to_cpu (hhea.descender);
  2712.     font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
  2713.     if (font->units_per_em == 0)
  2714.         font->units_per_em = 1000;
  2715.  
  2716.     font->font_name = NULL;
  2717.     status = _cairo_truetype_read_font_name (font->scaled_font_subset->scaled_font,
  2718.                                              &font->ps_name,
  2719.                                              &font->font_name);
  2720.     if (_cairo_status_is_error (status))
  2721.         return status;
  2722.  
  2723.     font->is_opentype = TRUE;
  2724.     font->data_length = data_length;
  2725.     font->data = malloc (data_length);
  2726.     if (unlikely (font->data == NULL))
  2727.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2728.  
  2729.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  2730.                                                  TT_TAG_CFF, 0, font->data,
  2731.                                                  &font->data_length);
  2732.     if (unlikely (status))
  2733.         return status;
  2734.  
  2735.     if (!check_fontdata_is_cff (font->data, data_length))
  2736.         return CAIRO_INT_STATUS_UNSUPPORTED;
  2737.  
  2738.     return CAIRO_STATUS_SUCCESS;
  2739. }
  2740.  
  2741. static cairo_int_status_t
  2742. _cairo_cff_font_load_cff (cairo_cff_font_t  *font)
  2743. {
  2744.     const cairo_scaled_font_backend_t *backend = font->backend;
  2745.     cairo_status_t status;
  2746.     unsigned long data_length;
  2747.  
  2748.     if (!backend->load_type1_data)
  2749.         return CAIRO_INT_STATUS_UNSUPPORTED;
  2750.  
  2751.     data_length = 0;
  2752.     status = backend->load_type1_data (font->scaled_font_subset->scaled_font,
  2753.                                       0, NULL, &data_length);
  2754.     if (unlikely (status))
  2755.         return status;
  2756.  
  2757.     font->font_name = NULL;
  2758.     font->is_opentype = FALSE;
  2759.     font->data_length = data_length;
  2760.     font->data = malloc (data_length);
  2761.     if (unlikely (font->data == NULL))
  2762.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2763.  
  2764.     status = font->backend->load_type1_data (font->scaled_font_subset->scaled_font,
  2765.                                              0, font->data, &font->data_length);
  2766.     if (unlikely (status))
  2767.         return status;
  2768.  
  2769.     if (!check_fontdata_is_cff (font->data, data_length))
  2770.         return CAIRO_INT_STATUS_UNSUPPORTED;
  2771.  
  2772.     return CAIRO_STATUS_SUCCESS;
  2773. }
  2774.  
  2775. static cairo_int_status_t
  2776. _cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
  2777.                         cairo_cff_font_t           **font_return,
  2778.                         const char                  *subset_name)
  2779. {
  2780.     const cairo_scaled_font_backend_t *backend;
  2781.     cairo_int_status_t status;
  2782.     cairo_cff_font_t *font;
  2783.  
  2784.     backend = scaled_font_subset->scaled_font->backend;
  2785.  
  2786.     /* We need to use a fallback font generated from the synthesized outlines. */
  2787.     if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
  2788.         return CAIRO_INT_STATUS_UNSUPPORTED;
  2789.  
  2790.     font = calloc (1, sizeof (cairo_cff_font_t));
  2791.     if (unlikely (font == NULL))
  2792.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2793.  
  2794.     font->backend = backend;
  2795.     font->scaled_font_subset = scaled_font_subset;
  2796.  
  2797.     status = _cairo_cff_font_load_opentype_cff (font);
  2798.     if (status == CAIRO_INT_STATUS_UNSUPPORTED)
  2799.         status = _cairo_cff_font_load_cff (font);
  2800.     if (status)
  2801.         goto fail1;
  2802.  
  2803.     font->data_end = font->data + font->data_length;
  2804.     _cairo_array_init (&font->output, sizeof (char));
  2805.     status = _cairo_array_grow_by (&font->output, 4096);
  2806.     if (unlikely (status))
  2807.         goto fail2;
  2808.  
  2809.     font->subset_font_name = strdup (subset_name);
  2810.     if (unlikely (font->subset_font_name == NULL)) {
  2811.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2812.         goto fail2;
  2813.     }
  2814.  
  2815.     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
  2816.     if (unlikely (font->widths == NULL)) {
  2817.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2818.         goto fail3;
  2819.     }
  2820.  
  2821.     if (font->is_opentype) {
  2822.         status = cairo_cff_font_create_set_widths (font);
  2823.         if (unlikely (status))
  2824.             goto fail4;
  2825.     }
  2826.  
  2827.     status = cff_dict_init (&font->top_dict);
  2828.     if (unlikely (status))
  2829.         goto fail4;
  2830.  
  2831.     status = cff_dict_init (&font->private_dict);
  2832.     if (unlikely (status))
  2833.         goto fail5;
  2834.  
  2835.     cff_index_init (&font->strings_index);
  2836.     cff_index_init (&font->charstrings_index);
  2837.     cff_index_init (&font->global_sub_index);
  2838.     cff_index_init (&font->local_sub_index);
  2839.     cff_index_init (&font->charstrings_subset_index);
  2840.     cff_index_init (&font->strings_subset_index);
  2841.     font->euro_sid = 0;
  2842.     font->fdselect = NULL;
  2843.     font->fd_dict = NULL;
  2844.     font->fd_private_dict = NULL;
  2845.     font->fd_local_sub_index = NULL;
  2846.     font->fd_local_sub_bias = NULL;
  2847.     font->fdselect_subset = NULL;
  2848.     font->fd_subset_map = NULL;
  2849.     font->private_dict_offset = NULL;
  2850.     font->global_subs_used = NULL;
  2851.     font->local_subs_used = NULL;
  2852.     font->fd_local_subs_used = NULL;
  2853.  
  2854.     *font_return = font;
  2855.  
  2856.     return CAIRO_STATUS_SUCCESS;
  2857.  
  2858. fail5:
  2859.     _cairo_hash_table_destroy (font->top_dict);
  2860. fail4:
  2861.     free (font->widths);
  2862. fail3:
  2863.     free (font->subset_font_name);
  2864. fail2:
  2865.     free (font->ps_name);
  2866.     _cairo_array_fini (&font->output);
  2867. fail1:
  2868.     free (font->data);
  2869.     free (font->font_name);
  2870.     free (font);
  2871.  
  2872.     return status;
  2873. }
  2874.  
  2875. static void
  2876. cairo_cff_font_destroy (cairo_cff_font_t *font)
  2877. {
  2878.     unsigned int i;
  2879.  
  2880.     free (font->widths);
  2881.     free (font->font_name);
  2882.     free (font->ps_name);
  2883.     free (font->subset_font_name);
  2884.     _cairo_array_fini (&font->output);
  2885.     cff_dict_fini (font->top_dict);
  2886.     cff_dict_fini (font->private_dict);
  2887.     cff_index_fini (&font->strings_index);
  2888.     cff_index_fini (&font->charstrings_index);
  2889.     cff_index_fini (&font->global_sub_index);
  2890.     cff_index_fini (&font->local_sub_index);
  2891.     cff_index_fini (&font->charstrings_subset_index);
  2892.     cff_index_fini (&font->strings_subset_index);
  2893.  
  2894.     /* If we bailed out early as a result of an error some of the
  2895.      * following cairo_cff_font_t members may still be NULL */
  2896.     if (font->fd_dict) {
  2897.         for (i = 0; i < font->num_fontdicts; i++) {
  2898.             if (font->fd_dict[i])
  2899.                 cff_dict_fini (font->fd_dict[i]);
  2900.         }
  2901.         free (font->fd_dict);
  2902.     }
  2903.     free (font->global_subs_used);
  2904.     free (font->local_subs_used);
  2905.     free (font->fd_subset_map);
  2906.     free (font->private_dict_offset);
  2907.  
  2908.     if (font->is_cid) {
  2909.         free (font->fdselect);
  2910.         free (font->fdselect_subset);
  2911.         if (font->fd_private_dict) {
  2912.             for (i = 0; i < font->num_fontdicts; i++) {
  2913.                 if (font->fd_private_dict[i])
  2914.                     cff_dict_fini (font->fd_private_dict[i]);
  2915.             }
  2916.             free (font->fd_private_dict);
  2917.         }
  2918.         if (font->fd_local_sub_index) {
  2919.             for (i = 0; i < font->num_fontdicts; i++)
  2920.                 cff_index_fini (&font->fd_local_sub_index[i]);
  2921.             free (font->fd_local_sub_index);
  2922.         }
  2923.         free (font->fd_local_sub_bias);
  2924.         if (font->fd_local_subs_used) {
  2925.             for (i = 0; i < font->num_fontdicts; i++) {
  2926.                 free (font->fd_local_subs_used[i]);
  2927.             }
  2928.             free (font->fd_local_subs_used);
  2929.         }
  2930.         free (font->fd_default_width);
  2931.         free (font->fd_nominal_width);
  2932.     }
  2933.  
  2934.     free (font->data);
  2935.  
  2936.     free (font);
  2937. }
  2938.  
  2939. cairo_status_t
  2940. _cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
  2941.                         const char                  *subset_name,
  2942.                         cairo_scaled_font_subset_t  *font_subset)
  2943. {
  2944.     cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
  2945.     cairo_status_t status;
  2946.     const char *data = NULL; /* squelch bogus compiler warning */
  2947.     unsigned long length = 0; /* squelch bogus compiler warning */
  2948.     unsigned int i;
  2949.  
  2950.     status = _cairo_cff_font_create (font_subset, &font, subset_name);
  2951.     if (unlikely (status))
  2952.         return status;
  2953.  
  2954.     status = cairo_cff_font_generate (font, &data, &length);
  2955.     if (unlikely (status))
  2956.         goto fail1;
  2957.  
  2958.     cff_subset->ps_name = strdup (font->ps_name);
  2959.     if (unlikely (cff_subset->ps_name == NULL)) {
  2960.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2961.         goto fail1;
  2962.     }
  2963.  
  2964.     if (font->font_name) {
  2965.         cff_subset->family_name_utf8 = strdup (font->font_name);
  2966.         if (cff_subset->family_name_utf8 == NULL) {
  2967.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2968.             goto fail2;
  2969.         }
  2970.     } else {
  2971.         cff_subset->family_name_utf8 = NULL;
  2972.     }
  2973.  
  2974.     cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
  2975.     if (unlikely (cff_subset->widths == NULL)) {
  2976.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2977.         goto fail3;
  2978.     }
  2979.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
  2980.         cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
  2981.  
  2982.     cff_subset->x_min = (double)font->x_min/font->units_per_em;
  2983.     cff_subset->y_min = (double)font->y_min/font->units_per_em;
  2984.     cff_subset->x_max = (double)font->x_max/font->units_per_em;
  2985.     cff_subset->y_max = (double)font->y_max/font->units_per_em;
  2986.     cff_subset->ascent = (double)font->ascent/font->units_per_em;
  2987.     cff_subset->descent = (double)font->descent/font->units_per_em;
  2988.  
  2989.     cff_subset->data = malloc (length);
  2990.     if (unlikely (cff_subset->data == NULL)) {
  2991.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2992.         goto fail4;
  2993.     }
  2994.  
  2995.     memcpy (cff_subset->data, data, length);
  2996.     cff_subset->data_length = length;
  2997.  
  2998.     cairo_cff_font_destroy (font);
  2999.  
  3000.     return CAIRO_STATUS_SUCCESS;
  3001.  
  3002.  fail4:
  3003.     free (cff_subset->widths);
  3004.  fail3:
  3005.     free (cff_subset->family_name_utf8);
  3006.  fail2:
  3007.     free (cff_subset->ps_name);
  3008.  fail1:
  3009.     cairo_cff_font_destroy (font);
  3010.  
  3011.     return status;
  3012. }
  3013.  
  3014. void
  3015. _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
  3016. {
  3017.     free (subset->ps_name);
  3018.     free (subset->family_name_utf8);
  3019.     free (subset->widths);
  3020.     free (subset->data);
  3021. }
  3022.  
  3023. cairo_bool_t
  3024. _cairo_cff_scaled_font_is_cid_cff (cairo_scaled_font_t *scaled_font)
  3025. {
  3026.     const cairo_scaled_font_backend_t *backend;
  3027.     cairo_int_status_t status;
  3028.     unsigned char *data;
  3029.     unsigned long data_length;
  3030.     unsigned char *current_ptr;
  3031.     unsigned char *data_end;
  3032.     cff_header_t  *header;
  3033.     cff_index_element_t *element;
  3034.     cairo_hash_table_t  *top_dict;
  3035.     cairo_array_t index;
  3036.     int size;
  3037.     cairo_bool_t is_cid = FALSE;
  3038.  
  3039.     backend = scaled_font->backend;
  3040.     data = NULL;
  3041.     data_length = 0;
  3042.     status = CAIRO_INT_STATUS_UNSUPPORTED;
  3043.     /* Try to load an OpenType/CFF font */
  3044.     if (backend->load_truetype_table &&
  3045.         (status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
  3046.                                                 0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
  3047.     {
  3048.         data = malloc (data_length);
  3049.         if (unlikely (data == NULL)) {
  3050.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3051.             return FALSE;
  3052.         }
  3053.  
  3054.         status = backend->load_truetype_table (scaled_font, TT_TAG_CFF,
  3055.                                            0, data, &data_length);
  3056.         if (unlikely (status))
  3057.             goto fail1;
  3058.     }
  3059.     /* Try to load a CFF font */
  3060.     if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
  3061.         backend->load_type1_data &&
  3062.         (status = backend->load_type1_data (scaled_font,
  3063.                                             0, NULL, &data_length)) == CAIRO_INT_STATUS_SUCCESS)
  3064.     {
  3065.         data = malloc (data_length);
  3066.         if (unlikely (data == NULL)) {
  3067.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3068.             return FALSE;
  3069.         }
  3070.  
  3071.         status = backend->load_type1_data (scaled_font, 0, data, &data_length);
  3072.         if (unlikely (status))
  3073.             goto fail1;
  3074.     }
  3075.     if (status)
  3076.         goto fail1;
  3077.  
  3078.     /* Check if it looks like a CFF font */
  3079.     if (!check_fontdata_is_cff (data, data_length))
  3080.         goto fail1;
  3081.  
  3082.     data_end = data + data_length;
  3083.  
  3084.     /* skip header */
  3085.     if (data_length < sizeof (cff_header_t))
  3086.         goto fail1;
  3087.  
  3088.     header = (cff_header_t *) data;
  3089.     current_ptr = data + header->header_size;
  3090.  
  3091.     /* skip name */
  3092.     cff_index_init (&index);
  3093.     status = cff_index_read (&index, &current_ptr, data_end);
  3094.     cff_index_fini (&index);
  3095.  
  3096.     if (status)
  3097.         goto fail1;
  3098.  
  3099.     /* read top dict */
  3100.     cff_index_init (&index);
  3101.     status = cff_index_read (&index, &current_ptr, data_end);
  3102.     if (unlikely (status))
  3103.         goto fail2;
  3104.  
  3105.     status = cff_dict_init (&top_dict);
  3106.     if (unlikely (status))
  3107.         goto fail2;
  3108.  
  3109.     element = _cairo_array_index (&index, 0);
  3110.     status = cff_dict_read (top_dict, element->data, element->length);
  3111.     if (unlikely (status))
  3112.         goto fail3;
  3113.  
  3114.     /* check for ROS operator indicating a CID font */
  3115.     if (cff_dict_get_operands (top_dict, ROS_OP, &size) != NULL)
  3116.         is_cid = TRUE;
  3117.  
  3118. fail3:
  3119.     cff_dict_fini (top_dict);
  3120.  
  3121. fail2:
  3122.     cff_index_fini (&index);
  3123.  
  3124. fail1:
  3125.     free (data);
  3126.  
  3127.     return is_cid;
  3128. }
  3129.  
  3130. static cairo_int_status_t
  3131. _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t  *scaled_font_subset,
  3132.                                  cairo_cff_font_t           **font_return,
  3133.                                  const char                  *subset_name)
  3134. {
  3135.     cairo_status_t status;
  3136.     cairo_cff_font_t *font;
  3137.  
  3138.     font = malloc (sizeof (cairo_cff_font_t));
  3139.     if (unlikely (font == NULL))
  3140.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3141.  
  3142.     font->backend = NULL;
  3143.     font->scaled_font_subset = scaled_font_subset;
  3144.  
  3145.     _cairo_array_init (&font->output, sizeof (char));
  3146.     status = _cairo_array_grow_by (&font->output, 4096);
  3147.     if (unlikely (status))
  3148.         goto fail1;
  3149.  
  3150.     font->subset_font_name = strdup (subset_name);
  3151.     if (unlikely (font->subset_font_name == NULL)) {
  3152.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3153.         goto fail1;
  3154.     }
  3155.  
  3156.     font->ps_name = strdup (subset_name);
  3157.     if (unlikely (font->ps_name == NULL)) {
  3158.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3159.         goto fail2;
  3160.     }
  3161.     font->font_name = NULL;
  3162.  
  3163.     font->x_min = 0;
  3164.     font->y_min = 0;
  3165.     font->x_max = 0;
  3166.     font->y_max = 0;
  3167.     font->ascent = 0;
  3168.     font->descent = 0;
  3169.  
  3170.     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
  3171.     if (unlikely (font->widths == NULL)) {
  3172.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3173.         goto fail3;
  3174.     }
  3175.  
  3176.     font->data_length = 0;
  3177.     font->data = NULL;
  3178.     font->data_end = NULL;
  3179.  
  3180.     status = cff_dict_init (&font->top_dict);
  3181.     if (unlikely (status))
  3182.         goto fail4;
  3183.  
  3184.     status = cff_dict_init (&font->private_dict);
  3185.     if (unlikely (status))
  3186.         goto fail5;
  3187.  
  3188.     cff_index_init (&font->strings_index);
  3189.     cff_index_init (&font->charstrings_index);
  3190.     cff_index_init (&font->global_sub_index);
  3191.     cff_index_init (&font->local_sub_index);
  3192.     cff_index_init (&font->charstrings_subset_index);
  3193.     cff_index_init (&font->strings_subset_index);
  3194.     font->global_subs_used = NULL;
  3195.     font->local_subs_used = NULL;
  3196.     font->subset_subroutines = FALSE;
  3197.     font->fdselect = NULL;
  3198.     font->fd_dict = NULL;
  3199.     font->fd_private_dict = NULL;
  3200.     font->fd_local_sub_index = NULL;
  3201.     font->fdselect_subset = NULL;
  3202.     font->fd_subset_map = NULL;
  3203.     font->private_dict_offset = NULL;
  3204.  
  3205.     *font_return = font;
  3206.  
  3207.     return CAIRO_STATUS_SUCCESS;
  3208.  
  3209. fail5:
  3210.     _cairo_hash_table_destroy (font->top_dict);
  3211. fail4:
  3212.     free (font->widths);
  3213. fail3:
  3214.     free (font->font_name);
  3215.     free (font->ps_name);
  3216. fail2:
  3217.     free (font->subset_font_name);
  3218. fail1:
  3219.     _cairo_array_fini (&font->output);
  3220.     free (font);
  3221.     return status;
  3222. }
  3223.  
  3224. static cairo_int_status_t
  3225. cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
  3226.                                   cairo_type2_charstrings_t  *type2_subset,
  3227.                                   const char                **data,
  3228.                                   unsigned long              *length)
  3229. {
  3230.     cairo_int_status_t status;
  3231.     cff_header_t header;
  3232.     cairo_array_t *charstring;
  3233.     unsigned char buf[40];
  3234.     unsigned char *end_buf, *end_buf2;
  3235.     unsigned int i;
  3236.     int sid;
  3237.  
  3238.     /* Create header */
  3239.     header.major = 1;
  3240.     header.minor = 0;
  3241.     header.header_size = 4;
  3242.     header.offset_size = 4;
  3243.     font->header = &header;
  3244.  
  3245.     /* Create Top Dict */
  3246.     font->is_cid = FALSE;
  3247.  
  3248.     snprintf((char*)buf, sizeof(buf), "CairoFont-%u-%u",
  3249.              font->scaled_font_subset->font_id,
  3250.              font->scaled_font_subset->subset_id);
  3251.     sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  3252.     status = cff_index_append_copy (&font->strings_subset_index,
  3253.                                     (unsigned char *)buf,
  3254.                                     strlen((char*)buf));
  3255.     if (unlikely (status))
  3256.         return status;
  3257.  
  3258.     end_buf = encode_integer (buf, sid);
  3259.     status = cff_dict_set_operands (font->top_dict, FULLNAME_OP,
  3260.                                     buf, end_buf - buf);
  3261.     if (unlikely (status))
  3262.         return status;
  3263.  
  3264.     status = cff_dict_set_operands (font->top_dict, FAMILYNAME_OP,
  3265.                                     buf, end_buf - buf);
  3266.     if (unlikely (status))
  3267.         return status;
  3268.  
  3269.     end_buf = encode_integer (buf, type2_subset->x_min);
  3270.     end_buf = encode_integer (end_buf, type2_subset->y_min);
  3271.     end_buf = encode_integer (end_buf, type2_subset->x_max);
  3272.     end_buf = encode_integer (end_buf, type2_subset->y_max);
  3273.     status = cff_dict_set_operands (font->top_dict,
  3274.                                     FONTBBOX_OP, buf, end_buf - buf);
  3275.     if (unlikely (status))
  3276.         return status;
  3277.  
  3278.     end_buf = encode_integer_max (buf, 0);
  3279.     status = cff_dict_set_operands (font->top_dict,
  3280.                                     CHARSTRINGS_OP, buf, end_buf - buf);
  3281.     if (unlikely (status))
  3282.         return status;
  3283.  
  3284.  
  3285.     if (font->scaled_font_subset->is_latin) {
  3286.         status = cff_dict_set_operands (font->top_dict,
  3287.                                         ENCODING_OP, buf, end_buf - buf);
  3288.         if (unlikely (status))
  3289.             return status;
  3290.  
  3291.         /* Private has two operands - size and offset */
  3292.         end_buf2 = encode_integer_max (end_buf, 0);
  3293.         cff_dict_set_operands (font->top_dict, PRIVATE_OP, buf, end_buf2 - buf);
  3294.         if (unlikely (status))
  3295.             return status;
  3296.  
  3297.     } else {
  3298.         status = cff_dict_set_operands (font->top_dict,
  3299.                                         FDSELECT_OP, buf, end_buf - buf);
  3300.         if (unlikely (status))
  3301.             return status;
  3302.  
  3303.         status = cff_dict_set_operands (font->top_dict,
  3304.                                         FDARRAY_OP, buf, end_buf - buf);
  3305.         if (unlikely (status))
  3306.             return status;
  3307.     }
  3308.  
  3309.     status = cff_dict_set_operands (font->top_dict,
  3310.                                     CHARSET_OP, buf, end_buf - buf);
  3311.     if (unlikely (status))
  3312.         return status;
  3313.  
  3314.     if (!font->scaled_font_subset->is_latin) {
  3315.         status = cairo_cff_font_set_ros_strings (font);
  3316.         if (unlikely (status))
  3317.             return status;
  3318.  
  3319.         /* Create CID FD dictionary */
  3320.         status = cairo_cff_font_create_cid_fontdict (font);
  3321.         if (unlikely (status))
  3322.             return status;
  3323.     } else {
  3324.         font->private_dict_offset = malloc (sizeof (int));
  3325.         if (unlikely (font->private_dict_offset == NULL))
  3326.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3327.     }
  3328.  
  3329.     /* Create charstrings */
  3330.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  3331.         charstring = _cairo_array_index(&type2_subset->charstrings, i);
  3332.  
  3333.         status = cff_index_append (&font->charstrings_subset_index,
  3334.                                    _cairo_array_index (charstring, 0),
  3335.                                    _cairo_array_num_elements (charstring));
  3336.  
  3337.         if (unlikely (status))
  3338.             return status;
  3339.     }
  3340.  
  3341.     if (font->scaled_font_subset->is_latin)
  3342.         status = cairo_cff_font_add_euro_charset_string (font);
  3343.  
  3344.     status = cairo_cff_font_write_subset (font);
  3345.     if (unlikely (status))
  3346.         return status;
  3347.  
  3348.     *data = _cairo_array_index (&font->output, 0);
  3349.     *length = _cairo_array_num_elements (&font->output);
  3350.  
  3351.     return CAIRO_STATUS_SUCCESS;
  3352. }
  3353.  
  3354. cairo_status_t
  3355. _cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
  3356.                           const char                  *subset_name,
  3357.                           cairo_scaled_font_subset_t  *font_subset)
  3358. {
  3359.     cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
  3360.     cairo_status_t status;
  3361.     const char *data = NULL; /* squelch bogus compiler warning */
  3362.     unsigned long length = 0; /* squelch bogus compiler warning */
  3363.     unsigned int i;
  3364.     cairo_type2_charstrings_t type2_subset;
  3365.  
  3366.     status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
  3367.     if (unlikely (status))
  3368.         return status;
  3369.  
  3370.     status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
  3371.     if (unlikely (status))
  3372.         goto fail1;
  3373.  
  3374.     status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
  3375.     if (unlikely (status))
  3376.         goto fail2;
  3377.  
  3378.     cff_subset->family_name_utf8 = NULL;
  3379.     cff_subset->ps_name = strdup (font->ps_name);
  3380.     if (unlikely (cff_subset->ps_name == NULL)) {
  3381.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3382.         goto fail2;
  3383.     }
  3384.  
  3385.     cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
  3386.     if (unlikely (cff_subset->widths == NULL)) {
  3387.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3388.         goto fail3;
  3389.     }
  3390.  
  3391.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
  3392.         cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
  3393.  
  3394.     cff_subset->x_min = (double)type2_subset.x_min/1000;
  3395.     cff_subset->y_min = (double)type2_subset.y_min/1000;
  3396.     cff_subset->x_max = (double)type2_subset.x_max/1000;
  3397.     cff_subset->y_max = (double)type2_subset.y_max/1000;
  3398.     cff_subset->ascent = (double)type2_subset.y_max/1000;
  3399.     cff_subset->descent = (double)type2_subset.y_min/1000;
  3400.  
  3401.     cff_subset->data = malloc (length);
  3402.     if (unlikely (cff_subset->data == NULL)) {
  3403.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  3404.         goto fail4;
  3405.     }
  3406.  
  3407.     memcpy (cff_subset->data, data, length);
  3408.     cff_subset->data_length = length;
  3409.  
  3410.     _cairo_type2_charstrings_fini (&type2_subset);
  3411.     cairo_cff_font_destroy (font);
  3412.  
  3413.     return CAIRO_STATUS_SUCCESS;
  3414.  
  3415.  fail4:
  3416.     free (cff_subset->widths);
  3417.  fail3:
  3418.     free (cff_subset->ps_name);
  3419.  fail2:
  3420.     _cairo_type2_charstrings_fini (&type2_subset);
  3421.  fail1:
  3422.     cairo_cff_font_destroy (font);
  3423.  
  3424.     return status;
  3425. }
  3426.  
  3427. void
  3428. _cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
  3429. {
  3430.     free (subset->ps_name);
  3431.     free (subset->widths);
  3432.     free (subset->data);
  3433. }
  3434.  
  3435. #endif /* CAIRO_HAS_FONT_SUBSET */
  3436.