~ubuntu-branches/ubuntu/raring/cairo/raring

« back to all changes in this revision

Viewing changes to src/cairo-cff-subset.c

  • Committer: Package Import Robot
  • Author(s): Stéphane Graber
  • Date: 2012-09-28 15:20:19 UTC
  • Revision ID: package-import@ubuntu.com-20120928152019-cobqis5072pxxfe4
Tags: 1.12.2-1ubuntu2
* Cherry-pick fixes from upstream (LP: #1030357)
  Thanks to Edward Donovan for the patch.
  - cff subsetting: widths can be floating point
  - cff: initialise variable to prevent valgrind warning
  - cff: use correct size for buffer
  - cff: convert '.' to locale specific decimal point before using sscanf
  - cff-subsetting: Ignore charset for non cid fonts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
1
2
/* cairo - a vector graphics library with display and print output
2
3
 *
3
4
 * Copyright © 2006 Adrian Johnson
51
52
#include "cairo-scaled-font-subsets-private.h"
52
53
#include "cairo-truetype-subset-private.h"
53
54
#include <string.h>
 
55
#include <locale.h>
54
56
 
55
57
/* CFF Dict Operators. If the high byte is 0 the command is encoded
56
58
 * with a single byte. */
151
153
    int                  units_per_em;
152
154
    int                  global_sub_bias;
153
155
    int                  local_sub_bias;
154
 
    int                  default_width;
155
 
    int                  nominal_width;
 
156
    double               default_width;
 
157
    double               nominal_width;
156
158
 
157
159
    /* CID Font Data */
158
160
    int                 *fdselect;
161
163
    cairo_hash_table_t **fd_private_dict;
162
164
    cairo_array_t       *fd_local_sub_index;
163
165
    int                 *fd_local_sub_bias;
164
 
    int                 *fd_default_width;
165
 
    int                 *fd_nominal_width;
 
166
    double              *fd_default_width;
 
167
    double              *fd_nominal_width;
166
168
 
167
169
    /* Subsetted Font Data */
168
170
    char                *subset_font_name;
293
295
static unsigned char *
294
296
decode_real (unsigned char *p, double *real)
295
297
{
 
298
    struct lconv *locale_data;
 
299
    const char *decimal_point;
 
300
    int decimal_point_len;
296
301
    int n;
297
302
    char buffer[100];
 
303
    char buffer2[200];
 
304
    char *q;
298
305
    char *buf = buffer;
299
 
    char *buf_end = buffer + sizeof (buf);
 
306
    char *buf_end = buffer + sizeof (buffer);
 
307
 
 
308
    locale_data = localeconv ();
 
309
    decimal_point = locale_data->decimal_point;
 
310
    decimal_point_len = strlen (decimal_point);
 
311
 
 
312
    assert (decimal_point_len != 0);
 
313
    assert (sizeof(buffer) + decimal_point_len < sizeof(buffer2));
300
314
 
301
315
    p++;
302
316
    while (buf + 2 < buf_end) {
312
326
    };
313
327
    *buf = 0;
314
328
 
315
 
    if (sscanf(buffer, "%lf", real) != 1)
 
329
    buf = buffer;
 
330
    if (strchr (buffer, '.')) {
 
331
         q = strchr (buffer, '.');
 
332
         strncpy (buffer2, buffer, q - buffer);
 
333
         buf = buffer2 + (q - buffer);
 
334
         strncpy (buf, decimal_point, decimal_point_len);
 
335
         buf += decimal_point_len;
 
336
         strcpy (buf, q + 1);
 
337
         buf = buffer2;
 
338
    }
 
339
 
 
340
    if (sscanf(buf, "%lf", real) != 1)
316
341
        *real = 0.0;
317
342
 
318
343
    return p;
886
911
                                  cairo_array_t      *local_sub_index,
887
912
                                  int                *local_sub_bias,
888
913
                                  cairo_bool_t      **local_subs_used,
889
 
                                  int                *default_width,
890
 
                                  int                *nominal_width,
 
914
                                  double             *default_width,
 
915
                                  double             *nominal_width,
891
916
                                  unsigned char      *ptr,
892
917
                                  int                 size)
893
918
{
922
947
    *default_width = 0;
923
948
    operand = cff_dict_get_operands (private_dict, DEFAULTWIDTH_OP, &i);
924
949
    if (operand)
925
 
        decode_integer (operand, default_width);
 
950
        decode_number (operand, default_width);
926
951
 
927
952
    *nominal_width = 0;
928
953
    operand = cff_dict_get_operands (private_dict, NOMINALWIDTH_OP, &i);
929
954
    if (operand)
930
 
        decode_integer (operand, nominal_width);
 
955
         decode_number (operand, nominal_width);
931
956
 
932
957
    num_subs = _cairo_array_num_elements (local_sub_index);
933
958
    *local_subs_used = calloc (num_subs, sizeof (cairo_bool_t));
1178
1203
        goto fail;
1179
1204
    font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index);
1180
1205
 
1181
 
    operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
1182
 
    if (font->is_cid && !operand)
1183
 
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1206
    if (font->is_cid) {
 
1207
         operand = cff_dict_get_operands (font->top_dict, CHARSET_OP, &size);
 
1208
         if (!operand)
 
1209
              return CAIRO_INT_STATUS_UNSUPPORTED;
1184
1210
 
1185
 
    decode_integer (operand, &offset);
1186
 
    font->charset = font->data + offset;
1187
 
    if (font->charset >= font->data_end)
1188
 
        return CAIRO_INT_STATUS_UNSUPPORTED;
 
1211
         decode_integer (operand, &offset);
 
1212
         font->charset = font->data + offset;
 
1213
         if (font->charset >= font->data_end)
 
1214
              return CAIRO_INT_STATUS_UNSUPPORTED;
 
1215
    }
1189
1216
 
1190
1217
    if (!font->is_opentype)
1191
1218
        cairo_cff_font_read_font_metrics (font, font->top_dict);
1442
1469
        *integer = -(p[0] - 251) * 256 - p[1] - 108;
1443
1470
        p += 2;
1444
1471
    } else { /* *p == 255 */
1445
 
    /* This actually a 16.16 fixed-point number however we are not interested in
1446
 
     * the value of fixed-point numbers. */
1447
 
        *integer = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
 
1472
         /* 16.16 fixed-point number. The fraction is ignored. */
 
1473
         *integer = (int16_t)((p[1] << 8) | p[2]);
1448
1474
        p += 5;
1449
1475
    }
1450
1476
    return p;
3167
3193
    cff_index_init (&font->strings_subset_index);
3168
3194
    font->global_subs_used = NULL;
3169
3195
    font->local_subs_used = NULL;
 
3196
    font->subset_subroutines = FALSE;
3170
3197
    font->fdselect = NULL;
3171
3198
    font->fd_dict = NULL;
3172
3199
    font->fd_private_dict = NULL;