Subversion Repositories Kolibri OS

Rev

Rev 1897 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1897 Rev 3959
Line 40... Line 40...
40
 * http://www.microsoft.com/typography/specs/default.htm
40
 * http://www.microsoft.com/typography/specs/default.htm
41
 */
41
 */
Line 42... Line 42...
42
 
42
 
43
#define _BSD_SOURCE /* for snprintf(), strdup() */
43
#define _BSD_SOURCE /* for snprintf(), strdup() */
-
 
44
#include "cairoint.h"
-
 
45
 
44
#include "cairoint.h"
46
#include "cairo-array-private.h"
Line 45... Line 47...
45
#include "cairo-error-private.h"
47
#include "cairo-error-private.h"
Line 46... Line 48...
46
 
48
 
Line 90... Line 92...
90
    cairo_array_t string_offsets;
92
    cairo_array_t string_offsets;
91
    unsigned long last_offset;
93
    unsigned long last_offset;
92
    unsigned long last_boundary;
94
    unsigned long last_boundary;
93
    int *parent_to_subset;
95
    int *parent_to_subset;
94
    cairo_status_t status;
96
    cairo_status_t status;
95
 
-
 
-
 
97
    cairo_bool_t is_pdf;
96
};
98
};
Line 97... Line 99...
97
 
99
 
98
/*
100
/*
99
 * Test that the structs we define for TrueType tables have the
101
 * Test that the structs we define for TrueType tables have the
Line 120... Line 122...
120
 
122
 
121
static cairo_status_t
123
static cairo_status_t
122
_cairo_truetype_font_set_error (cairo_truetype_font_t *font,
124
_cairo_truetype_font_set_error (cairo_truetype_font_t *font,
123
			        cairo_status_t status)
125
			        cairo_status_t status)
-
 
126
{
124
{
127
    if (status == CAIRO_STATUS_SUCCESS ||
125
    if (status == CAIRO_STATUS_SUCCESS || status == CAIRO_INT_STATUS_UNSUPPORTED)
128
	status == (int)CAIRO_INT_STATUS_UNSUPPORTED)
Line 126... Line 129...
126
	return status;
129
	return status;
Line 127... Line 130...
127
 
130
 
128
    _cairo_status_set_error (&font->status, status);
131
    _cairo_status_set_error (&font->status, status);
Line 129... Line 132...
129
 
132
 
130
    return _cairo_error (status);
133
    return _cairo_error (status);
-
 
134
}
131
}
135
 
132
 
136
static cairo_status_t
133
static cairo_status_t
137
_cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
134
_cairo_truetype_font_create (cairo_scaled_font_subset_t  *scaled_font_subset,
138
			     cairo_bool_t is_pdf,
135
			     cairo_truetype_font_t      **font_return)
139
			     cairo_truetype_font_t      **font_return)
Line 153... Line 157...
153
     *
157
     *
154
     *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
158
     *  if (cairo_font_options_get_vertical_layout (scaled_font_subset->scaled_font))
155
     *   return CAIRO_INT_STATUS_UNSUPPORTED;
159
     *   return CAIRO_INT_STATUS_UNSUPPORTED;
156
     */
160
     */
Line -... Line 161...
-
 
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;
157
 
165
 
158
    size = sizeof (tt_head_t);
166
    size = sizeof (tt_head_t);
159
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
167
    status = backend->load_truetype_table (scaled_font_subset->scaled_font,
160
                                          TT_TAG_head, 0,
168
                                          TT_TAG_head, 0,
161
					  (unsigned char *) &head,
169
					  (unsigned char *) &head,
Line 204... Line 212...
204
    if (unlikely (font->parent_to_subset == NULL)) {
212
    if (unlikely (font->parent_to_subset == NULL)) {
205
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
213
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
206
	goto fail2;
214
	goto fail2;
207
    }
215
    }
Line -... Line 216...
-
 
216
 
208
 
217
    font->is_pdf = is_pdf;
209
    font->base.num_glyphs = 0;
218
    font->base.num_glyphs = 0;
210
    font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
219
    font->base.x_min = (int16_t) be16_to_cpu (head.x_min);
211
    font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
220
    font->base.y_min = (int16_t) be16_to_cpu (head.y_min);
212
    font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
221
    font->base.x_max = (int16_t) be16_to_cpu (head.x_max);
Line 260... Line 269...
260
    free (font->base.widths);
269
    free (font->base.widths);
261
 fail4:
270
 fail4:
262
    free (font->base.ps_name);
271
    free (font->base.ps_name);
263
 fail3:
272
 fail3:
264
    free (font->parent_to_subset);
273
    free (font->parent_to_subset);
265
    if (font->base.font_name)
-
 
266
	free (font->base.font_name);
274
    free (font->base.font_name);
267
 fail2:
275
 fail2:
268
    free (font->glyphs);
276
    free (font->glyphs);
269
 fail1:
277
 fail1:
270
    _cairo_array_fini (&font->output);
278
    _cairo_array_fini (&font->output);
Line 277... Line 285...
277
cairo_truetype_font_destroy (cairo_truetype_font_t *font)
285
cairo_truetype_font_destroy (cairo_truetype_font_t *font)
278
{
286
{
279
    _cairo_array_fini (&font->string_offsets);
287
    _cairo_array_fini (&font->string_offsets);
280
    free (font->base.widths);
288
    free (font->base.widths);
281
    free (font->base.ps_name);
289
    free (font->base.ps_name);
282
    if (font->base.font_name)
-
 
283
	free (font->base.font_name);
290
    free (font->base.font_name);
284
    free (font->parent_to_subset);
291
    free (font->parent_to_subset);
285
    free (font->glyphs);
292
    free (font->glyphs);
286
    _cairo_array_fini (&font->output);
293
    _cairo_array_fini (&font->output);
287
    free (font);
294
    free (font);
Line 391... Line 398...
391
    font->last_boundary = boundary;
398
    font->last_boundary = boundary;
Line 392... Line 399...
392
 
399
 
393
    return CAIRO_STATUS_SUCCESS;
400
    return CAIRO_STATUS_SUCCESS;
Line -... Line 401...
-
 
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 },
394
}
423
};
395
 
424
 
396
static cairo_status_t
425
static cairo_status_t
397
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
426
cairo_truetype_font_write_cmap_table (cairo_truetype_font_t *font,
-
 
427
				      unsigned long          tag)
398
				      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++;
Line 399... Line 445...
399
{
445
 
400
    unsigned int i;
446
    entry_selector--;
Line 401... Line 447...
401
 
447
 
402
    cairo_truetype_font_write_be16 (font, 0);  /* Table version */
448
    cairo_truetype_font_write_be16 (font, 0);  /* Table version */
403
    cairo_truetype_font_write_be16 (font, 2);  /* Num tables */
449
    cairo_truetype_font_write_be16 (font, 1);  /* Num tables */
Line 404... Line -...
404
 
-
 
405
    cairo_truetype_font_write_be16 (font, 3);  /* Platform */
-
 
406
    cairo_truetype_font_write_be16 (font, 0);  /* Encoding */
-
 
407
    cairo_truetype_font_write_be32 (font, 20); /* Offset to start of table */
-
 
408
 
450
 
Line 409... Line 451...
409
    cairo_truetype_font_write_be16 (font, 1);  /* Platform */
451
    cairo_truetype_font_write_be16 (font, 3);  /* Platform */
410
    cairo_truetype_font_write_be16 (font, 0);  /* Encoding */
452
    cairo_truetype_font_write_be16 (font, 1);  /* Encoding */
411
    cairo_truetype_font_write_be32 (font, 52); /* Offset to start of table */
453
    cairo_truetype_font_write_be32 (font, 12); /* Offset to start of table */
412
 
454
 
413
    /* Output a format 4 encoding table. */
455
    /* Output a format 4 encoding table for the winansi encoding */
414
 
456
 
415
    cairo_truetype_font_write_be16 (font, 4);  /* Format */
457
    cairo_truetype_font_write_be16 (font, 4);  /* Format */
-
 
458
    cairo_truetype_font_write_be16 (font, length); /* Length */
416
    cairo_truetype_font_write_be16 (font, 32); /* Length */
459
    cairo_truetype_font_write_be16 (font, 0);  /* Version */
417
    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 */
418
    cairo_truetype_font_write_be16 (font, 4);  /* 2*segcount */
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++)
419
    cairo_truetype_font_write_be16 (font, 4);  /* searchrange */
465
	cairo_truetype_font_write_be16 (font, winansi_unicode_ranges[i].end); /* end count[] */
420
    cairo_truetype_font_write_be16 (font, 1);  /* entry selector */
466
    cairo_truetype_font_write_be16 (font, 0xffff);  /* end count[] */
-
 
467
 
-
 
468
    cairo_truetype_font_write_be16 (font, 0);       /* reserved */
421
    cairo_truetype_font_write_be16 (font, 0);  /* rangeshift */
469
 
422
    cairo_truetype_font_write_be16 (font, 0xf000 + font->base.num_glyphs - 1); /* end count[0] */
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
 
423
    cairo_truetype_font_write_be16 (font, 0xffff);  /* end count[1] */
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[] */
424
    cairo_truetype_font_write_be16 (font, 0);       /* reserved */
477
 
425
    cairo_truetype_font_write_be16 (font, 0xf000);  /* startCode[0] */
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[] */
426
    cairo_truetype_font_write_be16 (font, 0xffff);  /* startCode[1] */
481
	range_offset += (winansi_unicode_ranges[i].end - winansi_unicode_ranges[i].start + 1)*2 - 2;
-
 
482
    }
427
    cairo_truetype_font_write_be16 (font, 0x1000);  /* delta[0] */
483
    cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[] */
428
    cairo_truetype_font_write_be16 (font, 1);       /* delta[1] */
484
 
429
    cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[0] */
485
    for (i = 0; i < num_ranges; i++) {
430
    cairo_truetype_font_write_be16 (font, 0);       /* rangeOffset[1] */
486
	for (j = winansi_unicode_ranges[i].start; j < winansi_unicode_ranges[i].end + 1; j++) {
431
 
-
 
432
    /* Output a format 6 encoding table. */
-
 
433
 
487
	    int ch = _cairo_unicode_to_winansi (j);
434
    cairo_truetype_font_write_be16 (font, 6);
488
	    int glyph;
-
 
489
 
-
 
490
	    if (ch > 0)
Line 435... Line 491...
435
    cairo_truetype_font_write_be16 (font, 10 + 2 * font->base.num_glyphs);
491
		glyph = font->scaled_font_subset->latin_to_subset_glyph_index[ch];
436
    cairo_truetype_font_write_be16 (font, 0);
492
	    else
Line 437... Line 493...
437
    cairo_truetype_font_write_be16 (font, 0); /* First character */
493
		glyph = 0;
Line 983... Line 1039...
983
 * in which the callback functions will be called.
1039
 * in which the callback functions will be called.
984
 *
1040
 *
985
 * The tables in the table directory must be listed in alphabetical
1041
 * The tables in the table directory must be listed in alphabetical
986
 * order.  The "cvt", "fpgm", and "prep" are optional tables. They
1042
 * order.  The "cvt", "fpgm", and "prep" are optional tables. They
987
 * will only be embedded in the subset if they exist in the source
1043
 * will only be embedded in the subset if they exist in the source
988
 * font. The pos parameter of cairo_truetype_font_add_truetype_table()
1044
 * font. "cmap" is only embedded for latin fonts. The pos parameter of
-
 
1045
 * cairo_truetype_font_add_truetype_table() specifies the position of
989
 * specifies the position of the table in the table directory.
1046
 * the table in the table directory.
990
 */
1047
 */
991
static void
1048
static void
992
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
1049
cairo_truetype_font_create_truetype_table_list (cairo_truetype_font_t *font)
993
{
1050
{
994
    cairo_bool_t has_cvt = FALSE;
1051
    cairo_bool_t has_cvt = FALSE;
Line 998... Line 1055...
998
    int pos;
1055
    int pos;
Line 999... Line 1056...
999
 
1056
 
1000
    size = 0;
1057
    size = 0;
1001
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1058
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1002
                                      TT_TAG_cvt, 0, NULL,
1059
                                      TT_TAG_cvt, 0, NULL,
1003
                                      &size) == CAIRO_STATUS_SUCCESS)
1060
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
Line 1004... Line 1061...
1004
        has_cvt = TRUE;
1061
        has_cvt = TRUE;
1005
 
1062
 
1006
    size = 0;
1063
    size = 0;
1007
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1064
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1008
                                      TT_TAG_fpgm, 0, NULL,
1065
                                      TT_TAG_fpgm, 0, NULL,
Line 1009... Line 1066...
1009
                                      &size) == CAIRO_STATUS_SUCCESS)
1066
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
1010
        has_fpgm = TRUE;
1067
        has_fpgm = TRUE;
1011
 
1068
 
1012
    size = 0;
1069
    size = 0;
1013
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
1070
    if (font->backend->load_truetype_table (font->scaled_font_subset->scaled_font,
Line 1014... Line 1071...
1014
                                      TT_TAG_prep, 0, NULL,
1071
                                      TT_TAG_prep, 0, NULL,
1015
                                      &size) == CAIRO_STATUS_SUCCESS)
1072
                                      &size) == CAIRO_INT_STATUS_SUCCESS)
-
 
1073
        has_prep = TRUE;
-
 
1074
 
1016
        has_prep = TRUE;
1075
    font->num_tables = 0;
1017
 
1076
    pos = 0;
1018
    font->num_tables = 0;
1077
    if (font->is_pdf && font->scaled_font_subset->is_latin)
1019
    pos = 1;
1078
	pos++;
1020
    if (has_cvt)
1079
    if (has_cvt)
Line 1021... Line 1080...
1021
        pos++;
1080
        pos++;
-
 
1081
    if (has_fpgm)
1022
    if (has_fpgm)
1082
        pos++;
1023
        pos++;
1083
    cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
1024
    cairo_truetype_font_add_truetype_table (font, TT_TAG_glyf, cairo_truetype_font_write_glyf_table, pos);
1084
 
1025
 
1085
    pos = 0;
1026
    pos = 0;
1086
    if (font->is_pdf && font->scaled_font_subset->is_latin)
Line 1037... Line 1097...
1037
    cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
1097
    cairo_truetype_font_add_truetype_table (font, TT_TAG_maxp, cairo_truetype_font_write_maxp_table, pos++);
1038
    if (has_prep)
1098
    if (has_prep)
1039
        cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
1099
        cairo_truetype_font_add_truetype_table (font, TT_TAG_prep, cairo_truetype_font_write_generic_table, pos);
1040
}
1100
}
Line 1041... Line 1101...
1041
 
1101
 
1042
cairo_status_t
1102
static cairo_status_t
1043
_cairo_truetype_subset_init (cairo_truetype_subset_t    *truetype_subset,
1103
cairo_truetype_subset_init_internal (cairo_truetype_subset_t     *truetype_subset,
-
 
1104
				      cairo_scaled_font_subset_t *font_subset,
1044
			     cairo_scaled_font_subset_t	*font_subset)
1105
				      cairo_bool_t                is_pdf)
1045
{
1106
{
1046
    cairo_truetype_font_t *font = NULL;
1107
    cairo_truetype_font_t *font = NULL;
1047
    cairo_status_t status;
1108
    cairo_status_t status;
1048
    const char *data = NULL; /* squelch bogus compiler warning */
1109
    const char *data = NULL; /* squelch bogus compiler warning */
1049
    unsigned long length = 0; /* squelch bogus compiler warning */
1110
    unsigned long length = 0; /* squelch bogus compiler warning */
1050
    unsigned long offsets_length;
1111
    unsigned long offsets_length;
1051
    unsigned int i;
1112
    unsigned int i;
1052
    const unsigned long *string_offsets = NULL;
1113
    const unsigned long *string_offsets = NULL;
Line 1053... Line 1114...
1053
    unsigned long num_strings = 0;
1114
    unsigned long num_strings = 0;
1054
 
1115
 
1055
    status = _cairo_truetype_font_create (font_subset, &font);
1116
    status = _cairo_truetype_font_create (font_subset, is_pdf, &font);
Line 1056... Line 1117...
1056
    if (unlikely (status))
1117
    if (unlikely (status))
1057
	return status;
1118
	return status;
Line 1074... Line 1135...
1074
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1135
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1075
	goto fail1;
1136
	goto fail1;
1076
    }
1137
    }
Line 1077... Line 1138...
1077
 
1138
 
1078
    if (font->base.font_name != NULL) {
1139
    if (font->base.font_name != NULL) {
1079
	truetype_subset->font_name = strdup (font->base.font_name);
1140
	truetype_subset->family_name_utf8 = strdup (font->base.font_name);
1080
	if (unlikely (truetype_subset->font_name == NULL)) {
1141
	if (unlikely (truetype_subset->family_name_utf8 == NULL)) {
1081
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1142
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1082
	    goto fail2;
1143
	    goto fail2;
1083
	}
1144
	}
1084
    } else {
1145
    } else {
1085
	truetype_subset->font_name = NULL;
1146
	truetype_subset->family_name_utf8 = NULL;
Line 1086... Line 1147...
1086
    }
1147
    }
1087
 
1148
 
1088
    /* The widths array returned must contain only widths for the
1149
    /* The widths array returned must contain only widths for the
Line 1138... Line 1199...
1138
 fail5:
1199
 fail5:
1139
    free (truetype_subset->data);
1200
    free (truetype_subset->data);
1140
 fail4:
1201
 fail4:
1141
    free (truetype_subset->widths);
1202
    free (truetype_subset->widths);
1142
 fail3:
1203
 fail3:
1143
    if (truetype_subset->font_name)
-
 
1144
	free (truetype_subset->font_name);
1204
    free (truetype_subset->family_name_utf8);
1145
 fail2:
1205
 fail2:
1146
    free (truetype_subset->ps_name);
1206
    free (truetype_subset->ps_name);
1147
 fail1:
1207
 fail1:
1148
    cairo_truetype_font_destroy (font);
1208
    cairo_truetype_font_destroy (font);
Line 1149... Line 1209...
1149
 
1209
 
1150
    return status;
1210
    return status;
Line -... Line 1211...
-
 
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);
1151
}
1225
}
1152
 
1226
 
1153
void
1227
void
1154
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
1228
_cairo_truetype_subset_fini (cairo_truetype_subset_t *subset)
1155
{
-
 
1156
    free (subset->ps_name);
1229
{
1157
    if (subset->font_name)
1230
    free (subset->ps_name);
1158
	free (subset->font_name);
1231
    free (subset->family_name_utf8);
1159
    free (subset->widths);
1232
    free (subset->widths);
1160
    free (subset->data);
1233
    free (subset->data);
Line 1175... Line 1248...
1175
    unsigned long size;
1248
    unsigned long size;
1176
    uint16_t *start_code;
1249
    uint16_t *start_code;
1177
    uint16_t *end_code;
1250
    uint16_t *end_code;
1178
    uint16_t *delta;
1251
    uint16_t *delta;
1179
    uint16_t *range_offset;
1252
    uint16_t *range_offset;
1180
    uint16_t *glyph_array;
-
 
1181
    uint16_t  c;
1253
    uint16_t  c;
Line 1182... Line 1254...
1182
 
1254
 
1183
    backend = scaled_font->backend;
1255
    backend = scaled_font->backend;
1184
    size = 4;
1256
    size = 4;
Line 1215... Line 1287...
1215
 
1287
 
1216
    end_code = map->endCount;
1288
    end_code = map->endCount;
1217
    start_code = &(end_code[num_segments + 1]);
1289
    start_code = &(end_code[num_segments + 1]);
1218
    delta = &(start_code[num_segments]);
1290
    delta = &(start_code[num_segments]);
1219
    range_offset = &(delta[num_segments]);
-
 
Line 1220... Line 1291...
1220
    glyph_array = &(range_offset[num_segments]);
1291
    range_offset = &(delta[num_segments]);
1221
 
1292
 
1222
    /* search for glyph in segments with rangeOffset=0 */
1293
    /* search for glyph in segments with rangeOffset=0 */
1223
    for (i = 0; i < num_segments; i++) {
1294
    for (i = 0; i < num_segments; i++) {
Line 1268... Line 1339...
1268
cairo_int_status_t
1339
cairo_int_status_t
1269
_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
1340
_cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font,
1270
                               unsigned long        index,
1341
                               unsigned long        index,
1271
                               uint32_t            *ucs4)
1342
                               uint32_t            *ucs4)
1272
{
1343
{
1273
    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
1344
    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
1274
    const cairo_scaled_font_backend_t *backend;
1345
    const cairo_scaled_font_backend_t *backend;
1275
    tt_cmap_t *cmap;
1346
    tt_cmap_t *cmap;
1276
    char buf[4];
1347
    char buf[4];
1277
    int num_tables, i;
1348
    int num_tables, i;
1278
    unsigned long size;
1349
    unsigned long size;
Line 1320... Line 1391...
1320
    free (cmap);
1391
    free (cmap);
Line 1321... Line 1392...
1321
 
1392
 
1322
    return status;
1393
    return status;
Line -... Line 1394...
-
 
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;
1323
}
1495
}
1324
 
1496
 
1325
cairo_int_status_t
1497
cairo_int_status_t
1326
_cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
1498
_cairo_truetype_read_font_name (cairo_scaled_font_t  	 *scaled_font,
1327
				char 	       		**ps_name_out,
1499
				char 	       		**ps_name_out,
1328
				char 	       		**font_name_out)
1500
				char 	       		**font_name_out)
1329
{
1501
{
1330
    cairo_status_t status;
1502
    cairo_status_t status;
1331
    const cairo_scaled_font_backend_t *backend;
-
 
1332
    tt_name_t *name;
1503
    const cairo_scaled_font_backend_t *backend;
1333
    tt_name_record_t *record;
-
 
1334
    unsigned long size;
1504
    tt_name_t *name;
1335
    int i, j;
1505
    unsigned long size;
Line 1336... Line 1506...
1336
    char *ps_name = NULL;
1506
    char *ps_name = NULL;
1337
    char *font_name = NULL;
1507
    char *family_name = NULL;
1338
 
1508
 
Line 1357... Line 1527...
1357
					   (unsigned char *) name,
1527
					   (unsigned char *) name,
1358
					   &size);
1528
					   &size);
1359
    if (status)
1529
    if (status)
1360
	goto fail;
1530
	goto fail;
Line 1361... Line 1531...
1361
 
1531
 
1362
    /* Extract the font name and PS name from the name table. At
1532
    /* Find PS Name (name_id = 6). OT spec says PS name must be one of
1363
     * present this just looks for the Mac platform/Roman encoded font
1533
     * the following two encodings */
1364
     * name. It should be extended to use any suitable font name in
1534
    status = find_name (name, 6, 3, 1, 0x409, &ps_name); /* win, unicode, english-us */
1365
     * the name table.
1535
    if (unlikely(status))
1366
     */
-
 
1367
    for (i = 0; i < be16_to_cpu(name->num_records); i++) {
-
 
1368
        record = &(name->records[i]);
-
 
1369
        if ((be16_to_cpu (record->platform) == 1) &&
-
 
Line 1370... Line 1536...
1370
            (be16_to_cpu (record->encoding) == 0)) {
1536
	goto fail;
1371
 
1537
 
1372
	    if (be16_to_cpu (record->name) == 4) {
1538
    if (!ps_name) {
1373
		font_name = malloc (be16_to_cpu(record->length) + 1);
-
 
1374
		if (font_name == NULL) {
1539
	status = find_name (name, 6, 1, 0, 0, &ps_name); /* mac, roman, english */
1375
		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1540
	if (unlikely(status))
1376
		    goto fail;
-
 
1377
		}
-
 
1378
		strncpy(font_name,
-
 
1379
			((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
-
 
1380
			be16_to_cpu (record->length));
-
 
Line 1381... Line 1541...
1381
		font_name[be16_to_cpu (record->length)] = 0;
1541
	    goto fail;
1382
	    }
1542
    }
-
 
1543
 
-
 
1544
    /* Find Family name (name_id = 1) */
-
 
1545
    status = find_name (name, 1, 3, 1, 0x409, &family_name); /* win, unicode, english-us */
1383
 
1546
    if (unlikely(status))
1384
	    if (be16_to_cpu (record->name) == 6) {
1547
	goto fail;
-
 
1548
 
1385
		ps_name = malloc (be16_to_cpu(record->length) + 1);
1549
    if (!family_name) {
1386
		if (ps_name == NULL) {
-
 
1387
		    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
1388
		    goto fail;
-
 
1389
		}
-
 
1390
		strncpy(ps_name,
-
 
1391
			((char*)name) + be16_to_cpu (name->strings_offset) + be16_to_cpu (record->offset),
1550
	status = find_name (name, 1, 3, 0, 0x409, &family_name); /* win, symbol, english-us */
Line 1392... Line 1551...
1392
			be16_to_cpu (record->length));
1551
	if (unlikely(status))
-
 
1552
	    goto fail;
-
 
1553
    }
1393
		ps_name[be16_to_cpu (record->length)] = 0;
1554
 
1394
	    }
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
 
1395
 
1561
    if (!family_name) {
Line 1396... Line 1562...
1396
	    if (font_name && ps_name)
1562
	status = find_name (name, 1, 3, 1, -1, &family_name); /* win, unicode, any language */
Line 1397... Line 1563...
1397
		break;
1563
	if (unlikely(status))
-
 
1564
	    goto fail;
-
 
1565
    }
-
 
1566
 
-
 
1567
    free (name);
1398
        }
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. */
1399
    }
1574
    if (ps_name) {
-
 
1575
	static const char *reserved = "()<>[]{}/%#\\";
-
 
1576
	char buf[128]; /* max name length is 127 bytes */
1400
 
1577
	char *src = ps_name;
-
 
1578
	char *dst = buf;
-
 
1579
 
-
 
1580
	while (*src && dst < buf + 127) {
-
 
1581
	    unsigned char c = *src;
1401
    free (name);
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 {
1402
 
1590
		*dst++ = *src++;
-
 
1591
	    }
-
 
1592
	}
1403
    /* Ensure PS name does not contain any spaces */
1593
	*dst = 0;
1404
    if (ps_name) {
-
 
1405
	for (i = 0, j = 0; ps_name[j]; j++) {
1594
	free (ps_name);
Line 1406... Line 1595...
1406
	    if (ps_name[j] == ' ')
1595
	ps_name = strdup (buf);
1407
		continue;
1596
	if (ps_name == NULL) {
Line 1408... Line 1597...
1408
	    ps_name[i++] = ps_name[j];
1597
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
Line 1409... Line 1598...
1409
	}
1598
	    goto fail;
1410
	ps_name[i] = '\0';
1599
	}
1411
    }
-
 
1412
 
-
 
1413
    *ps_name_out = ps_name;
1600
    }
1414
    *font_name_out = font_name;
-
 
1415
 
-
 
1416
    return CAIRO_STATUS_SUCCESS;
1601
 
1417
 
-
 
1418
fail:
1602
    *ps_name_out = ps_name;
1419
    free (name);
1603
    *font_name_out = family_name;
Line 1420... Line 1604...
1420
 
1604
 
1421
    if (ps_name != NULL)
1605
    return CAIRO_STATUS_SUCCESS;
Line -... Line 1606...
-
 
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);
1422
	free (ps_name);
1649
    if (status)