Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* cairo - a vector graphics library with display and print output
  2.  *
  3.  * Copyright © 2004 Red Hat, Inc
  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 Red Hat, Inc.
  31.  *
  32.  * Contributor(s):
  33.  *      Kristian Høgsberg <krh@redhat.com>
  34.  *      Adrian Johnson <ajohnson@redneon.com>
  35.  */
  36.  
  37. /*
  38.  * Useful links:
  39.  * http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6.html
  40.  * http://www.microsoft.com/typography/specs/default.htm
  41.  */
  42.  
  43. #define _BSD_SOURCE /* for snprintf(), strdup() */
  44. #include "cairoint.h"
  45.  
  46. #include "cairo-array-private.h"
  47. #include "cairo-error-private.h"
  48.  
  49. #if CAIRO_HAS_FONT_SUBSET
  50.  
  51. #include "cairo-scaled-font-subsets-private.h"
  52. #include "cairo-truetype-subset-private.h"
  53.  
  54.  
  55. typedef struct subset_glyph subset_glyph_t;
  56. struct subset_glyph {
  57.     int parent_index;
  58.     unsigned long location;
  59. };
  60.  
  61. typedef struct _cairo_truetype_font cairo_truetype_font_t;
  62.  
  63. typedef struct table table_t;
  64. struct table {
  65.     unsigned long tag;
  66.     cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag);
  67.     int pos; /* position in the font directory */
  68. };
  69.  
  70. struct _cairo_truetype_font {
  71.  
  72.     cairo_scaled_font_subset_t *scaled_font_subset;
  73.  
  74.     table_t truetype_tables[10];
  75.     int num_tables;
  76.  
  77.     struct {
  78.         char *font_name;
  79.         char *ps_name;
  80.         unsigned int num_glyphs;
  81.         int *widths;
  82.         long x_min, y_min, x_max, y_max;
  83.         long ascent, descent;
  84.         int  units_per_em;
  85.     } base;
  86.  
  87.     subset_glyph_t *glyphs;
  88.     const cairo_scaled_font_backend_t *backend;
  89.     int num_glyphs_in_face;
  90.     int checksum_index;
  91.     cairo_array_t output;
  92.     cairo_array_t string_offsets;
  93.     unsigned long last_offset;
  94.     unsigned long last_boundary;
  95.     int *parent_to_subset;
  96.     cairo_status_t status;
  97.     cairo_bool_t is_pdf;
  98. };
  99.  
  100. /*
  101.  * Test that the structs we define for TrueType tables have the
  102.  * correct size, ie. they are not padded.
  103.  */
  104. #define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S))
  105. check (tt_head_t,       54);
  106. check (tt_hhea_t,       36);
  107. check (tt_maxp_t,       32);
  108. check (tt_name_record_t, 12);
  109. check (tt_name_t,       18);
  110. check (tt_name_t,       18);
  111. check (tt_composite_glyph_t, 16);
  112. check (tt_glyph_data_t, 26);
  113. #undef check
  114.  
  115. static cairo_status_t
  116. cairo_truetype_font_use_glyph (cairo_truetype_font_t        *font,
  117.                                unsigned short                glyph,
  118.                                unsigned short               *out);
  119.  
  120. #define SFNT_VERSION                    0x00010000
  121. #define SFNT_STRING_MAX_LENGTH  65535
  122.  
  123. static cairo_status_t
  124. _cairo_truetype_font_set_error (cairo_truetype_font_t *font,
  125.                                 cairo_status_t status)
  126. {
  127.     if (status == CAIRO_STATUS_SUCCESS ||
  128.         status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
  129.         return status;
  130.  
  131.     _cairo_status_set_error (&font->status, status);
  132.  
  133.     return _cairo_error (status);
  134. }
  135.  
  136. static cairo_status_t
  137. _cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
  138.                              cairo_bool_t is_pdf,
  139.                              cairo_truetype_font_t      **font_return)
  140. {
  141.     cairo_status_t status;
  142.     cairo_truetype_font_t *font;
  143.     const cairo_scaled_font_backend_t *backend;
  144.     tt_head_t head;
  145.     tt_hhea_t hhea;
  146.     tt_maxp_t maxp;
  147.     unsigned long size;
  148.  
  149.     backend = scaled_font_subset->scaled_font->backend;
  150.     if (!backend->load_truetype_table)
  151.         return CAIRO_INT_STATUS_UNSUPPORTED;
  152.  
  153.     /* FIXME: We should either support subsetting vertical fonts, or fail on
  154.      * vertical.  Currently font_options_t doesn't have vertical flag, but
  155.      * it should be added in the future.  For now, the freetype backend
  156.      * returns UNSUPPORTED in load_truetype_table if the font is vertical.
  157.      *
  158.      *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
  159.      *   return CAIRO_INT_STATUS_UNSUPPORTED;
  160.      */
  161.  
  162.     /* We need to use a fallback font generated from the synthesized outlines. */
  163.     if (backend->is_synthetic && backend->is_synthetic (scaled_font_subset->scaled_font))
  164.        return CAIRO_INT_STATUS_UNSUPPORTED;
  165.  
  166.     size = sizeof (tt_head_t);
  167.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  168.                                           TT_TAG_head, 0,
  169.                                           (unsigned char *) &head,
  170.                                           &size);
  171.     if (unlikely (status))
  172.         return status;
  173.  
  174.     size = sizeof (tt_maxp_t);
  175.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  176.                                            TT_TAG_maxp, 0,
  177.                                            (unsigned char *) &maxp,
  178.                                            &size);
  179.     if (unlikely (status))
  180.         return status;
  181.  
  182.     size = sizeof (tt_hhea_t);
  183.     status = backend->load_truetype_table (scaled_font_subset->scaled_font,
  184.                                            TT_TAG_hhea, 0,
  185.                                            (unsigned char *) &hhea,
  186.                                            &size);
  187.     if (unlikely (status))
  188.         return status;
  189.  
  190.     font = malloc (sizeof (cairo_truetype_font_t));
  191.     if (unlikely (font == NULL))
  192.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  193.  
  194.     font->backend = backend;
  195.     font->num_glyphs_in_face = be16_to_cpu (maxp.num_glyphs);
  196.     font->scaled_font_subset = scaled_font_subset;
  197.  
  198.     font->last_offset = 0;
  199.     font->last_boundary = 0;
  200.     _cairo_array_init (&font->output, sizeof (char));
  201.     status = _cairo_array_grow_by (&font->output, 4096);
  202.     if (unlikely (status))
  203.         goto fail1;
  204.  
  205.     font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t));
  206.     if (unlikely (font->glyphs == NULL)) {
  207.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  208.         goto fail1;
  209.     }
  210.  
  211.     font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int));
  212.     if (unlikely (font->parent_to_subset == NULL)) {
  213.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  214.         goto fail2;
  215.     }
  216.  
  217.     font->is_pdf = is_pdf;
  218.     font->base.num_glyphs = 0;
  219.     font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
  220.     font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
  221.     font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
  222.     font->base.y_max = (int16_t) be16_to_cpu (head.y_max);
  223.     font->base.ascent = (int16_t) be16_to_cpu (hhea.ascender);
  224.     font->base.descent = (int16_t) be16_to_cpu (hhea.descender);
  225.     font->base.units_per_em = (int16_t) be16_to_cpu (head.units_per_em);
  226.     if (font->base.units_per_em == 0)
  227.         font->base.units_per_em = 2048;
  228.  
  229.     font->base.ps_name = NULL;
  230.     font->base.font_name = NULL;
  231.     status = _cairo_truetype_read_font_name (scaled_font_subset->scaled_font,
  232.                                              &font->base.ps_name,
  233.                                              &font->base.font_name);
  234.     if (_cairo_status_is_error (status))
  235.         goto fail3;
  236.  
  237.     /* If the PS name is not found, create a CairoFont-x-y name. */
  238.     if (font->base.ps_name == NULL) {
  239.         font->base.ps_name = malloc (30);
  240.         if (unlikely (font->base.ps_name == NULL)) {
  241.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  242.             goto fail3;
  243.         }
  244.  
  245.         snprintf(font->base.ps_name, 30, "CairoFont-%u-%u",
  246.                  scaled_font_subset->font_id,
  247.                  scaled_font_subset->subset_id);
  248.     }
  249.  
  250.     font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int));
  251.     if (unlikely (font->base.widths == NULL)) {
  252.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  253.         goto fail4;
  254.     }
  255.  
  256.     _cairo_array_init (&font->string_offsets, sizeof (unsigned long));
  257.     status = _cairo_array_grow_by (&font->string_offsets, 10);
  258.     if (unlikely (status))
  259.         goto fail5;
  260.  
  261.     font->status = CAIRO_STATUS_SUCCESS;
  262.  
  263.     *font_return = font;
  264.  
  265.     return CAIRO_STATUS_SUCCESS;
  266.  
  267.  fail5:
  268.     _cairo_array_fini (&font->string_offsets);
  269.     free (font->base.widths);
  270.  fail4:
  271.     free (font->base.ps_name);
  272.  fail3:
  273.     free (font->parent_to_subset);
  274.     free (font->base.font_name);
  275.  fail2:
  276.     free (font->glyphs);
  277.  fail1:
  278.     _cairo_array_fini (&font->output);
  279.     free (font);
  280.  
  281.     return status;
  282. }
  283.  
  284. static void
  285. cairo_truetype_font_destroy (cairo_truetype_font_t *font)
  286. {
  287.     _cairo_array_fini (&font->string_offsets);
  288.     free (font->base.widths);
  289.     free (font->base.ps_name);
  290.     free (font->base.font_name);
  291.     free (font->parent_to_subset);
  292.     free (font->glyphs);
  293.     _cairo_array_fini (&font->output);
  294.     free (font);
  295. }
  296.  
  297. static cairo_status_t
  298. cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t  *font,
  299.                                            size_t                  length,
  300.                                            unsigned char         **buffer)
  301. {
  302.     cairo_status_t status;
  303.  
  304.     if (font->status)
  305.         return font->status;
  306.  
  307.     status = _cairo_array_allocate (&font->output, length, (void **) buffer);
  308.     if (unlikely (status))
  309.         return _cairo_truetype_font_set_error (font, status);
  310.  
  311.     return CAIRO_STATUS_SUCCESS;
  312. }
  313.  
  314. static void
  315. cairo_truetype_font_write (cairo_truetype_font_t *font,
  316.                            const void            *data,
  317.                            size_t                 length)
  318. {
  319.     cairo_status_t status;
  320.  
  321.     if (font->status)
  322.         return;
  323.  
  324.     status = _cairo_array_append_multiple (&font->output, data, length);
  325.     if (unlikely (status))
  326.         status = _cairo_truetype_font_set_error (font, status);
  327. }
  328.  
  329. static void
  330. cairo_truetype_font_write_be16 (cairo_truetype_font_t *font,
  331.                                 uint16_t               value)
  332. {
  333.     uint16_t be16_value;
  334.  
  335.     if (font->status)
  336.         return;
  337.  
  338.     be16_value = cpu_to_be16 (value);
  339.     cairo_truetype_font_write (font, &be16_value, sizeof be16_value);
  340. }
  341.  
  342. static void
  343. cairo_truetype_font_write_be32 (cairo_truetype_font_t *font,
  344.                                 uint32_t               value)
  345. {
  346.     uint32_t be32_value;
  347.  
  348.     if (font->status)
  349.         return;
  350.  
  351.     be32_value = cpu_to_be32 (value);
  352.     cairo_truetype_font_write (font, &be32_value, sizeof be32_value);
  353. }
  354.  
  355. static cairo_status_t
  356. cairo_truetype_font_align_output (cairo_truetype_font_t     *font,
  357.                                   unsigned long             *aligned)
  358. {
  359.     int length, pad;
  360.     unsigned char *padding;
  361.  
  362.     length = _cairo_array_num_elements (&font->output);
  363.     *aligned = (length + 3) & ~3;
  364.     pad = *aligned - length;
  365.  
  366.     if (pad) {
  367.         cairo_status_t status;
  368.  
  369.         status = cairo_truetype_font_allocate_write_buffer (font, pad,
  370.                                                             &padding);
  371.         if (unlikely (status))
  372.             return status;
  373.  
  374.         memset (padding, 0, pad);
  375.     }
  376.  
  377.     return CAIRO_STATUS_SUCCESS;
  378. }
  379.  
  380. static cairo_status_t
  381. cairo_truetype_font_check_boundary (cairo_truetype_font_t *font,
  382.                                     unsigned long          boundary)
  383. {
  384.     cairo_status_t status;
  385.  
  386.     if (font->status)
  387.         return font->status;
  388.  
  389.     if (boundary - font->last_offset > SFNT_STRING_MAX_LENGTH)
  390.     {
  391.         status = _cairo_array_append (&font->string_offsets,
  392.                                       &font->last_boundary);
  393.         if (unlikely (status))
  394.             return _cairo_truetype_font_set_error (font, status);
  395.  
  396.         font->last_offset = font->last_boundary;
  397.     }
  398.     font->last_boundary = boundary;
  399.  
  400.     return CAIRO_STATUS_SUCCESS;
  401. }
  402.  
  403. typedef struct _cmap_unicode_range {
  404.     unsigned int start;
  405.     unsigned int end;
  406. } cmap_unicode_range_t;
  407.  
  408. static cmap_unicode_range_t winansi_unicode_ranges[] = {
  409.     { 0x0020, 0x007f },
  410.     { 0x00a0, 0x00ff },
  411.     { 0x0152, 0x0153 },
  412.     { 0x0160, 0x0161 },
  413.     { 0x0178, 0x0178 },
  414.     { 0x017d, 0x017e },
  415.     { 0x0192, 0x0192 },
  416.     { 0x02c6, 0x02c6 },
  417.     { 0x02dc, 0x02dc },
  418.     { 0x2013, 0x2026 },
  419.     { 0x2030, 0x2030 },
  420.     { 0x2039, 0x203a },
  421.     { 0x20ac, 0x20ac },
  422.     { 0x2122, 0x2122 },
  423. };
  424.  
  425. static cairo_status_t
  426. cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
  427.                                       unsigned long          tag)
  428. {
  429.     int i;
  430.     unsigned int j;
  431.     int range_offset;
  432.     int num_ranges;
  433.     int entry_selector;
  434.     int length;
  435.  
  436.     num_ranges = ARRAY_LENGTH (winansi_unicode_ranges);
  437.  
  438.     length = 16 + (num_ranges + 1)*8;
  439.     for (i = 0; i < num_ranges; i++)
  440.         length += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2;
  441.  
  442.     entry_selector = 0;
  443.     while ((1 << entry_selector) <= (num_ranges + 1))
  444.         entry_selector++;
  445.  
  446.     entry_selector--;
  447.  
  448.     cairo_truetype_font_write_be16 (font, 0);  /* Table version */
  449.     cairo_truetype_font_write_be16 (font, 1);  /* Num tables */
  450.  
  451.     cairo_truetype_font_write_be16 (font, 3);  /* Platform */
  452.     cairo_truetype_font_write_be16 (font, 1);  /* Encoding */
  453.     cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
  454.  
  455.     /* Output a format 4 encoding table for the winansi encoding */
  456.  
  457.     cairo_truetype_font_write_be16 (font, 4);  /* Format */
  458.     cairo_truetype_font_write_be16 (font, length); /* Length */
  459.     cairo_truetype_font_write_be16 (font, 0);  /* Version */
  460.     cairo_truetype_font_write_be16 (font, num_ranges*2 + 2);  /* 2*segcount */
  461.     cairo_truetype_font_write_be16 (font, (1 << (entry_selector + 1)));  /* searchrange */
  462.     cairo_truetype_font_write_be16 (font, entry_selector);  /* entry selector */
  463.     cairo_truetype_font_write_be16 (font, num_ranges*2 + 2 - (1 << (entry_selector + 1)));  /* rangeshift */
  464.     for (i = 0; i < num_ranges; i++)
  465.         cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */
  466.     cairo_truetype_font_write_be16 (font, 0xffff);  /* end count[] */
  467.  
  468.     cairo_truetype_font_write_be16 (font, 0);       /* reserved */
  469.  
  470.     for (i = 0; i < num_ranges; i++)
  471.         cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].start);  /* startCode[] */
  472.     cairo_truetype_font_write_be16 (font, 0xffff);  /* startCode[] */
  473.  
  474.     for (i = 0; i < num_ranges; i++)
  475.         cairo_truetype_font_write_be16 (font, 0x0000);  /* delta[] */
  476.     cairo_truetype_font_write_be16 (font, 1);       /* delta[] */
  477.  
  478.     range_offset = num_ranges*2 + 2;
  479.     for (i = 0; i < num_ranges; i++) {
  480.         cairo_truetype_font_write_be16 (font, range_offset);       /* rangeOffset[] */
  481.         range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2;
  482.     }
  483.     cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[] */
  484.  
  485.     for (i = 0; i < num_ranges; i++) {
  486.         for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) {
  487.             int ch = _cairo_unicode_to_winansi (j);
  488.             int glyph;
  489.  
  490.             if (ch > 0)
  491.                 glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch];
  492.             else
  493.                 glyph = 0;
  494.             cairo_truetype_font_write_be16 (font, glyph);
  495.         }
  496.     }
  497.  
  498.     return font->status;
  499. }
  500.  
  501. static cairo_status_t
  502. cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font,
  503.                                          unsigned long          tag)
  504. {
  505.     cairo_status_t status;
  506.     unsigned char *buffer;
  507.     unsigned long size;
  508.  
  509.     if (font->status)
  510.         return font->status;
  511.  
  512.     size = 0;
  513.     status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font,
  514.                                                 tag, 0, NULL, &size);
  515.     if (unlikely (status))
  516.         return _cairo_truetype_font_set_error (font, status);
  517.  
  518.     status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
  519.     if (unlikely (status))
  520.         return _cairo_truetype_font_set_error (font, status);
  521.  
  522.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  523.                                                  tag, 0, buffer, &size);
  524.     if (unlikely (status))
  525.         return _cairo_truetype_font_set_error (font, status);
  526.  
  527.     return CAIRO_STATUS_SUCCESS;
  528. }
  529.  
  530. static cairo_status_t
  531. cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t        *font,
  532.                                            unsigned char                *buffer,
  533.                                            unsigned long                 size)
  534. {
  535.     tt_glyph_data_t *glyph_data;
  536.     tt_composite_glyph_t *composite_glyph;
  537.     int num_args;
  538.     int has_more_components;
  539.     unsigned short flags;
  540.     unsigned short index;
  541.     cairo_status_t status;
  542.     unsigned char *end = buffer + size;
  543.  
  544.     if (font->status)
  545.         return font->status;
  546.  
  547.     glyph_data = (tt_glyph_data_t *) buffer;
  548.     if ((unsigned char *)(&glyph_data->data) >= end)
  549.         return CAIRO_INT_STATUS_UNSUPPORTED;
  550.  
  551.     if ((int16_t)be16_to_cpu (glyph_data->num_contours) >= 0)
  552.         return CAIRO_STATUS_SUCCESS;
  553.  
  554.     composite_glyph = &glyph_data->glyph;
  555.     do {
  556.         if ((unsigned char *)(&composite_glyph->args[1]) > end)
  557.             return CAIRO_INT_STATUS_UNSUPPORTED;
  558.  
  559.         flags = be16_to_cpu (composite_glyph->flags);
  560.         has_more_components = flags & TT_MORE_COMPONENTS;
  561.         status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index);
  562.         if (unlikely (status))
  563.             return status;
  564.  
  565.         composite_glyph->index = cpu_to_be16 (index);
  566.         num_args = 1;
  567.         if (flags & TT_ARG_1_AND_2_ARE_WORDS)
  568.             num_args += 1;
  569.  
  570.         if (flags & TT_WE_HAVE_A_SCALE)
  571.             num_args += 1;
  572.         else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
  573.             num_args += 2;
  574.         else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
  575.             num_args += 4;
  576.  
  577.         composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
  578.     } while (has_more_components);
  579.  
  580.     return CAIRO_STATUS_SUCCESS;
  581. }
  582.  
  583. static cairo_status_t
  584. cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font,
  585.                                       unsigned long          tag)
  586. {
  587.     unsigned long start_offset, index, size, next;
  588.     tt_head_t header;
  589.     unsigned long begin, end;
  590.     unsigned char *buffer;
  591.     unsigned int i;
  592.     union {
  593.         unsigned char *bytes;
  594.         uint16_t      *short_offsets;
  595.         uint32_t      *long_offsets;
  596.     } u;
  597.     cairo_status_t status;
  598.  
  599.     if (font->status)
  600.         return font->status;
  601.  
  602.     size = sizeof (tt_head_t);
  603.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  604.                                                  TT_TAG_head, 0,
  605.                                                  (unsigned char*) &header, &size);
  606.     if (unlikely (status))
  607.         return _cairo_truetype_font_set_error (font, status);
  608.  
  609.     if (be16_to_cpu (header.index_to_loc_format) == 0)
  610.         size = sizeof (int16_t) * (font->num_glyphs_in_face + 1);
  611.     else
  612.         size = sizeof (int32_t) * (font->num_glyphs_in_face + 1);
  613.  
  614.     u.bytes = malloc (size);
  615.     if (unlikely (u.bytes == NULL))
  616.         return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY);
  617.  
  618.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  619.                                                  TT_TAG_loca, 0, u.bytes, &size);
  620.     if (unlikely (status))
  621.         return _cairo_truetype_font_set_error (font, status);
  622.  
  623.     start_offset = _cairo_array_num_elements (&font->output);
  624.     for (i = 0; i < font->base.num_glyphs; i++) {
  625.         index = font->glyphs[i].parent_index;
  626.         if (be16_to_cpu (header.index_to_loc_format) == 0) {
  627.             begin = be16_to_cpu (u.short_offsets[index]) * 2;
  628.             end = be16_to_cpu (u.short_offsets[index + 1]) * 2;
  629.         }
  630.         else {
  631.             begin = be32_to_cpu (u.long_offsets[index]);
  632.             end = be32_to_cpu (u.long_offsets[index + 1]);
  633.         }
  634.  
  635.         /* quick sanity check... */
  636.         if (end < begin) {
  637.             status = CAIRO_INT_STATUS_UNSUPPORTED;
  638.             goto FAIL;
  639.         }
  640.  
  641.         size = end - begin;
  642.         status = cairo_truetype_font_align_output (font, &next);
  643.         if (unlikely (status))
  644.             goto FAIL;
  645.  
  646.         status = cairo_truetype_font_check_boundary (font, next);
  647.         if (unlikely (status))
  648.             goto FAIL;
  649.  
  650.         font->glyphs[i].location = next - start_offset;
  651.  
  652.         status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
  653.         if (unlikely (status))
  654.             goto FAIL;
  655.  
  656.         if (size != 0) {
  657.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  658.                                                          TT_TAG_glyf, begin, buffer, &size);
  659.             if (unlikely (status))
  660.                 goto FAIL;
  661.  
  662.             status = cairo_truetype_font_remap_composite_glyph (font, buffer, size);
  663.             if (unlikely (status))
  664.                 goto FAIL;
  665.         }
  666.     }
  667.  
  668.     status = cairo_truetype_font_align_output (font, &next);
  669.     if (unlikely (status))
  670.         goto FAIL;
  671.  
  672.     font->glyphs[i].location = next - start_offset;
  673.  
  674.     status = font->status;
  675. FAIL:
  676.     free (u.bytes);
  677.  
  678.     return _cairo_truetype_font_set_error (font, status);
  679. }
  680.  
  681. static cairo_status_t
  682. cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
  683.                                       unsigned long          tag)
  684. {
  685.     unsigned char *buffer;
  686.     unsigned long size;
  687.     cairo_status_t status;
  688.  
  689.     if (font->status)
  690.         return font->status;
  691.  
  692.     size = 0;
  693.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  694.                                                  tag, 0, NULL, &size);
  695.     if (unlikely (status))
  696.         return _cairo_truetype_font_set_error (font, status);
  697.  
  698.     font->checksum_index = _cairo_array_num_elements (&font->output) + 8;
  699.     status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer);
  700.     if (unlikely (status))
  701.         return _cairo_truetype_font_set_error (font, status);
  702.  
  703.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  704.                                                  tag, 0, buffer, &size);
  705.     if (unlikely (status))
  706.         return _cairo_truetype_font_set_error (font, status);
  707.  
  708.     /* set checkSumAdjustment to 0 for table checksum calculation */
  709.     *(uint32_t *)(buffer + 8) = 0;
  710.  
  711.     return CAIRO_STATUS_SUCCESS;
  712. }
  713.  
  714. static cairo_status_t
  715. cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long tag)
  716. {
  717.     tt_hhea_t *hhea;
  718.     unsigned long size;
  719.     cairo_status_t status;
  720.  
  721.     if (font->status)
  722.         return font->status;
  723.  
  724.     size = sizeof (tt_hhea_t);
  725.     status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea);
  726.     if (unlikely (status))
  727.         return _cairo_truetype_font_set_error (font, status);
  728.  
  729.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  730.                                                  tag, 0, (unsigned char *) hhea, &size);
  731.     if (unlikely (status))
  732.         return _cairo_truetype_font_set_error (font, status);
  733.  
  734.     hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs));
  735.  
  736.     return CAIRO_STATUS_SUCCESS;
  737. }
  738.  
  739. static cairo_status_t
  740. cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font,
  741.                                       unsigned long          tag)
  742. {
  743.     unsigned long size;
  744.     unsigned long long_entry_size;
  745.     unsigned long short_entry_size;
  746.     short *p;
  747.     unsigned int i;
  748.     tt_hhea_t hhea;
  749.     int num_hmetrics;
  750.     cairo_status_t status;
  751.  
  752.     if (font->status)
  753.         return font->status;
  754.  
  755.     size = sizeof (tt_hhea_t);
  756.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  757.                                                  TT_TAG_hhea, 0,
  758.                                                  (unsigned char*) &hhea, &size);
  759.     if (unlikely (status))
  760.         return _cairo_truetype_font_set_error (font, status);
  761.  
  762.     num_hmetrics = be16_to_cpu(hhea.num_hmetrics);
  763.  
  764.     for (i = 0; i < font->base.num_glyphs; i++) {
  765.         long_entry_size = 2 * sizeof (int16_t);
  766.         short_entry_size = sizeof (int16_t);
  767.         status = cairo_truetype_font_allocate_write_buffer (font,
  768.                                                             long_entry_size,
  769.                                                             (unsigned char **) &p);
  770.         if (unlikely (status))
  771.             return _cairo_truetype_font_set_error (font, status);
  772.  
  773.         if (font->glyphs[i].parent_index < num_hmetrics) {
  774.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  775.                                                          TT_TAG_hmtx,
  776.                                                          font->glyphs[i].parent_index * long_entry_size,
  777.                                                          (unsigned char *) p, &long_entry_size);
  778.             if (unlikely (status))
  779.                 return _cairo_truetype_font_set_error (font, status);
  780.         }
  781.         else
  782.         {
  783.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  784.                                                          TT_TAG_hmtx,
  785.                                                          (num_hmetrics - 1) * long_entry_size,
  786.                                                          (unsigned char *) p, &short_entry_size);
  787.             if (unlikely (status))
  788.                 return _cairo_truetype_font_set_error (font, status);
  789.  
  790.             status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  791.                                                          TT_TAG_hmtx,
  792.                                                          num_hmetrics * long_entry_size +
  793.                                                          (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size,
  794.                                                          (unsigned char *) (p + 1), &short_entry_size);
  795.             if (unlikely (status))
  796.                 return _cairo_truetype_font_set_error (font, status);
  797.         }
  798.         font->base.widths[i] = be16_to_cpu (p[0]);
  799.     }
  800.  
  801.     return CAIRO_STATUS_SUCCESS;
  802. }
  803.  
  804. static cairo_status_t
  805. cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font,
  806.                                       unsigned long          tag)
  807. {
  808.     unsigned int i;
  809.     tt_head_t header;
  810.     unsigned long size;
  811.     cairo_status_t status;
  812.  
  813.     if (font->status)
  814.         return font->status;
  815.  
  816.     size = sizeof(tt_head_t);
  817.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  818.                                                  TT_TAG_head, 0,
  819.                                                  (unsigned char*) &header, &size);
  820.     if (unlikely (status))
  821.         return _cairo_truetype_font_set_error (font, status);
  822.  
  823.     if (be16_to_cpu (header.index_to_loc_format) == 0)
  824.     {
  825.         for (i = 0; i < font->base.num_glyphs + 1; i++)
  826.             cairo_truetype_font_write_be16 (font, font->glyphs[i].location / 2);
  827.     } else {
  828.         for (i = 0; i < font->base.num_glyphs + 1; i++)
  829.             cairo_truetype_font_write_be32 (font, font->glyphs[i].location);
  830.     }
  831.  
  832.     return font->status;
  833. }
  834.  
  835. static cairo_status_t
  836. cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font,
  837.                                       unsigned long          tag)
  838. {
  839.     tt_maxp_t *maxp;
  840.     unsigned long size;
  841.     cairo_status_t status;
  842.  
  843.     if (font->status)
  844.         return font->status;
  845.  
  846.     size = sizeof (tt_maxp_t);
  847.     status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp);
  848.     if (unlikely (status))
  849.         return _cairo_truetype_font_set_error (font, status);
  850.  
  851.     status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  852.                                                  tag, 0, (unsigned char *) maxp, &size);
  853.     if (unlikely (status))
  854.         return _cairo_truetype_font_set_error (font, status);
  855.  
  856.     maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs);
  857.  
  858.     return CAIRO_STATUS_SUCCESS;
  859. }
  860.  
  861. static cairo_status_t
  862. cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font)
  863. {
  864.     cairo_status_t status;
  865.     unsigned char *table_buffer;
  866.     size_t table_buffer_length;
  867.     unsigned short search_range, entry_selector, range_shift;
  868.  
  869.     if (font->status)
  870.         return font->status;
  871.  
  872.     search_range = 1;
  873.     entry_selector = 0;
  874.     while (search_range * 2 <= font->num_tables) {
  875.         search_range *= 2;
  876.         entry_selector++;
  877.     }
  878.     search_range *= 16;
  879.     range_shift = font->num_tables * 16 - search_range;
  880.  
  881.     cairo_truetype_font_write_be32 (font, SFNT_VERSION);
  882.     cairo_truetype_font_write_be16 (font, font->num_tables);
  883.     cairo_truetype_font_write_be16 (font, search_range);
  884.     cairo_truetype_font_write_be16 (font, entry_selector);
  885.     cairo_truetype_font_write_be16 (font, range_shift);
  886.  
  887.     /* Allocate space for the table directory. Each directory entry
  888.      * will be filled in by cairo_truetype_font_update_entry() after
  889.      * the table is written. */
  890.     table_buffer_length = font->num_tables * 16;
  891.     status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length,
  892.                                                       &table_buffer);
  893.     if (unlikely (status))
  894.         return _cairo_truetype_font_set_error (font, status);
  895.  
  896.     return CAIRO_STATUS_SUCCESS;
  897. }
  898.  
  899. static uint32_t
  900. cairo_truetype_font_calculate_checksum (cairo_truetype_font_t *font,
  901.                                         unsigned long          start,
  902.                                         unsigned long          end)
  903. {
  904.     uint32_t *padded_end;
  905.     uint32_t *p;
  906.     uint32_t checksum;
  907.     char *data;
  908.  
  909.     checksum = 0;
  910.     data = _cairo_array_index (&font->output, 0);
  911.     p = (uint32_t *) (data + start);
  912.     padded_end = (uint32_t *) (data + ((end + 3) & ~3));
  913.     while (p < padded_end)
  914.         checksum += be32_to_cpu(*p++);
  915.  
  916.     return checksum;
  917. }
  918.  
  919. static void
  920. cairo_truetype_font_update_entry (cairo_truetype_font_t *font,
  921.                                   int                    index,
  922.                                   unsigned long          tag,
  923.                                   unsigned long          start,
  924.                                   unsigned long          end)
  925. {
  926.     uint32_t *entry;
  927.  
  928.     entry = _cairo_array_index (&font->output, 12 + 16 * index);
  929.     entry[0] = cpu_to_be32 ((uint32_t)tag);
  930.     entry[1] = cpu_to_be32 (cairo_truetype_font_calculate_checksum (font, start, end));
  931.     entry[2] = cpu_to_be32 ((uint32_t)start);
  932.     entry[3] = cpu_to_be32 ((uint32_t)(end - start));
  933. }
  934.  
  935. static cairo_status_t
  936. cairo_truetype_font_generate (cairo_truetype_font_t  *font,
  937.                               const char            **data,
  938.                               unsigned long          *length,
  939.                               const unsigned long   **string_offsets,
  940.                               unsigned long          *num_strings)
  941. {
  942.     cairo_status_t status;
  943.     unsigned long start, end, next;
  944.     uint32_t checksum, *checksum_location;
  945.     int i;
  946.  
  947.     if (font->status)
  948.         return font->status;
  949.  
  950.     status = cairo_truetype_font_write_offset_table (font);
  951.     if (unlikely (status))
  952.         goto FAIL;
  953.  
  954.     status = cairo_truetype_font_align_output (font, &start);
  955.     if (unlikely (status))
  956.         goto FAIL;
  957.  
  958.     end = 0;
  959.     for (i = 0; i < font->num_tables; i++) {
  960.         status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag);
  961.         if (unlikely (status))
  962.             goto FAIL;
  963.  
  964.         end = _cairo_array_num_elements (&font->output);
  965.         status = cairo_truetype_font_align_output (font, &next);
  966.         if (unlikely (status))
  967.             goto FAIL;
  968.  
  969.         cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos,
  970.                                           font->truetype_tables[i].tag, start, end);
  971.         status = cairo_truetype_font_check_boundary (font, next);
  972.         if (unlikely (status))
  973.             goto FAIL;
  974.  
  975.         start = next;
  976.     }
  977.  
  978.     checksum =
  979.         0xb1b0afba - cairo_truetype_font_calculate_checksum (font, 0, end);
  980.     checksum_location = _cairo_array_index (&font->output, font->checksum_index);
  981.     *checksum_location = cpu_to_be32 (checksum);
  982.  
  983.     *data = _cairo_array_index (&font->output, 0);
  984.     *length = _cairo_array_num_elements (&font->output);
  985.     *num_strings = _cairo_array_num_elements (&font->string_offsets);
  986.     if (*num_strings != 0)
  987.         *string_offsets = _cairo_array_index (&font->string_offsets, 0);
  988.     else
  989.         *string_offsets = NULL;
  990.  
  991.  FAIL:
  992.     return _cairo_truetype_font_set_error (font, status);
  993. }
  994.  
  995. static cairo_status_t
  996. cairo_truetype_font_use_glyph (cairo_truetype_font_t        *font,
  997.                                unsigned short                glyph,
  998.                                unsigned short               *out)
  999. {
  1000.     if (glyph >= font->num_glyphs_in_face)
  1001.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1002.  
  1003.     if (font->parent_to_subset[glyph] == 0) {
  1004.         font->parent_to_subset[glyph] = font->base.num_glyphs;
  1005.         font->glyphs[font->base.num_glyphs].parent_index = glyph;
  1006.         font->base.num_glyphs++;
  1007.     }
  1008.  
  1009.     *out = font->parent_to_subset[glyph];
  1010.     return CAIRO_STATUS_SUCCESS;
  1011. }
  1012.  
  1013. static void
  1014. cairo_truetype_font_add_truetype_table (cairo_truetype_font_t *font,
  1015.            unsigned long tag,
  1016.            cairo_status_t (*write) (cairo_truetype_font_t *font, unsigned long tag),
  1017.            int pos)
  1018. {
  1019.     font->truetype_tables[font->num_tables].tag = tag;
  1020.     font->truetype_tables[font->num_tables].write = write;
  1021.     font->truetype_tables[font->num_tables].pos = pos;
  1022.     font->num_tables++;
  1023. }
  1024.  
  1025. /* cairo_truetype_font_create_truetype_table_list() builds the list of
  1026.  * truetype tables to be embedded in the subsetted font. Each call to
  1027.  * cairo_truetype_font_add_truetype_table() adds a table, the callback
  1028.  * for generating the table, and the position in the table directory
  1029.  * to the truetype_tables array.
  1030.  *
  1031.  * As we write out the glyf table we remap composite glyphs.
  1032.  * Remapping composite glyphs will reference the sub glyphs the
  1033.  * composite glyph is made up of. The "glyf" table callback needs to
  1034.  * be called first so we have all the glyphs in the subset before
  1035.  * going further.
  1036.  *
  1037.  * The order in which tables are added to the truetype_table array
  1038.  * using cairo_truetype_font_add_truetype_table() specifies the order
  1039.  * in which the callback functions will be called.
  1040.  *
  1041.  * The tables in the table directory must be listed in alphabetical
  1042.  * order.  The "cvt", "fpgm", and "prep" are optional tables. They
  1043.  * will only be embedded in the subset if they exist in the source
  1044.  * font. "cmap" is only embedded for latin fonts. The pos parameter of
  1045.  * cairo_truetype_font_add_truetype_table() specifies the position of
  1046.  * the table in the table directory.
  1047.  */
  1048. static void
  1049. cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
  1050. {
  1051.     cairo_bool_t has_cvt = FALSE;
  1052.     cairo_bool_t has_fpgm = FALSE;
  1053.     cairo_bool_t has_prep = FALSE;
  1054.     unsigned long size;
  1055.     int pos;
  1056.  
  1057.     size = 0;
  1058.     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1059.                                       TT_TAG_cvt, 0, NULL,
  1060.                                       &size) == CAIRO_INT_STATUS_SUCCESS)
  1061.         has_cvt = TRUE;
  1062.  
  1063.     size = 0;
  1064.     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1065.                                       TT_TAG_fpgm, 0, NULL,
  1066.                                       &size) == CAIRO_INT_STATUS_SUCCESS)
  1067.         has_fpgm = TRUE;
  1068.  
  1069.     size = 0;
  1070.     if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
  1071.                                       TT_TAG_prep, 0, NULL,
  1072.                                       &size) == CAIRO_INT_STATUS_SUCCESS)
  1073.         has_prep = TRUE;
  1074.  
  1075.     font->num_tables = 0;
  1076.     pos = 0;
  1077.     if (font->is_pdf && font->scaled_font_subset->is_latin)
  1078.         pos++;
  1079.     if (has_cvt)
  1080.         pos++;
  1081.     if (has_fpgm)
  1082.         pos++;
  1083.     cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
  1084.  
  1085.     pos = 0;
  1086.     if (font->is_pdf && font->scaled_font_subset->is_latin)
  1087.         cairo_truetype_font_add_truetype_table (font, TT_TAG_cmap, cairo_truetype_font_write_cmap_table, pos++);
  1088.     if (has_cvt)
  1089.         cairo_truetype_font_add_truetype_table (font, TT_TAG_cvt, cairo_truetype_font_write_generic_table, pos++);
  1090.     if (has_fpgm)
  1091.         cairo_truetype_font_add_truetype_table (font, TT_TAG_fpgm, cairo_truetype_font_write_generic_table, pos++);
  1092.     pos++;
  1093.     cairo_truetype_font_add_truetype_table (font, TT_TAG_head, cairo_truetype_font_write_head_table, pos++);
  1094.     cairo_truetype_font_add_truetype_table (font, TT_TAG_hhea, cairo_truetype_font_write_hhea_table, pos++);
  1095.     cairo_truetype_font_add_truetype_table (font, TT_TAG_hmtx, cairo_truetype_font_write_hmtx_table, pos++);
  1096.     cairo_truetype_font_add_truetype_table (font, TT_TAG_loca, cairo_truetype_font_write_loca_table, pos++);
  1097.     cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
  1098.     if (has_prep)
  1099.         cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
  1100. }
  1101.  
  1102. static cairo_status_t
  1103. cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
  1104.                                       cairo_scaled_font_subset_t *font_subset,
  1105.                                       cairo_bool_t                is_pdf)
  1106. {
  1107.     cairo_truetype_font_t *font = NULL;
  1108.     cairo_status_t status;
  1109.     const char *data = NULL; /* squelch bogus compiler warning */
  1110.     unsigned long length = 0; /* squelch bogus compiler warning */
  1111.     unsigned long offsets_length;
  1112.     unsigned int i;
  1113.     const unsigned long *string_offsets = NULL;
  1114.     unsigned long num_strings = 0;
  1115.  
  1116.     status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
  1117.     if (unlikely (status))
  1118.         return status;
  1119.  
  1120.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) {
  1121.         unsigned short parent_glyph = font->scaled_font_subset->glyphs[i];
  1122.         status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph);
  1123.         if (unlikely (status))
  1124.             goto fail1;
  1125.     }
  1126.  
  1127.     cairo_truetype_font_create_truetype_table_list (font);
  1128.     status = cairo_truetype_font_generate (font, &data, &length,
  1129.                                            &string_offsets, &num_strings);
  1130.     if (unlikely (status))
  1131.         goto fail1;
  1132.  
  1133.     truetype_subset->ps_name = strdup (font->base.ps_name);
  1134.     if (unlikely (truetype_subset->ps_name == NULL)) {
  1135.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1136.         goto fail1;
  1137.     }
  1138.  
  1139.     if (font->base.font_name != NULL) {
  1140.         truetype_subset->family_name_utf8 = strdup (font->base.font_name);
  1141.         if (unlikely (truetype_subset->family_name_utf8 == NULL)) {
  1142.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1143.             goto fail2;
  1144.         }
  1145.     } else {
  1146.         truetype_subset->family_name_utf8 = NULL;
  1147.     }
  1148.  
  1149.     /* The widths array returned must contain only widths for the
  1150.      * glyphs in font_subset. Any subglyphs appended after
  1151.      * font_subset->num_glyphs are omitted. */
  1152.     truetype_subset->widths = calloc (sizeof (double),
  1153.                                       font->scaled_font_subset->num_glyphs);
  1154.     if (unlikely (truetype_subset->widths == NULL)) {
  1155.         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1156.         goto fail3;
  1157.     }
  1158.     for (i = 0; i < font->scaled_font_subset->num_glyphs; i++)
  1159.         truetype_subset->widths[i] = (double)font->base.widths[i]/font->base.units_per_em;
  1160.  
  1161.     truetype_subset->x_min = (double)font->base.x_min/font->base.units_per_em;
  1162.     truetype_subset->y_min = (double)font->base.y_min/font->base.units_per_em;
  1163.     truetype_subset->x_max = (double)font->base.x_max/font->base.units_per_em;
  1164.     truetype_subset->y_max = (double)font->base.y_max/font->base.units_per_em;
  1165.     truetype_subset->ascent = (double)font->base.ascent/font->base.units_per_em;
  1166.     truetype_subset->descent = (double)font->base.descent/font->base.units_per_em;
  1167.  
  1168.     if (length) {
  1169.         truetype_subset->data = malloc (length);
  1170.         if (unlikely (truetype_subset->data == NULL)) {
  1171.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1172.             goto fail4;
  1173.         }
  1174.  
  1175.         memcpy (truetype_subset->data, data, length);
  1176.     } else
  1177.         truetype_subset->data = NULL;
  1178.     truetype_subset->data_length = length;
  1179.  
  1180.     if (num_strings) {
  1181.         offsets_length = num_strings * sizeof (unsigned long);
  1182.         truetype_subset->string_offsets = malloc (offsets_length);
  1183.         if (unlikely (truetype_subset->string_offsets == NULL)) {
  1184.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1185.             goto fail5;
  1186.         }
  1187.  
  1188.         memcpy (truetype_subset->string_offsets, string_offsets, offsets_length);
  1189.         truetype_subset->num_string_offsets = num_strings;
  1190.     } else {
  1191.         truetype_subset->string_offsets = NULL;
  1192.         truetype_subset->num_string_offsets = 0;
  1193.     }
  1194.  
  1195.     cairo_truetype_font_destroy (font);
  1196.  
  1197.     return CAIRO_STATUS_SUCCESS;
  1198.  
  1199.  fail5:
  1200.     free (truetype_subset->data);
  1201.  fail4:
  1202.     free (truetype_subset->widths);
  1203.  fail3:
  1204.     free (truetype_subset->family_name_utf8);
  1205.  fail2:
  1206.     free (truetype_subset->ps_name);
  1207.  fail1:
  1208.     cairo_truetype_font_destroy (font);
  1209.  
  1210.     return status;
  1211. }
  1212.  
  1213. cairo_status_t
  1214. _cairo_truetype_subset_init_ps (cairo_truetype_subset_t    *truetype_subset,
  1215.                                 cairo_scaled_font_subset_t      *font_subset)
  1216. {
  1217.     return cairo_truetype_subset_init_internal (truetype_subset, font_subset, FALSE);
  1218. }
  1219.  
  1220. cairo_status_t
  1221. _cairo_truetype_subset_init_pdf (cairo_truetype_subset_t    *truetype_subset,
  1222.                                 cairo_scaled_font_subset_t      *font_subset)
  1223. {
  1224.     return cairo_truetype_subset_init_internal (truetype_subset, font_subset, TRUE);
  1225. }
  1226.  
  1227. void
  1228. _cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
  1229. {
  1230.     free (subset->ps_name);
  1231.     free (subset->family_name_utf8);
  1232.     free (subset->widths);
  1233.     free (subset->data);
  1234.     free (subset->string_offsets);
  1235. }
  1236.  
  1237. static cairo_int_status_t
  1238. _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font,
  1239.                               unsigned long        table_offset,
  1240.                               unsigned long        index,
  1241.                               uint32_t            *ucs4)
  1242. {
  1243.     cairo_status_t status;
  1244.     const cairo_scaled_font_backend_t *backend;
  1245.     tt_segment_map_t *map;
  1246.     char buf[4];
  1247.     unsigned int num_segments, i;
  1248.     unsigned long size;
  1249.     uint16_t *start_code;
  1250.     uint16_t *end_code;
  1251.     uint16_t *delta;
  1252.     uint16_t *range_offset;
  1253.     uint16_t  c;
  1254.  
  1255.     backend = scaled_font->backend;
  1256.     size = 4;
  1257.     status = backend->load_truetype_table (scaled_font,
  1258.                                            TT_TAG_cmap, table_offset,
  1259.                                            (unsigned char *) &buf,
  1260.                                            &size);
  1261.     if (unlikely (status))
  1262.         return status;
  1263.  
  1264.     /* All table formats have the same first two words */
  1265.     map = (tt_segment_map_t *) buf;
  1266.     if (be16_to_cpu (map->format) != 4)
  1267.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1268.  
  1269.     size = be16_to_cpu (map->length);
  1270.     map = malloc (size);
  1271.     if (unlikely (map == NULL))
  1272.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1273.  
  1274.     status = backend->load_truetype_table (scaled_font,
  1275.                                            TT_TAG_cmap, table_offset,
  1276.                                            (unsigned char *) map,
  1277.                                            &size);
  1278.     if (unlikely (status))
  1279.         goto fail;
  1280.  
  1281.     num_segments = be16_to_cpu (map->segCountX2)/2;
  1282.  
  1283.     /* A Format 4 cmap contains 8 uint16_t numbers and 4 arrays of
  1284.      * uint16_t each num_segments long. */
  1285.     if (size < (8 + 4*num_segments)*sizeof(uint16_t))
  1286.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1287.  
  1288.     end_code = map->endCount;
  1289.     start_code = &(end_code[num_segments + 1]);
  1290.     delta = &(start_code[num_segments]);
  1291.     range_offset = &(delta[num_segments]);
  1292.  
  1293.     /* search for glyph in segments with rangeOffset=0 */
  1294.     for (i = 0; i < num_segments; i++) {
  1295.         c = index - be16_to_cpu (delta[i]);
  1296.         if (range_offset[i] == 0 &&
  1297.             c >= be16_to_cpu (start_code[i]) &&
  1298.             c <= be16_to_cpu (end_code[i]))
  1299.         {
  1300.             *ucs4 = c;
  1301.             goto found;
  1302.         }
  1303.     }
  1304.  
  1305.     /* search for glyph in segments with rangeOffset=1 */
  1306.     for (i = 0; i < num_segments; i++) {
  1307.         if (range_offset[i] != 0) {
  1308.             uint16_t *glyph_ids = &range_offset[i] + be16_to_cpu (range_offset[i])/2;
  1309.             int range_size = be16_to_cpu (end_code[i]) - be16_to_cpu (start_code[i]) + 1;
  1310.             uint16_t g_id_be = cpu_to_be16 (index);
  1311.             int j;
  1312.  
  1313.             if (range_size > 0) {
  1314.                 if ((char*)glyph_ids + 2*range_size > (char*)map + size)
  1315.                     return CAIRO_INT_STATUS_UNSUPPORTED;
  1316.  
  1317.                 for (j = 0; j < range_size; j++) {
  1318.                     if (glyph_ids[j] == g_id_be) {
  1319.                         *ucs4 = be16_to_cpu (start_code[i]) + j;
  1320.                         goto found;
  1321.                     }
  1322.                 }
  1323.             }
  1324.         }
  1325.     }
  1326.  
  1327.     /* glyph not found */
  1328.     *ucs4 = -1;
  1329.  
  1330. found:
  1331.     status = CAIRO_STATUS_SUCCESS;
  1332.  
  1333. fail:
  1334.     free (map);
  1335.  
  1336.     return status;
  1337. }
  1338.  
  1339. cairo_int_status_t
  1340. _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
  1341.                                unsigned long        index,
  1342.                                uint32_t            *ucs4)
  1343. {
  1344.     cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
  1345.     const cairo_scaled_font_backend_t *backend;
  1346.     tt_cmap_t *cmap;
  1347.     char buf[4];
  1348.     int num_tables, i;
  1349.     unsigned long size;
  1350.  
  1351.     backend = scaled_font->backend;
  1352.     if (!backend->load_truetype_table)
  1353.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1354.  
  1355.     size = 4;
  1356.     status = backend->load_truetype_table (scaled_font,
  1357.                                            TT_TAG_cmap, 0,
  1358.                                            (unsigned char *) &buf,
  1359.                                            &size);
  1360.     if (unlikely (status))
  1361.         return status;
  1362.  
  1363.     cmap = (tt_cmap_t *) buf;
  1364.     num_tables = be16_to_cpu (cmap->num_tables);
  1365.     size = 4 + num_tables*sizeof(tt_cmap_index_t);
  1366.     cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4);
  1367.     if (unlikely (cmap == NULL))
  1368.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1369.  
  1370.     status = backend->load_truetype_table (scaled_font,
  1371.                                            TT_TAG_cmap, 0,
  1372.                                            (unsigned char *) cmap,
  1373.                                            &size);
  1374.     if (unlikely (status))
  1375.         goto cleanup;
  1376.  
  1377.     /* Find a table with Unicode mapping */
  1378.     for (i = 0; i < num_tables; i++) {
  1379.         if (be16_to_cpu (cmap->index[i].platform) == 3 &&
  1380.             be16_to_cpu (cmap->index[i].encoding) == 1) {
  1381.             status = _cairo_truetype_reverse_cmap (scaled_font,
  1382.                                                    be32_to_cpu (cmap->index[i].offset),
  1383.                                                    index,
  1384.                                                    ucs4);
  1385.             if (status != CAIRO_INT_STATUS_UNSUPPORTED)
  1386.                 break;
  1387.         }
  1388.     }
  1389.  
  1390. cleanup:
  1391.     free (cmap);
  1392.  
  1393.     return status;
  1394. }
  1395.  
  1396. static cairo_status_t
  1397. find_name (tt_name_t *name, int name_id, int platform, int encoding, int language, char **str_out)
  1398. {
  1399.     tt_name_record_t *record;
  1400.     int i, len;
  1401.     char *str;
  1402.     char *p;
  1403.     cairo_bool_t has_tag;
  1404.     cairo_status_t status;
  1405.  
  1406.     str = NULL;
  1407.     for (i = 0; i < be16_to_cpu (name->num_records); i++) {
  1408.         record = &(name->records[i]);
  1409.         if (be16_to_cpu (record->name) == name_id &&
  1410.             be16_to_cpu (record->platform) == platform &&
  1411.             be16_to_cpu (record->encoding) == encoding &&
  1412.             (language == -1 || be16_to_cpu (record->language) == language)) {
  1413.  
  1414.             str = malloc (be16_to_cpu (record->length) + 1);
  1415.             if (str == NULL)
  1416.                 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1417.  
  1418.             len = be16_to_cpu (record->length);
  1419.             memcpy (str,
  1420.                     ((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
  1421.                     len);
  1422.             str[be16_to_cpu (record->length)] = 0;
  1423.             break;
  1424.         }
  1425.     }
  1426.     if (str == NULL) {
  1427.         *str_out = NULL;
  1428.         return CAIRO_STATUS_SUCCESS;
  1429.     }
  1430.  
  1431.     if (platform == 3) { /* Win platform, unicode encoding */
  1432.         /* convert to utf8 */
  1433.         int size = 0;
  1434.         char *utf8;
  1435.         uint16_t *u = (uint16_t *) str;
  1436.         int u_len = len/2;
  1437.  
  1438.         for (i = 0; i < u_len; i++)
  1439.             size += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), NULL);
  1440.  
  1441.         utf8 = malloc (size + 1);
  1442.         if (utf8 == NULL) {
  1443.             status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
  1444.             goto fail;
  1445.         }
  1446.         p = utf8;
  1447.         for (i = 0; i < u_len; i++)
  1448.             p += _cairo_ucs4_to_utf8 (be16_to_cpu(u[i]), p);
  1449.         *p = 0;
  1450.         free (str);
  1451.         str = utf8;
  1452.     } else if (platform == 1) { /* Mac platform, Mac Roman encoding */
  1453.         /* Replace characters above 127 with underscores. We could use
  1454.          * a lookup table to convert to unicode but since most fonts
  1455.          * include a unicode name this is just a rarely used fallback. */
  1456.         for (i = 0; i < len; i++) {
  1457.             if ((unsigned char)str[i] > 127)
  1458.                 str[i] = '_';
  1459.         }
  1460.     }
  1461.  
  1462.     /* If font name is prefixed with a PDF subset tag, strip it off. */
  1463.     p = str;
  1464.     len = strlen (str);
  1465.     has_tag = FALSE;
  1466.     if (len > 7 && p[6] == '+') {
  1467.         has_tag = TRUE;
  1468.         for (i = 0; i < 6; i++) {
  1469.             if (p[i] < 'A' || p[i] > 'Z') {
  1470.                 has_tag = FALSE;
  1471.                 break;
  1472.             }
  1473.         }
  1474.     }
  1475.     if (has_tag) {
  1476.         p = malloc (len - 6);
  1477.         if (unlikely (p == NULL)) {
  1478.             status =_cairo_error (CAIRO_STATUS_NO_MEMORY);
  1479.             goto fail;
  1480.         }
  1481.         memcpy (p, str + 7, len - 7);
  1482.         p[len-7] = 0;
  1483.         free (str);
  1484.         str = p;
  1485.     }
  1486.  
  1487.     *str_out = str;
  1488.  
  1489.     return CAIRO_STATUS_SUCCESS;
  1490.  
  1491.   fail:
  1492.     free (str);
  1493.  
  1494.     return status;
  1495. }
  1496.  
  1497. cairo_int_status_t
  1498. _cairo_truetype_read_font_name (cairo_scaled_font_t      *scaled_font,
  1499.                                 char                    **ps_name_out,
  1500.                                 char                    **font_name_out)
  1501. {
  1502.     cairo_status_t status;
  1503.     const cairo_scaled_font_backend_t *backend;
  1504.     tt_name_t *name;
  1505.     unsigned long size;
  1506.     char *ps_name = NULL;
  1507.     char *family_name = NULL;
  1508.  
  1509.     backend = scaled_font->backend;
  1510.     if (!backend->load_truetype_table)
  1511.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1512.  
  1513.     size = 0;
  1514.     status = backend->load_truetype_table (scaled_font,
  1515.                                            TT_TAG_name, 0,
  1516.                                            NULL,
  1517.                                            &size);
  1518.     if (status)
  1519.         return status;
  1520.  
  1521.     name = malloc (size);
  1522.     if (name == NULL)
  1523.         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1524.  
  1525.     status = backend->load_truetype_table (scaled_font,
  1526.                                            TT_TAG_name, 0,
  1527.                                            (unsigned char *) name,
  1528.                                            &size);
  1529.     if (status)
  1530.         goto fail;
  1531.  
  1532.     /* Find PS Name (name_id = 6). OT spec says PS name must be one of
  1533.      * the following two encodings */
  1534.     status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
  1535.     if (unlikely(status))
  1536.         goto fail;
  1537.  
  1538.     if (!ps_name) {
  1539.         status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
  1540.         if (unlikely(status))
  1541.             goto fail;
  1542.     }
  1543.  
  1544.     /* Find Family name (name_id = 1) */
  1545.     status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
  1546.     if (unlikely(status))
  1547.         goto fail;
  1548.  
  1549.     if (!family_name) {
  1550.         status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
  1551.         if (unlikely(status))
  1552.             goto fail;
  1553.     }
  1554.  
  1555.     if (!family_name) {
  1556.         status = find_name (name, 1, 1, 0, 0, &family_name); /* mac, roman, english */
  1557.         if (unlikely(status))
  1558.             goto fail;
  1559.     }
  1560.  
  1561.     if (!family_name) {
  1562.         status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
  1563.         if (unlikely(status))
  1564.             goto fail;
  1565.     }
  1566.  
  1567.     free (name);
  1568.  
  1569.     /* Ensure PS name is a valid PDF/PS name object. In PDF names are
  1570.      * treated as UTF8 and non ASCII bytes, ' ', and '#' are encoded
  1571.      * as '#' followed by 2 hex digits that encode the byte. By also
  1572.      * encoding the characters in the reserved string we ensure the
  1573.      * name is also PS compatible. */
  1574.     if (ps_name) {
  1575.         static const char *reserved = "()<>[]{}/%#\\";
  1576.         char buf[128]; /* max name length is 127 bytes */
  1577.         char *src = ps_name;
  1578.         char *dst = buf;
  1579.  
  1580.         while (*src && dst < buf + 127) {
  1581.             unsigned char c = *src;
  1582.             if (c < 0x21 || c > 0x7e || strchr (reserved, c)) {
  1583.                 if (dst + 4 > buf + 127)
  1584.                     break;
  1585.  
  1586.                 snprintf (dst, 4, "#%02X", c);
  1587.                 src++;
  1588.                 dst += 3;
  1589.             } else {
  1590.                 *dst++ = *src++;
  1591.             }
  1592.         }
  1593.         *dst = 0;
  1594.         free (ps_name);
  1595.         ps_name = strdup (buf);
  1596.         if (ps_name == NULL) {
  1597.             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
  1598.             goto fail;
  1599.         }
  1600.     }
  1601.  
  1602.     *ps_name_out = ps_name;
  1603.     *font_name_out = family_name;
  1604.  
  1605.     return CAIRO_STATUS_SUCCESS;
  1606.  
  1607. fail:
  1608.     free (name);
  1609.     free (ps_name);
  1610.     free (family_name);
  1611.     *ps_name_out = NULL;
  1612.     *font_name_out = NULL;
  1613.  
  1614.     return status;
  1615. }
  1616.  
  1617. cairo_int_status_t
  1618. _cairo_truetype_get_style (cairo_scaled_font_t           *scaled_font,
  1619.                            int                           *weight,
  1620.                            cairo_bool_t                  *bold,
  1621.                            cairo_bool_t                  *italic)
  1622. {
  1623.     cairo_status_t status;
  1624.     const cairo_scaled_font_backend_t *backend;
  1625.     tt_os2_t os2;
  1626.     unsigned long size;
  1627.     uint16_t selection;
  1628.  
  1629.     backend = scaled_font->backend;
  1630.     if (!backend->load_truetype_table)
  1631.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1632.  
  1633.     size = 0;
  1634.     status = backend->load_truetype_table (scaled_font,
  1635.                                            TT_TAG_OS2, 0,
  1636.                                            NULL,
  1637.                                            &size);
  1638.     if (status)
  1639.         return status;
  1640.  
  1641.     if (size < sizeof(os2))
  1642.         return CAIRO_INT_STATUS_UNSUPPORTED;
  1643.  
  1644.     size = sizeof (os2);
  1645.     status = backend->load_truetype_table (scaled_font,
  1646.                                            TT_TAG_OS2, 0,
  1647.                                            (unsigned char *) &os2,
  1648.                                            &size);
  1649.     if (status)
  1650.         return status;
  1651.  
  1652.     *weight = be16_to_cpu (os2.usWeightClass);
  1653.     selection = be16_to_cpu (os2.fsSelection);
  1654.     *bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE;
  1655.     *italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE;
  1656.  
  1657.     return CAIRO_STATUS_SUCCESS;
  1658. }
  1659.  
  1660. #endif /* CAIRO_HAS_FONT_SUBSET */
  1661.