Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* cairo - a vector graphics library with display and print output
  2.  *
  3.  * Copyright © 2006 Adrian Johnson
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it either under the terms of the GNU Lesser General Public
  7.  * License version 2.1 as published by the Free Software Foundation
  8.  * (the "LGPL") or, at your option, under the terms of the Mozilla
  9.  * Public License Version 1.1 (the "MPL"). If you do not alter this
  10.  * notice, a recipient may use your version of this file under either
  11.  * the MPL or the LGPL.
  12.  *
  13.  * You should have received a copy of the LGPL along with this library
  14.  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
  15.  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
  16.  * You should have received a copy of the MPL along with this library
  17.  * in the file COPYING-MPL-1.1
  18.  *
  19.  * The contents of this file are subject to the Mozilla Public License
  20.  * Version 1.1 (the "License"); you may not use this file except in
  21.  * compliance with the License. You may obtain a copy of the License at
  22.  * http://www.mozilla.org/MPL/
  23.  *
  24.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
  25.  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
  26.  * the specific language governing rights and limitations.
  27.  *
  28.  * The Original Code is the cairo graphics library.
  29.  *
  30.  * The Initial Developer of the Original Code is Adrian Johnson.
  31.  *
  32.  * Contributor(s):
  33.  *      Adrian Johnson <ajohnson@redneon.com>
  34.  *      Eugeniy Meshcheryakov <eugen@debian.org>
  35.  */
  36.  
  37. /*
  38.  * Useful links:
  39.  * http://www.adobe.com/devnet/font/pdfs/5176.CFF.pdf
  40.  */
  41.  
  42. #define _BSD_SOURCE /* for snprintf(), strdup() */
  43. #include "cairoint.h"
  44. #include "cairo-error-private.h"
  45.  
  46. #if CAIRO_HAS_FONT_SUBSET
  47.  
  48. #include "cairo-scaled-font-subsets-private.h"
  49. #include "cairo-truetype-subset-private.h"
  50. #include <string.h>
  51.  
  52. /* CFF Dict Operators. If the high byte is 0 the command is encoded
  53.  * with a single byte. */
  54. #define BASEFONTNAME_OP  0x0c16
  55. #define CIDCOUNT_OP      0x0c22
  56. #define CHARSET_OP       0x000f
  57. #define CHARSTRINGS_OP   0x0011
  58. #define COPYRIGHT_OP     0x0c00
  59. #define ENCODING_OP      0x0010
  60. #define FAMILYNAME_OP    0x0003
  61. #define FDARRAY_OP       0x0c24
  62. #define FDSELECT_OP      0x0c25
  63. #define FONTBBOX_OP      0x0005
  64. #define FONTNAME_OP      0x0c26
  65. #define FULLNAME_OP      0x0002
  66. #define LOCAL_SUB_OP     0x0013
  67. #define NOTICE_OP        0x0001
  68. #define POSTSCRIPT_OP    0x0c15
  69. #define PRIVATE_OP       0x0012
  70. #define ROS_OP           0x0c1e
  71. #define UNIQUEID_OP      0x000d
  72. #define VERSION_OP       0x0000
  73. #define WEIGHT_OP        0x0004
  74. #define XUID_OP          0x000e
  75.  
  76. #define NUM_STD_STRINGS 391
  77.  
  78. typedef struct _cff_header {
  79.     uint8_t major;
  80.     uint8_t minor;
  81.     uint8_t header_size;
  82.     uint8_t offset_size;
  83. } cff_header_t;
  84.  
  85. typedef struct _cff_index_element {
  86.     cairo_bool_t   is_copy;
  87.     unsigned char *data;
  88.     int            length;
  89. } cff_index_element_t;
  90.  
  91. typedef struct _cff_dict_operator {
  92.     cairo_hash_entry_t base;
  93.  
  94.     unsigned short operator;
  95.     unsigned char *operand;
  96.     int            operand_length;
  97.     int            operand_offset;
  98. } cff_dict_operator_t;
  99.  
  100. typedef struct _cairo_cff_font {
  101.  
  102.     cairo_scaled_font_subset_t *scaled_font_subset;
  103.     const cairo_scaled_font_backend_t *backend;
  104.  
  105.     /* Font Data */
  106.     unsigned char       *data;
  107.     unsigned long        data_length;
  108.     unsigned char       *current_ptr;
  109.     unsigned char       *data_end;
  110.     cff_header_t        *header;
  111.     char                *font_name;
  112.     char                *ps_name;
  113.     cairo_hash_table_t  *top_dict;
  114.     cairo_hash_table_t  *private_dict;
  115.     cairo_array_t        strings_index;
  116.     cairo_array_t        charstrings_index;
  117.     cairo_array_t        global_sub_index;
  118.     cairo_array_t        local_sub_index;
  119.     int                  num_glyphs;
  120.     cairo_bool_t         is_cid;
  121.     int                  units_per_em;
  122.  
  123.     /* CID Font Data */
  124.     int                 *fdselect;
  125.     unsigned int         num_fontdicts;
  126.     cairo_hash_table_t **fd_dict;
  127.     cairo_hash_table_t **fd_private_dict;
  128.     cairo_array_t       *fd_local_sub_index;
  129.  
  130.     /* Subsetted Font Data */
  131.     char                *subset_font_name;
  132.     cairo_array_t        charstrings_subset_index;
  133.     cairo_array_t        strings_subset_index;
  134.     int                 *fdselect_subset;
  135.     unsigned int         num_subset_fontdicts;
  136.     int                 *fd_subset_map;
  137.     int                 *private_dict_offset;
  138.     cairo_array_t        output;
  139.  
  140.     /* Subset Metrics */
  141.     int                 *widths;
  142.     int                  x_min, y_min, x_max, y_max;
  143.     int                  ascent, descent;
  144.  
  145. } cairo_cff_font_t;
  146.  
  147. /* Encoded integer using maximum sized encoding. This is required for
  148.  * operands that are later modified after encoding. */
  149. static unsigned char *
  150. encode_integer_max (unsigned char *p, int i)
  151. {
  152.     *p++ = 29;
  153.     *p++ = i >> 24;
  154.     *p++ = (i >> 16) & 0xff;
  155.     *p++ = (i >> 8)  & 0xff;
  156.     *p++ = i & 0xff;
  157.     return p;
  158. }
  159.  
  160. static unsigned char *
  161. encode_integer (unsigned char *p, int i)
  162. {
  163.     if (i >= -107 && i <= 107) {
  164.         *p++ = i + 139;
  165.     } else if (i >= 108 && i <= 1131) {
  166.         i -= 108;
  167.         *p++ = (i >> 8)+ 247;
  168.         *p++ = i & 0xff;
  169.     } else if (i >= -1131 && i <= -108) {
  170.         i = -i - 108;
  171.         *p++ = (i >> 8)+ 251;
  172.         *p++ = i & 0xff;
  173.     } else if (i >= -32768 && i <= 32767) {
  174.         *p++ = 28;
  175.         *p++ = (i >> 8)  & 0xff;
  176.         *p++ = i & 0xff;
  177.     } else {
  178.         p = encode_integer_max (p, i);
  179.     }
  180.     return p;
  181. }
  182.  
  183. static unsigned char *
  184. decode_integer (unsigned char *p, int *integer)
  185. {
  186.     if (*p == 28) {
  187.         *integer = (int)(p[1]<<8 | p[2]);
  188.         p += 3;
  189.     } else if (*p == 29) {
  190.         *integer = (int)((p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4]);
  191.         p += 5;
  192.     } else if (*p >= 32 && *p <= 246) {
  193.         *integer = *p++ - 139;
  194.     } else if (*p <= 250) {
  195.         *integer = (p[0] - 247) * 256 + p[1] + 108;
  196.         p += 2;
  197.     } else if (*p <= 254) {
  198.         *integer = -(p[0] - 251) * 256 - p[1] - 108;
  199.         p += 2;
  200.     } else {
  201.         *integer = 0;
  202.         p += 1;
  203.     }
  204.     return p;
  205. }
  206.  
  207. static unsigned char *
  208. decode_operator (unsigned char *p, unsigned short *operator)
  209. {
  210.     unsigned short op = 0;
  211.  
  212.     op = *p++;
  213.     if (op == 12) {
  214.         op <<= 8;
  215.         op |= *p++;
  216.     }
  217.     *operator = op;
  218.     return p;
  219. }
  220.  
  221. /* return 0 if not an operand */
  222. static int
  223. operand_length (unsigned char *p)
  224. {
  225.     unsigned char *begin = p;
  226.  
  227.     if (*p == 28)
  228.         return 3;
  229.  
  230.     if (*p == 29)
  231.         return 5;
  232.  
  233.     if (*p >= 32 && *p <= 246)
  234.         return 1;
  235.  
  236.     if (*p >= 247 && *p <= 254)
  237.         return 2;
  238.  
  239.     if (*p == 30) {
  240.         while ((*p & 0x0f) != 0x0f)
  241.             p++;
  242.         return p - begin + 1;
  243.     }
  244.  
  245.     return 0;
  246. }
  247.  
  248. static unsigned char *
  249. encode_index_offset (unsigned char *p, int offset_size, unsigned long offset)
  250. {
  251.     while (--offset_size >= 0) {
  252.         p[offset_size] = (unsigned char) (offset & 0xff);
  253.         offset >>= 8;
  254.     }
  255.     return p + offset_size;
  256. }
  257.  
  258. static unsigned long
  259. decode_index_offset(unsigned char *p, int off_size)
  260. {
  261.     unsigned long offset = 0;
  262.  
  263.     while (off_size-- > 0)
  264.         offset = offset*256 + *p++;
  265.     return offset;
  266. }
  267.  
  268. static void
  269. cff_index_init (cairo_array_t *index)
  270. {
  271.     _cairo_array_init (index, sizeof (cff_index_element_t));
  272. }
  273.  
  274. static cairo_int_status_t
  275. cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_ptr)
  276. {
  277.     cff_index_element_t element;
  278.     unsigned char *data, *p;
  279.     cairo_status_t status;
  280.     int offset_size, count, start, i;
  281.     int end = 0;
  282.  
  283.     p = *ptr;
  284.     if (p + 2 > end_ptr)
  285.         return CAIRO_INT_STATUS_UNSUPPORTED;
  286.     count = be16_to_cpu( *((uint16_t *)p) );
  287.     p += 2;
  288.     if (count > 0) {
  289.         offset_size = *p++;
  290.         if (p + (count + 1)*offset_size > end_ptr)
  291.             return CAIRO_INT_STATUS_UNSUPPORTED;
  292.         data = p + offset_size*(count + 1) - 1;
  293.         start = decode_index_offset (p, offset_size);
  294.         p += offset_size;
  295.         for (i = 0; i < count; i++) {
  296.             end = decode_index_offset (p, offset_size);
  297.             p += offset_size;
  298.             if (p > end_ptr)
  299.                 return CAIRO_INT_STATUS_UNSUPPORTED;
  300.             element.length = end - start;
  301.             element.is_copy = FALSE;
  302.             element.data = data + start;
  303.             status = _cairo_array_append (index, &element);
  304.             if (unlikely (status))
  305.                 return status;
  306.             start = end;
  307.         }
  308.         p = data + end;
  309.     }
  310.     *ptr = p;
  311.  
  312.     return CAIRO_STATUS_SUCCESS;
  313. }
  314.  
  315. static cairo_status_t
  316. cff_index_write (cairo_array_t *index, cairo_array_t *output)
  317. {
  318.     int offset_size;
  319.     int offset;
  320.     int num_elem;
  321.     int i;
  322.     cff_index_element_t *element;
  323.     uint16_t count;
  324.     unsigned char buf[5];
  325.     cairo_status_t status;
  326.  
  327.     num_elem = _cairo_array_num_elements (index);
  328.     count = cpu_to_be16 ((uint16_t) num_elem);
  329.     status = _cairo_array_append_multiple (output, &count, 2);
  330.     if (unlikely (status))
  331.         return status;
  332.  
  333.     if (num_elem == 0)
  334.         return CAIRO_STATUS_SUCCESS;
  335.  
  336.     /* Find maximum offset to determine offset size */
  337.     offset = 1;
  338.     for (i = 0; i < num_elem; i++) {
  339.         element = _cairo_array_index (index, i);
  340.         offset += element->length;
  341.     }
  342.     if (offset < 0x100)
  343.         offset_size = 1;
  344.     else if (offset < 0x10000)
  345.         offset_size = 2;
  346.     else if (offset < 0x1000000)
  347.         offset_size = 3;
  348.     else
  349.         offset_size = 4;
  350.  
  351.     buf[0] = (unsigned char) offset_size;
  352.     status = _cairo_array_append (output, buf);
  353.     if (unlikely (status))
  354.         return status;
  355.  
  356.     offset = 1;
  357.     encode_index_offset (buf, offset_size, offset);
  358.     status = _cairo_array_append_multiple (output, buf, offset_size);
  359.     if (unlikely (status))
  360.         return status;
  361.  
  362.     for (i = 0; i < num_elem; i++) {
  363.         element = _cairo_array_index (index, i);
  364.         offset += element->length;
  365.         encode_index_offset (buf, offset_size, offset);
  366.         status = _cairo_array_append_multiple (output, buf, offset_size);
  367.         if (unlikely (status))
  368.             return status;
  369.     }
  370.  
  371.     for (i = 0; i < num_elem; i++) {
  372.         element = _cairo_array_index (index, i);
  373.         status = _cairo_array_append_multiple (output,
  374.                                                element->data,
  375.                                                element->length);
  376.         if (unlikely (status))
  377.             return status;
  378.     }
  379.     return CAIRO_STATUS_SUCCESS;
  380. }
  381.  
  382. static cairo_status_t
  383. cff_index_append (cairo_array_t *index, unsigned char *object , int length)
  384. {
  385.     cff_index_element_t element;
  386.  
  387.     element.length = length;
  388.     element.is_copy = FALSE;
  389.     element.data = object;
  390.  
  391.     return _cairo_array_append (index, &element);
  392. }
  393.  
  394. static cairo_status_t
  395. cff_index_append_copy (cairo_array_t *index,
  396.                        const unsigned char *object,
  397.                        unsigned int length)
  398. {
  399.     cff_index_element_t element;
  400.     cairo_status_t status;
  401.  
  402.     element.length = length;
  403.     element.is_copy = TRUE;
  404.     element.data = malloc (element.length);
  405.     if (unlikely (element.data == NULL))
  406.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  407.  
  408.     memcpy (element.data, object, element.length);
  409.  
  410.     status = _cairo_array_append (index, &element);
  411.     if (unlikely (status)) {
  412.         free (element.data);
  413.         return status;
  414.     }
  415.  
  416.     return CAIRO_STATUS_SUCCESS;
  417. }
  418.  
  419. static void
  420. cff_index_fini (cairo_array_t *index)
  421. {
  422.     cff_index_element_t *element;
  423.     int i;
  424.  
  425.     for (i = 0; i < _cairo_array_num_elements (index); i++) {
  426.         element = _cairo_array_index (index, i);
  427.         if (element->is_copy)
  428.             free (element->data);
  429.     }
  430.     _cairo_array_fini (index);
  431. }
  432.  
  433. static cairo_bool_t
  434. _cairo_cff_dict_equal (const void *key_a, const void *key_b)
  435. {
  436.     const cff_dict_operator_t *op_a = key_a;
  437.     const cff_dict_operator_t *op_b = key_b;
  438.  
  439.     return op_a->operator == op_b->operator;
  440. }
  441.  
  442. static cairo_status_t
  443. cff_dict_init (cairo_hash_table_t **dict)
  444. {
  445.     *dict = _cairo_hash_table_create (_cairo_cff_dict_equal);
  446.     if (unlikely (*dict == NULL))
  447.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  448.  
  449.     return CAIRO_STATUS_SUCCESS;
  450. }
  451.  
  452. static void
  453. _cairo_dict_init_key (cff_dict_operator_t *key, int operator)
  454. {
  455.     key->base.hash = (unsigned long) operator;
  456.     key->operator = operator;
  457. }
  458.  
  459. static cairo_status_t
  460. cff_dict_create_operator (int            operator,
  461.                           unsigned char *operand,
  462.                           int            size,
  463.                           cff_dict_operator_t **out)
  464. {
  465.     cff_dict_operator_t *op;
  466.  
  467.     op = malloc (sizeof (cff_dict_operator_t));
  468.     if (unlikely (op == NULL))
  469.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  470.  
  471.     _cairo_dict_init_key (op, operator);
  472.     op->operand = malloc (size);
  473.     if (unlikely (op->operand == NULL)) {
  474.         free (op);
  475.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  476.     }
  477.  
  478.     memcpy (op->operand, operand, size);
  479.     op->operand_length = size;
  480.     op->operand_offset = -1;
  481.  
  482.     *out = op;
  483.     return CAIRO_STATUS_SUCCESS;
  484. }
  485.  
  486. static cairo_status_t
  487. cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size)
  488. {
  489.     unsigned char *end;
  490.     cairo_array_t operands;
  491.     cff_dict_operator_t *op;
  492.     unsigned short operator;
  493.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  494.     int size;
  495.  
  496.     end = p + dict_size;
  497.     _cairo_array_init (&operands, 1);
  498.     while (p < end) {
  499.         size = operand_length (p);
  500.         if (size != 0) {
  501.             status = _cairo_array_append_multiple (&operands, p, size);
  502.             if (unlikely (status))
  503.                 goto fail;
  504.  
  505.             p += size;
  506.         } else {
  507.             p = decode_operator (p, &operator);
  508.             status = cff_dict_create_operator (operator,
  509.                                           _cairo_array_index (&operands, 0),
  510.                                           _cairo_array_num_elements (&operands),
  511.                                           &op);
  512.             if (unlikely (status))
  513.                 goto fail;
  514.  
  515.             status = _cairo_hash_table_insert (dict, &op->base);
  516.             if (unlikely (status))
  517.                 goto fail;
  518.  
  519.             _cairo_array_truncate (&operands, 0);
  520.         }
  521.     }
  522.  
  523. fail:
  524.     _cairo_array_fini (&operands);
  525.  
  526.     return status;
  527. }
  528.  
  529. static void
  530. cff_dict_remove (cairo_hash_table_t *dict, unsigned short operator)
  531. {
  532.     cff_dict_operator_t key, *op;
  533.  
  534.     _cairo_dict_init_key (&key, operator);
  535.     op = _cairo_hash_table_lookup (dict, &key.base);
  536.     if (op != NULL) {
  537.         free (op->operand);
  538.         _cairo_hash_table_remove (dict, (cairo_hash_entry_t *) op);
  539.         free (op);
  540.     }
  541. }
  542.  
  543. static unsigned char *
  544. cff_dict_get_operands (cairo_hash_table_t *dict,
  545.                        unsigned short      operator,
  546.                        int                *size)
  547. {
  548.     cff_dict_operator_t key, *op;
  549.  
  550.     _cairo_dict_init_key (&key, operator);
  551.     op = _cairo_hash_table_lookup (dict, &key.base);
  552.     if (op != NULL) {
  553.         *size = op->operand_length;
  554.         return op->operand;
  555.     }
  556.  
  557.     return NULL;
  558. }
  559.  
  560. static cairo_status_t
  561. cff_dict_set_operands (cairo_hash_table_t *dict,
  562.                        unsigned short      operator,
  563.                        unsigned char      *operand,
  564.                        int                 size)
  565. {
  566.     cff_dict_operator_t key, *op;
  567.     cairo_status_t status;
  568.  
  569.     _cairo_dict_init_key (&key, operator);
  570.     op = _cairo_hash_table_lookup (dict, &key.base);
  571.     if (op != NULL) {
  572.         free (op->operand);
  573.         op->operand = malloc (size);
  574.         if (unlikely (op->operand == NULL))
  575.             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  576.  
  577.         memcpy (op->operand, operand, size);
  578.         op->operand_length = size;
  579.     }
  580.     else
  581.     {
  582.         status = cff_dict_create_operator (operator, operand, size, &op);
  583.         if (unlikely (status))
  584.             return status;
  585.  
  586.         status = _cairo_hash_table_insert (dict, &op->base);
  587.         if (unlikely (status))
  588.             return status;
  589.     }
  590.  
  591.     return CAIRO_STATUS_SUCCESS;
  592. }
  593.  
  594. static int
  595. cff_dict_get_location (cairo_hash_table_t *dict,
  596.                        unsigned short      operator,
  597.                        int                *size)
  598. {
  599.     cff_dict_operator_t key, *op;
  600.  
  601.     _cairo_dict_init_key (&key, operator);
  602.     op = _cairo_hash_table_lookup (dict, &key.base);
  603.     if (op != NULL) {
  604.         *size = op->operand_length;
  605.         return op->operand_offset;
  606.     }
  607.  
  608.     return -1;
  609. }
  610.  
  611. typedef struct _dict_write_info {
  612.     cairo_array_t *output;
  613.     cairo_status_t status;
  614. } dict_write_info_t;
  615.  
  616. static void
  617. cairo_dict_write_operator (cff_dict_operator_t *op, dict_write_info_t *write_info)
  618. {
  619.     unsigned char data;
  620.  
  621.     op->operand_offset = _cairo_array_num_elements (write_info->output);
  622.     write_info->status = _cairo_array_append_multiple (write_info->output, op->operand, op->operand_length);
  623.     if (write_info->status)
  624.         return;
  625.  
  626.     if (op->operator & 0xff00) {
  627.         data = op->operator >> 8;
  628.         write_info->status = _cairo_array_append (write_info->output, &data);
  629.         if (write_info->status)
  630.             return;
  631.     }
  632.     data = op->operator & 0xff;
  633.     write_info->status = _cairo_array_append (write_info->output, &data);
  634. }
  635.  
  636. static void
  637. _cairo_dict_collect (void *entry, void *closure)
  638. {
  639.     dict_write_info_t   *write_info = closure;
  640.     cff_dict_operator_t *op = entry;
  641.  
  642.     if (write_info->status)
  643.         return;
  644.  
  645.     /* The ROS operator is handled separately in cff_dict_write() */
  646.     if (op->operator != ROS_OP)
  647.         cairo_dict_write_operator (op, write_info);
  648. }
  649.  
  650. static cairo_status_t
  651. cff_dict_write (cairo_hash_table_t *dict, cairo_array_t *output)
  652. {
  653.     dict_write_info_t write_info;
  654.     cff_dict_operator_t key, *op;
  655.  
  656.     write_info.output = output;
  657.     write_info.status = CAIRO_STATUS_SUCCESS;
  658.  
  659.     /* The CFF specification requires that the Top Dict of CID fonts
  660.      * begin with the ROS operator. */
  661.     _cairo_dict_init_key (&key, ROS_OP);
  662.     op = _cairo_hash_table_lookup (dict, &key.base);
  663.     if (op != NULL)
  664.         cairo_dict_write_operator (op, &write_info);
  665.  
  666.     _cairo_hash_table_foreach (dict, _cairo_dict_collect, &write_info);
  667.  
  668.     return write_info.status;
  669. }
  670.  
  671. static void
  672. _cff_dict_entry_pluck (void *_entry, void *dict)
  673. {
  674.     cff_dict_operator_t *entry = _entry;
  675.  
  676.     _cairo_hash_table_remove (dict, &entry->base);
  677.     free (entry->operand);
  678.     free (entry);
  679. }
  680.  
  681. static void
  682. cff_dict_fini (cairo_hash_table_t *dict)
  683. {
  684.     _cairo_hash_table_foreach (dict, _cff_dict_entry_pluck, dict);
  685.     _cairo_hash_table_destroy (dict);
  686. }
  687.  
  688. static cairo_int_status_t
  689. cairo_cff_font_read_header (cairo_cff_font_t *font)
  690. {
  691.     if (font->data_length < sizeof (cff_header_t))
  692.         return CAIRO_INT_STATUS_UNSUPPORTED;
  693.  
  694.     font->header = (cff_header_t *) font->data;
  695.     font->current_ptr = font->data + font->header->header_size;
  696.  
  697.     return CAIRO_STATUS_SUCCESS;
  698. }
  699.  
  700. static cairo_int_status_t
  701. cairo_cff_font_read_name (cairo_cff_font_t *font)
  702. {
  703.     cairo_array_t index;
  704.     cairo_int_status_t status;
  705.  
  706.     /* The original font name is not used in the subset. Read the name
  707.      * index to skip over it. */
  708.     cff_index_init (&index);
  709.     status = cff_index_read (&index, &font->current_ptr, font->data_end);
  710.     cff_index_fini (&index);
  711.  
  712.     return status;
  713. }
  714.  
  715. static cairo_int_status_t
  716. cairo_cff_font_read_private_dict (cairo_cff_font_t   *font,
  717.                                   cairo_hash_table_t *private_dict,
  718.                                   cairo_array_t      *local_sub_index,
  719.                                   unsigned char      *ptr,
  720.                                   int                 size)
  721. {
  722.     cairo_int_status_t status;
  723.     unsigned char buf[10];
  724.     unsigned char *end_buf;
  725.     int offset;
  726.     int i;
  727.     unsigned char *operand;
  728.     unsigned char *p;
  729.  
  730.     status = cff_dict_read (private_dict, ptr, size);
  731.     if (unlikely (status))
  732.         return status;
  733.  
  734.     operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i);
  735.     if (operand) {
  736.         decode_integer (operand, &offset);
  737.         p = ptr + offset;
  738.         status = cff_index_read (local_sub_index, &p, font->data_end);
  739.         if (unlikely (status))
  740.             return status;
  741.  
  742.         /* Use maximum sized encoding to reserve space for later modification. */
  743.         end_buf = encode_integer_max (buf, 0);
  744.         status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf);
  745.         if (unlikely (status))
  746.             return status;
  747.     }
  748.  
  749.     return CAIRO_STATUS_SUCCESS;
  750. }
  751.  
  752. static cairo_int_status_t
  753. cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p)
  754. {
  755.     int type, num_ranges, first, last, fd, i, j;
  756.  
  757.     font->fdselect = calloc (font->num_glyphs, sizeof (int));
  758.     if (unlikely (font->fdselect == NULL))
  759.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  760.  
  761.     type = *p++;
  762.     if (type == 0)
  763.     {
  764.         for (i = 0; i < font->num_glyphs; i++)
  765.             font->fdselect[i] = *p++;
  766.     } else if (type == 3) {
  767.         num_ranges = be16_to_cpu( *((uint16_t *)p) );
  768.         p += 2;
  769.         for  (i = 0; i < num_ranges; i++)
  770.         {
  771.             first = be16_to_cpu( *((uint16_t *)p) );
  772.             p += 2;
  773.             fd = *p++;
  774.             last = be16_to_cpu( *((uint16_t *)p) );
  775.             for (j = first; j < last; j++)
  776.                 font->fdselect[j] = fd;
  777.         }
  778.     } else {
  779.         return CAIRO_INT_STATUS_UNSUPPORTED;
  780.     }
  781.  
  782.     return CAIRO_STATUS_SUCCESS;
  783. }
  784.  
  785. static cairo_int_status_t
  786. cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr)
  787. {
  788.     cairo_array_t index;
  789.     cff_index_element_t *element;
  790.     unsigned int i;
  791.     int size;
  792.     unsigned char *operand;
  793.     int offset;
  794.     cairo_int_status_t status;
  795.     unsigned char buf[100];
  796.     unsigned char *end_buf;
  797.  
  798.     cff_index_init (&index);
  799.     status = cff_index_read (&index, &ptr, font->data_end);
  800.     if (unlikely (status))
  801.         goto fail;
  802.  
  803.     font->num_fontdicts = _cairo_array_num_elements (&index);
  804.  
  805.     font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
  806.     if (unlikely (font->fd_dict == NULL)) {
  807.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  808.         goto fail;
  809.     }
  810.  
  811.     font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts);
  812.     if (unlikely (font->fd_private_dict == NULL)) {
  813.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  814.         goto fail;
  815.     }
  816.  
  817.     font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts);
  818.     if (unlikely (font->fd_local_sub_index == NULL)) {
  819.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  820.         goto fail;
  821.     }
  822.  
  823.     for (i = 0; i < font->num_fontdicts; i++) {
  824.         status = cff_dict_init (&font->fd_dict[i]);
  825.         if (unlikely (status))
  826.             goto fail;
  827.  
  828.         element = _cairo_array_index (&index, i);
  829.         status = cff_dict_read (font->fd_dict[i], element->data, element->length);
  830.         if (unlikely (status))
  831.             goto fail;
  832.  
  833.         operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size);
  834.         if (operand == NULL) {
  835.             status = CAIRO_INT_STATUS_UNSUPPORTED;
  836.             goto fail;
  837.         }
  838.         operand = decode_integer (operand, &size);
  839.         decode_integer (operand, &offset);
  840.         status = cff_dict_init (&font->fd_private_dict[i]);
  841.         if (unlikely (status))
  842.             goto fail;
  843.  
  844.         cff_index_init (&font->fd_local_sub_index[i]);
  845.         status = cairo_cff_font_read_private_dict (font,
  846.                                                    font->fd_private_dict[i],
  847.                                                    &font->fd_local_sub_index[i],
  848.                                                    font->data + offset,
  849.                                                    size);
  850.         if (unlikely (status))
  851.             goto fail;
  852.  
  853.         /* Set integer operand to max value to use max size encoding to reserve
  854.          * space for any value later */
  855.         end_buf = encode_integer_max (buf, 0);
  856.         end_buf = encode_integer_max (end_buf, 0);
  857.         status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf);
  858.         if (unlikely (status))
  859.             goto fail;
  860.     }
  861.  
  862.     return CAIRO_STATUS_SUCCESS;
  863.  
  864. fail:
  865.     cff_index_fini (&index);
  866.  
  867.     return status;
  868. }
  869.  
  870. static cairo_int_status_t
  871. cairo_cff_font_read_top_dict (cairo_cff_font_t *font)
  872. {
  873.     cairo_array_t index;
  874.     cff_index_element_t *element;
  875.     unsigned char buf[20];
  876.     unsigned char *end_buf;
  877.     unsigned char *operand;
  878.     cairo_int_status_t status;
  879.     unsigned char *p;
  880.     int size;
  881.     int offset;
  882.  
  883.     cff_index_init (&index);
  884.     status = cff_index_read (&index, &font->current_ptr, font->data_end);
  885.     if (unlikely (status))
  886.         goto fail;
  887.  
  888.     element = _cairo_array_index (&index, 0);
  889.     status = cff_dict_read (font->top_dict, element->data, element->length);
  890.     if (unlikely (status))
  891.         goto fail;
  892.  
  893.     if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL)
  894.         font->is_cid = TRUE;
  895.     else
  896.         font->is_cid = FALSE;
  897.  
  898.     operand = cff_dict_get_operands (font->top_dict, CHARSTRINGS_OP, &size);
  899.     decode_integer (operand, &offset);
  900.     p = font->data + offset;
  901.     status = cff_index_read (&font->charstrings_index, &p, font->data_end);
  902.     if (unlikely (status))
  903.         goto fail;
  904.     font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
  905.  
  906.     if (font->is_cid) {
  907.         operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size);
  908.         decode_integer (operand, &offset);
  909.         status = cairo_cff_font_read_fdselect (font, font->data + offset);
  910.         if (unlikely (status))
  911.             goto fail;
  912.  
  913.         operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size);
  914.         decode_integer (operand, &offset);
  915.         status = cairo_cff_font_read_cid_fontdict (font, font->data + offset);
  916.         if (unlikely (status))
  917.             goto fail;
  918.     } else {
  919.         operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size);
  920.         operand = decode_integer (operand, &size);
  921.         decode_integer (operand, &offset);
  922.         status = cairo_cff_font_read_private_dict (font,
  923.                                                    font->private_dict,
  924.                                                    &font->local_sub_index,
  925.                                                    font->data + offset,
  926.                                                    size);
  927.         if (unlikely (status))
  928.             goto fail;
  929.     }
  930.  
  931.     /* Use maximum sized encoding to reserve space for later modification. */
  932.     end_buf = encode_integer_max (buf, 0);
  933.     status = cff_dict_set_operands (font->top_dict,
  934.                                     CHARSTRINGS_OP, buf, end_buf - buf);
  935.     if (unlikely (status))
  936.         goto fail;
  937.  
  938.     status = cff_dict_set_operands (font->top_dict,
  939.                                     FDSELECT_OP, buf, end_buf - buf);
  940.     if (unlikely (status))
  941.         goto fail;
  942.  
  943.     status = cff_dict_set_operands (font->top_dict,
  944.                                     FDARRAY_OP, buf, end_buf - buf);
  945.     if (unlikely (status))
  946.         goto fail;
  947.  
  948.     status = cff_dict_set_operands (font->top_dict,
  949.                                     CHARSET_OP, buf, end_buf - buf);
  950.     if (unlikely (status))
  951.         goto fail;
  952.  
  953.     cff_dict_remove (font->top_dict, ENCODING_OP);
  954.     cff_dict_remove (font->top_dict, PRIVATE_OP);
  955.  
  956.     /* Remove the unique identifier operators as the subsetted font is
  957.      * not the same is the original font. */
  958.     cff_dict_remove (font->top_dict, UNIQUEID_OP);
  959.     cff_dict_remove (font->top_dict, XUID_OP);
  960.  
  961. fail:
  962.     cff_index_fini (&index);
  963.  
  964.     return status;
  965. }
  966.  
  967. static cairo_int_status_t
  968. cairo_cff_font_read_strings (cairo_cff_font_t *font)
  969. {
  970.     return cff_index_read (&font->strings_index, &font->current_ptr, font->data_end);
  971. }
  972.  
  973. static cairo_int_status_t
  974. cairo_cff_font_read_global_subroutines (cairo_cff_font_t *font)
  975. {
  976.     return cff_index_read (&font->global_sub_index, &font->current_ptr, font->data_end);
  977. }
  978.  
  979. typedef cairo_int_status_t
  980. (*font_read_t) (cairo_cff_font_t *font);
  981.  
  982. static const font_read_t font_read_funcs[] = {
  983.     cairo_cff_font_read_header,
  984.     cairo_cff_font_read_name,
  985.     cairo_cff_font_read_top_dict,
  986.     cairo_cff_font_read_strings,
  987.     cairo_cff_font_read_global_subroutines,
  988. };
  989.  
  990. static cairo_int_status_t
  991. cairo_cff_font_read_font (cairo_cff_font_t *font)
  992. {
  993.     cairo_int_status_t status;
  994.     unsigned int i;
  995.  
  996.     for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) {
  997.         status = font_read_funcs[i] (font);
  998.         if (unlikely (status))
  999.             return status;
  1000.     }
  1001.  
  1002.     return CAIRO_STATUS_SUCCESS;
  1003. }
  1004.  
  1005. static cairo_status_t
  1006. cairo_cff_font_set_ros_strings (cairo_cff_font_t *font)
  1007. {
  1008.     cairo_status_t status;
  1009.     unsigned char buf[30];
  1010.     unsigned char *p;
  1011.     int sid1, sid2;
  1012.     const char *registry = "Adobe";
  1013.     const char *ordering = "Identity";
  1014.  
  1015.     sid1 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1016.     status = cff_index_append_copy (&font->strings_subset_index,
  1017.                                     (unsigned char *)registry,
  1018.                                     strlen(registry));
  1019.     if (unlikely (status))
  1020.         return status;
  1021.  
  1022.     sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1023.     status = cff_index_append_copy (&font->strings_subset_index,
  1024.                                     (unsigned char *)ordering,
  1025.                                     strlen(ordering));
  1026.     if (unlikely (status))
  1027.         return status;
  1028.  
  1029.     p = encode_integer (buf, sid1);
  1030.     p = encode_integer (p, sid2);
  1031.     p = encode_integer (p, 0);
  1032.     status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf);
  1033.     if (unlikely (status))
  1034.         return status;
  1035.  
  1036.     p = encode_integer (buf, font->scaled_font_subset->num_glyphs);
  1037.     status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf);
  1038.     if (unlikely (status))
  1039.         return status;
  1040.  
  1041.     return CAIRO_STATUS_SUCCESS;
  1042. }
  1043.  
  1044. static cairo_status_t
  1045. cairo_cff_font_subset_dict_string(cairo_cff_font_t   *font,
  1046.                                   cairo_hash_table_t *dict,
  1047.                                   int                 operator)
  1048. {
  1049.     int size;
  1050.     unsigned char *p;
  1051.     int sid;
  1052.     unsigned char buf[100];
  1053.     cff_index_element_t *element;
  1054.     cairo_status_t status;
  1055.  
  1056.     p = cff_dict_get_operands (dict, operator, &size);
  1057.     if (!p)
  1058.         return CAIRO_STATUS_SUCCESS;
  1059.  
  1060.     decode_integer (p, &sid);
  1061.     if (sid < NUM_STD_STRINGS)
  1062.         return CAIRO_STATUS_SUCCESS;
  1063.  
  1064.     element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS);
  1065.     sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index);
  1066.     status = cff_index_append (&font->strings_subset_index, element->data, element->length);
  1067.     if (unlikely (status))
  1068.         return status;
  1069.  
  1070.     p = encode_integer (buf, sid);
  1071.     status = cff_dict_set_operands (dict, operator, buf, p - buf);
  1072.     if (unlikely (status))
  1073.         return status;
  1074.  
  1075.     return CAIRO_STATUS_SUCCESS;
  1076. }
  1077.  
  1078. static const int dict_strings[] = {
  1079.     VERSION_OP,
  1080.     NOTICE_OP,
  1081.     COPYRIGHT_OP,
  1082.     FULLNAME_OP,
  1083.     FAMILYNAME_OP,
  1084.     WEIGHT_OP,
  1085.     POSTSCRIPT_OP,
  1086.     BASEFONTNAME_OP,
  1087.     FONTNAME_OP,
  1088. };
  1089.  
  1090. static cairo_status_t
  1091. cairo_cff_font_subset_dict_strings (cairo_cff_font_t   *font,
  1092.                                     cairo_hash_table_t *dict)
  1093. {
  1094.     cairo_status_t status;
  1095.     unsigned int i;
  1096.  
  1097.     for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) {
  1098.         status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]);
  1099.         if (unlikely (status))
  1100.             return status;
  1101.     }
  1102.  
  1103.     return CAIRO_STATUS_SUCCESS;
  1104. }
  1105.  
  1106. static cairo_status_t
  1107. cairo_cff_font_subset_charstrings (cairo_cff_font_t  *font)
  1108. {
  1109.     cff_index_element_t *element;
  1110.     unsigned int i;
  1111.     cairo_status_t status;
  1112.  
  1113.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1114.         element = _cairo_array_index (&font->charstrings_index,
  1115.                                       font->scaled_font_subset->glyphs[i]);
  1116.         status = cff_index_append (&font->charstrings_subset_index,
  1117.                                    element->data,
  1118.                                    element->length);
  1119.         if (unlikely (status))
  1120.             return status;
  1121.     }
  1122.  
  1123.     return CAIRO_STATUS_SUCCESS;
  1124. }
  1125.  
  1126. static cairo_status_t
  1127. cairo_cff_font_subset_fontdict (cairo_cff_font_t  *font)
  1128. {
  1129.     unsigned int i;
  1130.     int fd;
  1131.     int *reverse_map;
  1132.  
  1133.     font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs,
  1134.                                      sizeof (int));
  1135.     if (unlikely (font->fdselect_subset == NULL))
  1136.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1137.  
  1138.     font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int));
  1139.     if (unlikely (font->fd_subset_map == NULL))
  1140.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1141.  
  1142.     font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int));
  1143.     if (unlikely (font->private_dict_offset == NULL))
  1144.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1145.  
  1146.     reverse_map = calloc (font->num_fontdicts, sizeof (int));
  1147.     if (unlikely (reverse_map == NULL))
  1148.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1149.  
  1150.     for (i = 0; i < font->num_fontdicts; i++)
  1151.         reverse_map[i] = -1;
  1152.  
  1153.     font->num_subset_fontdicts = 0;
  1154.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1155.         fd = font->fdselect[font->scaled_font_subset->glyphs[i]];
  1156.         if (reverse_map[fd] < 0) {
  1157.             font->fd_subset_map[font->num_subset_fontdicts] = fd;
  1158.             reverse_map[fd] = font->num_subset_fontdicts++;
  1159.         }
  1160.         font->fdselect_subset[i] = reverse_map[fd];
  1161.     }
  1162.  
  1163.     free (reverse_map);
  1164.  
  1165.     return CAIRO_STATUS_SUCCESS;
  1166. }
  1167.  
  1168. static cairo_status_t
  1169. cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font)
  1170. {
  1171.     unsigned char buf[100];
  1172.     unsigned char *end_buf;
  1173.     cairo_status_t status;
  1174.  
  1175.     font->num_fontdicts = 1;
  1176.     font->fd_dict = malloc (sizeof (cairo_hash_table_t *));
  1177.     if (unlikely (font->fd_dict == NULL))
  1178.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1179.  
  1180.     if (cff_dict_init (&font->fd_dict[0])) {
  1181.         free (font->fd_dict);
  1182.         font->fd_dict = NULL;
  1183.         font->num_fontdicts = 0;
  1184.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1185.     }
  1186.  
  1187.     font->fd_subset_map = malloc (sizeof (int));
  1188.     if (unlikely (font->fd_subset_map == NULL))
  1189.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1190.  
  1191.     font->private_dict_offset = malloc (sizeof (int));
  1192.     if (unlikely (font->private_dict_offset == NULL))
  1193.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1194.  
  1195.     font->fd_subset_map[0] = 0;
  1196.     font->num_subset_fontdicts = 1;
  1197.  
  1198.     /* Set integer operand to max value to use max size encoding to reserve
  1199.      * space for any value later */
  1200.     end_buf = encode_integer_max (buf, 0);
  1201.     end_buf = encode_integer_max (end_buf, 0);
  1202.     status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf);
  1203.     if (unlikely (status))
  1204.         return status;
  1205.  
  1206.     return CAIRO_STATUS_SUCCESS;
  1207. }
  1208.  
  1209. static cairo_status_t
  1210. cairo_cff_font_subset_strings (cairo_cff_font_t *font)
  1211. {
  1212.     cairo_status_t status;
  1213.     unsigned int i;
  1214.  
  1215.     status = cairo_cff_font_subset_dict_strings (font, font->top_dict);
  1216.     if (unlikely (status))
  1217.         return status;
  1218.  
  1219.     if (font->is_cid) {
  1220.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  1221.             status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]);
  1222.             if (unlikely (status))
  1223.                 return status;
  1224.  
  1225.             status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]);
  1226.             if (unlikely (status))
  1227.                 return status;
  1228.         }
  1229.     } else {
  1230.         status = cairo_cff_font_subset_dict_strings (font, font->private_dict);
  1231.     }
  1232.  
  1233.     return status;
  1234. }
  1235.  
  1236. static cairo_status_t
  1237. cairo_cff_font_subset_font (cairo_cff_font_t  *font)
  1238. {
  1239.     cairo_status_t status;
  1240.  
  1241.     status = cairo_cff_font_set_ros_strings (font);
  1242.     if (unlikely (status))
  1243.         return status;
  1244.  
  1245.     status = cairo_cff_font_subset_charstrings (font);
  1246.     if (unlikely (status))
  1247.         return status;
  1248.  
  1249.     if (font->is_cid)
  1250.         status = cairo_cff_font_subset_fontdict (font);
  1251.     else
  1252.         status = cairo_cff_font_create_cid_fontdict (font);
  1253.     if (unlikely (status))
  1254.         return status;
  1255.  
  1256.     status = cairo_cff_font_subset_strings (font);
  1257.     if (unlikely (status))
  1258.         return status;
  1259.  
  1260.     return status;
  1261. }
  1262.  
  1263. /* Set the operand of the specified operator in the (already written)
  1264.  * top dict to point to the current position in the output
  1265.  * array. Operands updated with this function must have previously
  1266.  * been encoded with the 5-byte (max) integer encoding. */
  1267. static void
  1268. cairo_cff_font_set_topdict_operator_to_cur_pos (cairo_cff_font_t  *font,
  1269.                                                 int                operator)
  1270. {
  1271.     int cur_pos;
  1272.     int offset;
  1273.     int size;
  1274.     unsigned char buf[10];
  1275.     unsigned char *buf_end;
  1276.     unsigned char *op_ptr;
  1277.  
  1278.     cur_pos = _cairo_array_num_elements (&font->output);
  1279.     buf_end = encode_integer_max (buf, cur_pos);
  1280.     offset = cff_dict_get_location (font->top_dict, operator, &size);
  1281.     assert (offset > 0);
  1282.     op_ptr = _cairo_array_index (&font->output, offset);
  1283.     memcpy (op_ptr, buf, buf_end - buf);
  1284. }
  1285.  
  1286. static cairo_status_t
  1287. cairo_cff_font_write_header (cairo_cff_font_t *font)
  1288. {
  1289.     return _cairo_array_append_multiple (&font->output,
  1290.                                          font->header,
  1291.                                          font->header->header_size);
  1292. }
  1293.  
  1294. static cairo_status_t
  1295. cairo_cff_font_write_name (cairo_cff_font_t *font)
  1296. {
  1297.     cairo_status_t status = CAIRO_STATUS_SUCCESS;
  1298.     cairo_array_t index;
  1299.  
  1300.     cff_index_init (&index);
  1301.  
  1302.     status = cff_index_append_copy (&index,
  1303.                                     (unsigned char *) font->subset_font_name,
  1304.                                     strlen(font->subset_font_name));
  1305.     if (unlikely (status))
  1306.         goto FAIL;
  1307.  
  1308.     status = cff_index_write (&index, &font->output);
  1309.     if (unlikely (status))
  1310.         goto FAIL;
  1311.  
  1312. FAIL:
  1313.     cff_index_fini (&index);
  1314.  
  1315.     return status;
  1316. }
  1317.  
  1318. static cairo_status_t
  1319. cairo_cff_font_write_top_dict (cairo_cff_font_t *font)
  1320. {
  1321.     uint16_t count;
  1322.     unsigned char buf[10];
  1323.     unsigned char *p;
  1324.     int offset_index;
  1325.     int dict_start, dict_size;
  1326.     int offset_size = 4;
  1327.     cairo_status_t status;
  1328.  
  1329.     /* Write an index containing the top dict */
  1330.  
  1331.     count = cpu_to_be16 (1);
  1332.     status = _cairo_array_append_multiple (&font->output, &count, 2);
  1333.     if (unlikely (status))
  1334.         return status;
  1335.     buf[0] = offset_size;
  1336.     status = _cairo_array_append (&font->output, buf);
  1337.     if (unlikely (status))
  1338.         return status;
  1339.     encode_index_offset (buf, offset_size, 1);
  1340.     status = _cairo_array_append_multiple (&font->output, buf, offset_size);
  1341.     if (unlikely (status))
  1342.         return status;
  1343.  
  1344.     /* Reserve space for last element of offset array and update after
  1345.      * dict is written */
  1346.     offset_index = _cairo_array_num_elements (&font->output);
  1347.     status = _cairo_array_append_multiple (&font->output, buf, offset_size);
  1348.     if (unlikely (status))
  1349.         return status;
  1350.  
  1351.     dict_start = _cairo_array_num_elements (&font->output);
  1352.     status = cff_dict_write (font->top_dict, &font->output);
  1353.     if (unlikely (status))
  1354.         return status;
  1355.     dict_size = _cairo_array_num_elements (&font->output) - dict_start;
  1356.  
  1357.     encode_index_offset (buf, offset_size, dict_size + 1);
  1358.     p = _cairo_array_index (&font->output, offset_index);
  1359.     memcpy (p, buf, offset_size);
  1360.  
  1361.     return CAIRO_STATUS_SUCCESS;
  1362. }
  1363.  
  1364. static cairo_status_t
  1365. cairo_cff_font_write_strings (cairo_cff_font_t  *font)
  1366. {
  1367.     return cff_index_write (&font->strings_subset_index, &font->output);
  1368. }
  1369.  
  1370. static cairo_status_t
  1371. cairo_cff_font_write_global_subrs (cairo_cff_font_t  *font)
  1372. {
  1373.     return cff_index_write (&font->global_sub_index, &font->output);
  1374. }
  1375.  
  1376. static cairo_status_t
  1377. cairo_cff_font_write_fdselect (cairo_cff_font_t  *font)
  1378. {
  1379.     unsigned char data;
  1380.     unsigned int i;
  1381.     cairo_int_status_t status;
  1382.  
  1383.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDSELECT_OP);
  1384.  
  1385.     if (font->is_cid) {
  1386.         data = 0;
  1387.         status = _cairo_array_append (&font->output, &data);
  1388.         if (unlikely (status))
  1389.             return status;
  1390.  
  1391.         for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1392.             data = font->fdselect_subset[i];
  1393.             status = _cairo_array_append (&font->output, &data);
  1394.             if (unlikely (status))
  1395.                 return status;
  1396.         }
  1397.     } else {
  1398.         unsigned char byte;
  1399.         uint16_t word;
  1400.  
  1401.         status = _cairo_array_grow_by (&font->output, 9);
  1402.         if (unlikely (status))
  1403.             return status;
  1404.  
  1405.         byte = 3;
  1406.         status = _cairo_array_append (&font->output, &byte);
  1407.         assert (status == CAIRO_STATUS_SUCCESS);
  1408.  
  1409.         word = cpu_to_be16 (1);
  1410.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  1411.         assert (status == CAIRO_STATUS_SUCCESS);
  1412.  
  1413.         word = cpu_to_be16 (0);
  1414.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  1415.         assert (status == CAIRO_STATUS_SUCCESS);
  1416.  
  1417.         byte = 0;
  1418.         status = _cairo_array_append (&font->output, &byte);
  1419.         assert (status == CAIRO_STATUS_SUCCESS);
  1420.  
  1421.         word = cpu_to_be16 (font->scaled_font_subset->num_glyphs);
  1422.         status = _cairo_array_append_multiple (&font->output, &word, 2);
  1423.         assert (status == CAIRO_STATUS_SUCCESS);
  1424.     }
  1425.  
  1426.     return CAIRO_STATUS_SUCCESS;
  1427. }
  1428.  
  1429. static cairo_status_t
  1430. cairo_cff_font_write_charset (cairo_cff_font_t  *font)
  1431. {
  1432.     unsigned char byte;
  1433.     uint16_t word;
  1434.     cairo_status_t status;
  1435.  
  1436.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP);
  1437.     status = _cairo_array_grow_by (&font->output, 5);
  1438.     if (unlikely (status))
  1439.         return status;
  1440.  
  1441.     byte = 2;
  1442.     status = _cairo_array_append (&font->output, &byte);
  1443.     assert (status == CAIRO_STATUS_SUCCESS);
  1444.  
  1445.     word = cpu_to_be16 (1);
  1446.     status = _cairo_array_append_multiple (&font->output, &word, 2);
  1447.     assert (status == CAIRO_STATUS_SUCCESS);
  1448.  
  1449.     word = cpu_to_be16 (font->scaled_font_subset->num_glyphs - 2);
  1450.     status = _cairo_array_append_multiple (&font->output, &word, 2);
  1451.     assert (status == CAIRO_STATUS_SUCCESS);
  1452.  
  1453.     return CAIRO_STATUS_SUCCESS;
  1454. }
  1455.  
  1456. static cairo_status_t
  1457. cairo_cff_font_write_charstrings (cairo_cff_font_t  *font)
  1458. {
  1459.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSTRINGS_OP);
  1460.  
  1461.     return cff_index_write (&font->charstrings_subset_index, &font->output);
  1462. }
  1463.  
  1464. static cairo_status_t
  1465. cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font)
  1466. {
  1467.     unsigned int i;
  1468.     cairo_int_status_t status;
  1469.     uint32_t *offset_array;
  1470.     int offset_base;
  1471.     uint16_t count;
  1472.     uint8_t offset_size = 4;
  1473.  
  1474.     cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP);
  1475.     count = cpu_to_be16 (font->num_subset_fontdicts);
  1476.     status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t));
  1477.     if (unlikely (status))
  1478.         return status;
  1479.     status = _cairo_array_append (&font->output, &offset_size);
  1480.     if (unlikely (status))
  1481.         return status;
  1482.     status = _cairo_array_allocate (&font->output,
  1483.                                     (font->num_subset_fontdicts + 1)*offset_size,
  1484.                                     (void **) &offset_array);
  1485.     if (unlikely (status))
  1486.         return status;
  1487.     offset_base = _cairo_array_num_elements (&font->output) - 1;
  1488.     *offset_array++ = cpu_to_be32(1);
  1489.     for (i = 0; i < font->num_subset_fontdicts; i++) {
  1490.         status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]],
  1491.                                  &font->output);
  1492.         if (unlikely (status))
  1493.             return status;
  1494.         *offset_array++ = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base);
  1495.     }
  1496.  
  1497.     return CAIRO_STATUS_SUCCESS;
  1498. }
  1499.  
  1500. static cairo_status_t
  1501. cairo_cff_font_write_private_dict (cairo_cff_font_t   *font,
  1502.                                    int                 dict_num,
  1503.                                    cairo_hash_table_t *parent_dict,
  1504.                                    cairo_hash_table_t *private_dict)
  1505. {
  1506.     int offset;
  1507.     int size;
  1508.     unsigned char buf[10];
  1509.     unsigned char *buf_end;
  1510.     unsigned char *p;
  1511.     cairo_status_t status;
  1512.  
  1513.     /* Write private dict and update offset and size in top dict */
  1514.     font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output);
  1515.     status = cff_dict_write (private_dict, &font->output);
  1516.     if (unlikely (status))
  1517.         return status;
  1518.  
  1519.     size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
  1520.     /* private entry has two operands - size and offset */
  1521.     buf_end = encode_integer_max (buf, size);
  1522.     buf_end = encode_integer_max (buf_end, font->private_dict_offset[dict_num]);
  1523.     offset = cff_dict_get_location (parent_dict, PRIVATE_OP, &size);
  1524.     assert (offset > 0);
  1525.     p = _cairo_array_index (&font->output, offset);
  1526.     memcpy (p, buf, buf_end - buf);
  1527.  
  1528.     return CAIRO_STATUS_SUCCESS;
  1529. }
  1530.  
  1531. static cairo_status_t
  1532. cairo_cff_font_write_local_sub (cairo_cff_font_t   *font,
  1533.                                 int                 dict_num,
  1534.                                 cairo_hash_table_t *private_dict,
  1535.                                 cairo_array_t      *local_sub_index)
  1536. {
  1537.     int offset;
  1538.     int size;
  1539.     unsigned char buf[10];
  1540.     unsigned char *buf_end;
  1541.     unsigned char *p;
  1542.     cairo_status_t status;
  1543.  
  1544.     if (_cairo_array_num_elements (local_sub_index) > 0) {
  1545.         /* Write local subroutines and update offset in private
  1546.          * dict. Local subroutines offset is relative to start of
  1547.          * private dict */
  1548.         offset = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num];
  1549.         buf_end = encode_integer_max (buf, offset);
  1550.         offset = cff_dict_get_location (private_dict, LOCAL_SUB_OP, &size);
  1551.         assert (offset > 0);
  1552.         p = _cairo_array_index (&font->output, offset);
  1553.         memcpy (p, buf, buf_end - buf);
  1554.         status = cff_index_write (local_sub_index, &font->output);
  1555.         if (unlikely (status))
  1556.             return status;
  1557.     }
  1558.  
  1559.     return CAIRO_STATUS_SUCCESS;
  1560. }
  1561.  
  1562.  
  1563. static cairo_status_t
  1564. cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t  *font)
  1565. {
  1566.     unsigned int i;
  1567.     cairo_int_status_t status;
  1568.  
  1569.     if (font->is_cid) {
  1570.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  1571.             status = cairo_cff_font_write_private_dict (
  1572.                             font,
  1573.                             i,
  1574.                             font->fd_dict[font->fd_subset_map[i]],
  1575.                             font->fd_private_dict[font->fd_subset_map[i]]);
  1576.             if (unlikely (status))
  1577.                 return status;
  1578.         }
  1579.  
  1580.         for (i = 0; i < font->num_subset_fontdicts; i++) {
  1581.             status = cairo_cff_font_write_local_sub (
  1582.                             font,
  1583.                             i,
  1584.                             font->fd_private_dict[font->fd_subset_map[i]],
  1585.                            &font->fd_local_sub_index[font->fd_subset_map[i]]);
  1586.             if (unlikely (status))
  1587.                 return status;
  1588.         }
  1589.     } else {
  1590.         status = cairo_cff_font_write_private_dict (font,
  1591.                                                     0,
  1592.                                                     font->fd_dict[0],
  1593.                                                     font->private_dict);
  1594.         if (unlikely (status))
  1595.             return status;
  1596.  
  1597.         status = cairo_cff_font_write_local_sub (font,
  1598.                                                  0,
  1599.                                                  font->private_dict,
  1600.                                                  &font->local_sub_index);
  1601.         if (unlikely (status))
  1602.             return status;
  1603.     }
  1604.  
  1605.     return CAIRO_STATUS_SUCCESS;
  1606. }
  1607.  
  1608. typedef cairo_status_t
  1609. (*font_write_t) (cairo_cff_font_t *font);
  1610.  
  1611. static const font_write_t font_write_funcs[] = {
  1612.     cairo_cff_font_write_header,
  1613.     cairo_cff_font_write_name,
  1614.     cairo_cff_font_write_top_dict,
  1615.     cairo_cff_font_write_strings,
  1616.     cairo_cff_font_write_global_subrs,
  1617.     cairo_cff_font_write_charset,
  1618.     cairo_cff_font_write_fdselect,
  1619.     cairo_cff_font_write_charstrings,
  1620.     cairo_cff_font_write_cid_fontdict,
  1621.     cairo_cff_font_write_cid_private_dict_and_local_sub,
  1622. };
  1623.  
  1624. static cairo_status_t
  1625. cairo_cff_font_write_subset (cairo_cff_font_t *font)
  1626. {
  1627.     cairo_int_status_t status;
  1628.     unsigned int i;
  1629.  
  1630.     for (i = 0; i < ARRAY_LENGTH (font_write_funcs); i++) {
  1631.         status = font_write_funcs[i] (font);
  1632.         if (unlikely (status))
  1633.             return status;
  1634.     }
  1635.  
  1636.     return CAIRO_STATUS_SUCCESS;
  1637. }
  1638.  
  1639. static cairo_int_status_t
  1640. cairo_cff_font_generate (cairo_cff_font_t  *font,
  1641.                          const char       **data,
  1642.                          unsigned long     *length)
  1643. {
  1644.     cairo_int_status_t status;
  1645.  
  1646.     status = cairo_cff_font_read_font (font);
  1647.     if (unlikely (status))
  1648.         return status;
  1649.  
  1650.     status = cairo_cff_font_subset_font (font);
  1651.     if (unlikely (status))
  1652.         return status;
  1653.  
  1654.     status = cairo_cff_font_write_subset (font);
  1655.     if (unlikely (status))
  1656.         return status;
  1657.  
  1658.     *data = _cairo_array_index (&font->output, 0);
  1659.     *length = _cairo_array_num_elements (&font->output);
  1660.  
  1661.     return CAIRO_STATUS_SUCCESS;
  1662. }
  1663.  
  1664. static cairo_int_status_t
  1665. cairo_cff_font_create_set_widths (cairo_cff_font_t *font)
  1666. {
  1667.     unsigned long size;
  1668.     unsigned long long_entry_size;
  1669.     unsigned long short_entry_size;
  1670.     unsigned int i;
  1671.     tt_hhea_t hhea;
  1672.     int num_hmetrics;
  1673.     unsigned char buf[10];
  1674.     int glyph_index;
  1675.     cairo_int_status_t status;
  1676.  
  1677.     size = sizeof (tt_hhea_t);
  1678.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1679.                                                  TT_TAG_hhea, 0,
  1680.                                                  (unsigned char*) &hhea, &size);
  1681.     if (unlikely (status))
  1682.         return status;
  1683.     num_hmetrics = be16_to_cpu (hhea.num_hmetrics);
  1684.  
  1685.     for (i = 1; i < font->scaled_font_subset->num_glyphs; i++) {
  1686.         glyph_index = font->scaled_font_subset->glyphs[i];
  1687.         long_entry_size = 2 * sizeof (int16_t);
  1688.         short_entry_size = sizeof (int16_t);
  1689.         if (glyph_index < num_hmetrics) {
  1690.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1691.                                                          TT_TAG_hmtx,
  1692.                                                          glyph_index * long_entry_size,
  1693.                                                          buf, &short_entry_size);
  1694.             if (unlikely (status))
  1695.                 return status;
  1696.         }
  1697.         else
  1698.         {
  1699.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1700.                                                          TT_TAG_hmtx,
  1701.                                                          (num_hmetrics - 1) * long_entry_size,
  1702.                                                          buf, &short_entry_size);
  1703.             if (unlikely (status))
  1704.                 return status;
  1705.         }
  1706.         font->widths[i] = be16_to_cpu (*((int16_t*)buf));
  1707.     }
  1708.  
  1709.     return CAIRO_STATUS_SUCCESS;
  1710. }
  1711.  
  1712. static cairo_int_status_t
  1713. _cairo_cff_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
  1714.                         cairo_cff_font_t           **font_return,
  1715.                         const char                  *subset_name)
  1716. {
  1717.     const cairo_scaled_font_backend_t *backend;
  1718.     cairo_status_t status;
  1719.     cairo_cff_font_t *font;
  1720.     tt_head_t head;
  1721.     tt_hhea_t hhea;
  1722.     unsigned long size, data_length;
  1723.  
  1724.     backend = scaled_font_subset->scaled_font->backend;
  1725.     if (!backend->load_truetype_table)
  1726.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1727.  
  1728.     data_length = 0;
  1729.     status = backend->load_truetype_table( scaled_font_subset->scaled_font,
  1730.                                            TT_TAG_CFF, 0, NULL, &data_length);
  1731.     if (unlikely (status))
  1732.         return status;
  1733.  
  1734.     size = sizeof (tt_head_t);
  1735.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  1736.                                            TT_TAG_head, 0,
  1737.                                            (unsigned char *) &head, &size);
  1738.     if (unlikely (status))
  1739.         return status;
  1740.  
  1741.     size = sizeof (tt_hhea_t);
  1742.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  1743.                                            TT_TAG_hhea, 0,
  1744.                                            (unsigned char *) &hhea, &size);
  1745.     if (unlikely (status))
  1746.         return status;
  1747.  
  1748.     size = 0;
  1749.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  1750.                                            TT_TAG_hmtx, 0, NULL, &size);
  1751.     if (unlikely (status))
  1752.         return status;
  1753.  
  1754.     font = malloc (sizeof (cairo_cff_font_t));
  1755.     if (unlikely (font == NULL))
  1756.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1757.  
  1758.     font->backend = backend;
  1759.     font->scaled_font_subset = scaled_font_subset;
  1760.  
  1761.     _cairo_array_init (&font->output, sizeof (char));
  1762.     status = _cairo_array_grow_by (&font->output, 4096);
  1763.     if (unlikely (status))
  1764.         goto fail2;
  1765.  
  1766.     font->subset_font_name = strdup (subset_name);
  1767.     if (unlikely (font->subset_font_name == NULL)) {
  1768.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1769.         goto fail2;
  1770.     }
  1771.     font->x_min = (int16_t) be16_to_cpu (head.x_min);
  1772.     font->y_min = (int16_t) be16_to_cpu (head.y_min);
  1773.     font->x_max = (int16_t) be16_to_cpu (head.x_max);
  1774.     font->y_max = (int16_t) be16_to_cpu (head.y_max);
  1775.     font->ascent = (int16_t) be16_to_cpu (hhea.ascender);
  1776.     font->descent = (int16_t) be16_to_cpu (hhea.descender);
  1777.     font->units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
  1778.     if (font->units_per_em == 0)
  1779.         font->units_per_em = 1000;
  1780.  
  1781.     font->font_name = NULL;
  1782.     status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
  1783.                                              &font->ps_name,
  1784.                                              &font->font_name);
  1785.     if (_cairo_status_is_error (status))
  1786.         goto fail3;
  1787.  
  1788.     /* If the PS name is not found, create a CairoFont-x-y name. */
  1789.     if (font->ps_name == NULL) {
  1790.         font->ps_name = malloc (30);
  1791.         if (unlikely (font->ps_name == NULL)) {
  1792.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1793.             goto fail3;
  1794.         }
  1795.  
  1796.         snprintf(font->ps_name, 30, "CairoFont-%u-%u",
  1797.                  scaled_font_subset->font_id,
  1798.                  scaled_font_subset->subset_id);
  1799.     }
  1800.  
  1801.     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
  1802.     if (unlikely (font->widths == NULL)) {
  1803.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1804.         goto fail4;
  1805.     }
  1806.  
  1807.     status = cairo_cff_font_create_set_widths (font);
  1808.     if (unlikely (status))
  1809.         goto fail5;
  1810.  
  1811.     font->data_length = data_length;
  1812.     font->data = malloc (data_length);
  1813.     if (unlikely (font->data == NULL)) {
  1814.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1815.         goto fail5;
  1816.     }
  1817.     status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font,
  1818.                                                   TT_TAG_CFF, 0, font->data,
  1819.                                                   &font->data_length);
  1820.     if (unlikely (status))
  1821.         goto fail6;
  1822.  
  1823.     font->data_end = font->data + font->data_length;
  1824.  
  1825.     status = cff_dict_init (&font->top_dict);
  1826.     if (unlikely (status))
  1827.         goto fail6;
  1828.  
  1829.     status = cff_dict_init (&font->private_dict);
  1830.     if (unlikely (status))
  1831.         goto fail7;
  1832.  
  1833.     cff_index_init (&font->strings_index);
  1834.     cff_index_init (&font->charstrings_index);
  1835.     cff_index_init (&font->global_sub_index);
  1836.     cff_index_init (&font->local_sub_index);
  1837.     cff_index_init (&font->charstrings_subset_index);
  1838.     cff_index_init (&font->strings_subset_index);
  1839.     font->fdselect = NULL;
  1840.     font->fd_dict = NULL;
  1841.     font->fd_private_dict = NULL;
  1842.     font->fd_local_sub_index = NULL;
  1843.     font->fdselect_subset = NULL;
  1844.     font->fd_subset_map = NULL;
  1845.     font->private_dict_offset = NULL;
  1846.  
  1847.     *font_return = font;
  1848.  
  1849.     return CAIRO_STATUS_SUCCESS;
  1850.  
  1851. fail7:
  1852.     _cairo_hash_table_destroy (font->top_dict);
  1853. fail6:
  1854.     free (font->data);
  1855. fail5:
  1856.     free (font->widths);
  1857. fail4:
  1858.     if (font->font_name)
  1859.         free (font->font_name);
  1860. fail3:
  1861.     free (font->subset_font_name);
  1862. fail2:
  1863.     _cairo_array_fini (&font->output);
  1864.     free (font);
  1865.  
  1866.     return status;
  1867. }
  1868.  
  1869. static void
  1870. cairo_cff_font_destroy (cairo_cff_font_t *font)
  1871. {
  1872.     unsigned int i;
  1873.  
  1874.     free (font->widths);
  1875.     if (font->font_name)
  1876.         free (font->font_name);
  1877.     free (font->ps_name);
  1878.     free (font->subset_font_name);
  1879.     _cairo_array_fini (&font->output);
  1880.     cff_dict_fini (font->top_dict);
  1881.     cff_dict_fini (font->private_dict);
  1882.     cff_index_fini (&font->strings_index);
  1883.     cff_index_fini (&font->charstrings_index);
  1884.     cff_index_fini (&font->global_sub_index);
  1885.     cff_index_fini (&font->local_sub_index);
  1886.     cff_index_fini (&font->charstrings_subset_index);
  1887.     cff_index_fini (&font->strings_subset_index);
  1888.  
  1889.     /* If we bailed out early as a result of an error some of the
  1890.      * following cairo_cff_font_t members may still be NULL */
  1891.     if (font->fd_dict) {
  1892.         for (i = 0; i < font->num_fontdicts; i++) {
  1893.             if (font->fd_dict[i])
  1894.                 cff_dict_fini (font->fd_dict[i]);
  1895.         }
  1896.         free (font->fd_dict);
  1897.     }
  1898.     if (font->fd_subset_map)
  1899.         free (font->fd_subset_map);
  1900.     if (font->private_dict_offset)
  1901.         free (font->private_dict_offset);
  1902.  
  1903.     if (font->is_cid) {
  1904.         if (font->fdselect)
  1905.             free (font->fdselect);
  1906.         if (font->fdselect_subset)
  1907.             free (font->fdselect_subset);
  1908.         if (font->fd_private_dict) {
  1909.             for (i = 0; i < font->num_fontdicts; i++) {
  1910.                 if (font->fd_private_dict[i])
  1911.                     cff_dict_fini (font->fd_private_dict[i]);
  1912.             }
  1913.             free (font->fd_private_dict);
  1914.         }
  1915.         if (font->fd_local_sub_index) {
  1916.             for (i = 0; i < font->num_fontdicts; i++)
  1917.                 cff_index_fini (&font->fd_local_sub_index[i]);
  1918.             free (font->fd_local_sub_index);
  1919.         }
  1920.     }
  1921.  
  1922.     if (font->data)
  1923.         free (font->data);
  1924.  
  1925.     free (font);
  1926. }
  1927.  
  1928. cairo_status_t
  1929. _cairo_cff_subset_init (cairo_cff_subset_t          *cff_subset,
  1930.                         const char                  *subset_name,
  1931.                         cairo_scaled_font_subset_t  *font_subset)
  1932. {
  1933.     cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
  1934.     cairo_status_t status;
  1935.     const char *data = NULL; /* squelch bogus compiler warning */
  1936.     unsigned long length = 0; /* squelch bogus compiler warning */
  1937.     unsigned int i;
  1938.  
  1939.     status = _cairo_cff_font_create (font_subset, &font, subset_name);
  1940.     if (unlikely (status))
  1941.         return status;
  1942.  
  1943.     status = cairo_cff_font_generate (font, &data, &length);
  1944.     if (unlikely (status))
  1945.         goto fail1;
  1946.  
  1947.     cff_subset->ps_name = strdup (font->ps_name);
  1948.     if (unlikely (cff_subset->ps_name == NULL)) {
  1949.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1950.         goto fail1;
  1951.     }
  1952.  
  1953.     if (font->font_name) {
  1954.         cff_subset->font_name = strdup (font->font_name);
  1955.         if (cff_subset->font_name == NULL) {
  1956.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1957.             goto fail2;
  1958.         }
  1959.     } else {
  1960.         cff_subset->font_name = NULL;
  1961.     }
  1962.  
  1963.     cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
  1964.     if (unlikely (cff_subset->widths == NULL)) {
  1965.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1966.         goto fail3;
  1967.     }
  1968.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
  1969.         cff_subset->widths[i] = (double)font->widths[i]/font->units_per_em;
  1970.  
  1971.     cff_subset->x_min = (double)font->x_min/font->units_per_em;
  1972.     cff_subset->y_min = (double)font->y_min/font->units_per_em;
  1973.     cff_subset->x_max = (double)font->x_max/font->units_per_em;
  1974.     cff_subset->y_max = (double)font->y_max/font->units_per_em;
  1975.     cff_subset->ascent = (double)font->ascent/font->units_per_em;
  1976.     cff_subset->descent = (double)font->descent/font->units_per_em;
  1977.  
  1978.     cff_subset->data = malloc (length);
  1979.     if (unlikely (cff_subset->data == NULL)) {
  1980.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1981.         goto fail4;
  1982.     }
  1983.  
  1984.     memcpy (cff_subset->data, data, length);
  1985.     cff_subset->data_length = length;
  1986.  
  1987.     cairo_cff_font_destroy (font);
  1988.  
  1989.     return CAIRO_STATUS_SUCCESS;
  1990.  
  1991.  fail4:
  1992.     free (cff_subset->widths);
  1993.  fail3:
  1994.     if (cff_subset->font_name)
  1995.         free (cff_subset->font_name);
  1996.  fail2:
  1997.     free (cff_subset->ps_name);
  1998.  fail1:
  1999.     cairo_cff_font_destroy (font);
  2000.  
  2001.     return status;
  2002. }
  2003.  
  2004. void
  2005. _cairo_cff_subset_fini (cairo_cff_subset_t *subset)
  2006. {
  2007.     free (subset->ps_name);
  2008.     if (subset->font_name)
  2009.         free (subset->font_name);
  2010.     free (subset->widths);
  2011.     free (subset->data);
  2012. }
  2013.  
  2014. static cairo_int_status_t
  2015. _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t  *scaled_font_subset,
  2016.                                  cairo_cff_font_t           **font_return,
  2017.                                  const char                  *subset_name)
  2018. {
  2019.     cairo_status_t status;
  2020.     cairo_cff_font_t *font;
  2021.  
  2022.     font = malloc (sizeof (cairo_cff_font_t));
  2023.     if (unlikely (font == NULL))
  2024.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2025.  
  2026.     font->backend = NULL;
  2027.     font->scaled_font_subset = scaled_font_subset;
  2028.  
  2029.     _cairo_array_init (&font->output, sizeof (char));
  2030.     status = _cairo_array_grow_by (&font->output, 4096);
  2031.     if (unlikely (status))
  2032.         goto fail1;
  2033.  
  2034.     font->subset_font_name = strdup (subset_name);
  2035.     if (unlikely (font->subset_font_name == NULL)) {
  2036.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2037.         goto fail1;
  2038.     }
  2039.  
  2040.     font->ps_name = strdup (subset_name);
  2041.     if (unlikely (font->ps_name == NULL)) {
  2042.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2043.         goto fail2;
  2044.     }
  2045.     font->font_name = NULL;
  2046.  
  2047.     font->x_min = 0;
  2048.     font->y_min = 0;
  2049.     font->x_max = 0;
  2050.     font->y_max = 0;
  2051.     font->ascent = 0;
  2052.     font->descent = 0;
  2053.  
  2054.     font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int));
  2055.     if (unlikely (font->widths == NULL)) {
  2056.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2057.         goto fail3;
  2058.     }
  2059.  
  2060.     font->data_length = 0;
  2061.     font->data = NULL;
  2062.     font->data_end = NULL;
  2063.  
  2064.     status = cff_dict_init (&font->top_dict);
  2065.     if (unlikely (status))
  2066.         goto fail4;
  2067.  
  2068.     status = cff_dict_init (&font->private_dict);
  2069.     if (unlikely (status))
  2070.         goto fail5;
  2071.  
  2072.     cff_index_init (&font->strings_index);
  2073.     cff_index_init (&font->charstrings_index);
  2074.     cff_index_init (&font->global_sub_index);
  2075.     cff_index_init (&font->local_sub_index);
  2076.     cff_index_init (&font->charstrings_subset_index);
  2077.     cff_index_init (&font->strings_subset_index);
  2078.     font->fdselect = NULL;
  2079.     font->fd_dict = NULL;
  2080.     font->fd_private_dict = NULL;
  2081.     font->fd_local_sub_index = NULL;
  2082.     font->fdselect_subset = NULL;
  2083.     font->fd_subset_map = NULL;
  2084.     font->private_dict_offset = NULL;
  2085.  
  2086.     *font_return = font;
  2087.  
  2088.     return CAIRO_STATUS_SUCCESS;
  2089.  
  2090. fail5:
  2091.     _cairo_hash_table_destroy (font->top_dict);
  2092. fail4:
  2093.     free (font->widths);
  2094. fail3:
  2095.     if (font->font_name)
  2096.         free (font->font_name);
  2097.     free (font->ps_name);
  2098. fail2:
  2099.     free (font->subset_font_name);
  2100. fail1:
  2101.     _cairo_array_fini (&font->output);
  2102.     free (font);
  2103.     return status;
  2104. }
  2105.  
  2106. static cairo_int_status_t
  2107. cairo_cff_font_fallback_generate (cairo_cff_font_t           *font,
  2108.                                   cairo_type2_charstrings_t  *type2_subset,
  2109.                                   const char                **data,
  2110.                                   unsigned long              *length)
  2111. {
  2112.     cairo_int_status_t status;
  2113.     cff_header_t header;
  2114.     cairo_array_t *charstring;
  2115.     unsigned char buf[40];
  2116.     unsigned char *end_buf;
  2117.     unsigned int i;
  2118.  
  2119.     /* Create header */
  2120.     header.major = 1;
  2121.     header.minor = 0;
  2122.     header.header_size = 4;
  2123.     header.offset_size = 4;
  2124.     font->header = &header;
  2125.  
  2126.     /* Create Top Dict */
  2127.     font->is_cid = FALSE;
  2128.     end_buf = encode_integer (buf, type2_subset->x_min);
  2129.     end_buf = encode_integer (end_buf, type2_subset->y_min);
  2130.     end_buf = encode_integer (end_buf, type2_subset->x_max);
  2131.     end_buf = encode_integer (end_buf, type2_subset->y_max);
  2132.     status = cff_dict_set_operands (font->top_dict,
  2133.                                     FONTBBOX_OP, buf, end_buf - buf);
  2134.     if (unlikely (status))
  2135.         return status;
  2136.  
  2137.     end_buf = encode_integer_max (buf, 0);
  2138.     status = cff_dict_set_operands (font->top_dict,
  2139.                                     CHARSTRINGS_OP, buf, end_buf - buf);
  2140.     if (unlikely (status))
  2141.         return status;
  2142.  
  2143.     status = cff_dict_set_operands (font->top_dict,
  2144.                                     FDSELECT_OP, buf, end_buf - buf);
  2145.     if (unlikely (status))
  2146.         return status;
  2147.  
  2148.     status = cff_dict_set_operands (font->top_dict,
  2149.                                     FDARRAY_OP, buf, end_buf - buf);
  2150.     if (unlikely (status))
  2151.         return status;
  2152.  
  2153.     status = cff_dict_set_operands (font->top_dict,
  2154.                                     CHARSET_OP, buf, end_buf - buf);
  2155.     if (unlikely (status))
  2156.         return status;
  2157.  
  2158.     status = cairo_cff_font_set_ros_strings (font);
  2159.     if (unlikely (status))
  2160.         return status;
  2161.  
  2162.     /* Create CID FD dictionary */
  2163.     status = cairo_cff_font_create_cid_fontdict (font);
  2164.     if (unlikely (status))
  2165.         return status;
  2166.  
  2167.     /* Create charstrings */
  2168.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  2169.         charstring = _cairo_array_index(&type2_subset->charstrings, i);
  2170.  
  2171.         status = cff_index_append (&font->charstrings_subset_index,
  2172.                                    _cairo_array_index (charstring, 0),
  2173.                                    _cairo_array_num_elements (charstring));
  2174.  
  2175.         if (unlikely (status))
  2176.             return status;
  2177.     }
  2178.  
  2179.     status = cairo_cff_font_write_subset (font);
  2180.     if (unlikely (status))
  2181.         return status;
  2182.  
  2183.     *data = _cairo_array_index (&font->output, 0);
  2184.     *length = _cairo_array_num_elements (&font->output);
  2185.  
  2186.     return CAIRO_STATUS_SUCCESS;
  2187. }
  2188.  
  2189. cairo_status_t
  2190. _cairo_cff_fallback_init (cairo_cff_subset_t          *cff_subset,
  2191.                           const char                  *subset_name,
  2192.                           cairo_scaled_font_subset_t  *font_subset)
  2193. {
  2194.     cairo_cff_font_t *font = NULL; /* squelch bogus compiler warning */
  2195.     cairo_status_t status;
  2196.     const char *data = NULL; /* squelch bogus compiler warning */
  2197.     unsigned long length = 0; /* squelch bogus compiler warning */
  2198.     unsigned int i;
  2199.     cairo_type2_charstrings_t type2_subset;
  2200.  
  2201.     status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name);
  2202.     if (unlikely (status))
  2203.         return status;
  2204.  
  2205.     status = _cairo_type2_charstrings_init (&type2_subset, font_subset);
  2206.     if (unlikely (status))
  2207.         goto fail1;
  2208.  
  2209.     status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length);
  2210.     if (unlikely (status))
  2211.         goto fail2;
  2212.  
  2213.     cff_subset->font_name = NULL;
  2214.     cff_subset->ps_name = strdup (font->ps_name);
  2215.     if (unlikely (cff_subset->ps_name == NULL)) {
  2216.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2217.         goto fail2;
  2218.     }
  2219.  
  2220.     cff_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs);
  2221.     if (unlikely (cff_subset->widths == NULL)) {
  2222.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2223.         goto fail3;
  2224.     }
  2225.  
  2226.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
  2227.         cff_subset->widths[i] = (double)type2_subset.widths[i]/1000;
  2228.  
  2229.     cff_subset->x_min = (double)type2_subset.x_min/1000;
  2230.     cff_subset->y_min = (double)type2_subset.y_min/1000;
  2231.     cff_subset->x_max = (double)type2_subset.x_max/1000;
  2232.     cff_subset->y_max = (double)type2_subset.y_max/1000;
  2233.     cff_subset->ascent = (double)type2_subset.y_max/1000;
  2234.     cff_subset->descent = (double)type2_subset.y_min/1000;
  2235.  
  2236.     cff_subset->data = malloc (length);
  2237.     if (unlikely (cff_subset->data == NULL)) {
  2238.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  2239.         goto fail4;
  2240.     }
  2241.  
  2242.     memcpy (cff_subset->data, data, length);
  2243.     cff_subset->data_length = length;
  2244.     cff_subset->data_length = length;
  2245.  
  2246.     _cairo_type2_charstrings_fini (&type2_subset);
  2247.     cairo_cff_font_destroy (font);
  2248.  
  2249.     return CAIRO_STATUS_SUCCESS;
  2250.  
  2251.  fail4:
  2252.     free (cff_subset->widths);
  2253.  fail3:
  2254.     free (cff_subset->ps_name);
  2255.  fail2:
  2256.     _cairo_type2_charstrings_fini (&type2_subset);
  2257.  fail1:
  2258.     cairo_cff_font_destroy (font);
  2259.  
  2260.     return status;
  2261. }
  2262.  
  2263. void
  2264. _cairo_cff_fallback_fini (cairo_cff_subset_t *subset)
  2265. {
  2266.     free (subset->ps_name);
  2267.     free (subset->widths);
  2268.     free (subset->data);
  2269. }
  2270.  
  2271. #endif /* CAIRO_HAS_FONT_SUBSET */
  2272.