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 68... Line 68...
68
    cairo_hash_entry_t base;
68
    cairo_hash_entry_t base;
Line 69... Line 69...
69
 
69
 
70
    cairo_bool_t is_scaled;
70
    cairo_bool_t is_scaled;
71
    cairo_bool_t is_composite;
71
    cairo_bool_t is_composite;
-
 
72
    cairo_bool_t is_user;
72
    cairo_bool_t is_user;
73
    cairo_bool_t use_latin_subset;
73
    cairo_scaled_font_subsets_t *parent;
74
    cairo_scaled_font_subsets_t *parent;
74
    cairo_scaled_font_t *scaled_font;
75
    cairo_scaled_font_t *scaled_font;
Line 75... Line 76...
75
    unsigned int font_id;
76
    unsigned int font_id;
76
 
77
 
-
 
78
    int current_subset;
77
    int current_subset;
79
    int num_glyphs_in_current_subset;
-
 
80
    int num_glyphs_in_latin_subset;
Line 78... Line 81...
78
    int num_glyphs_in_current_subset;
81
    int max_glyphs_per_subset;
79
    int max_glyphs_per_subset;
82
    char latin_char_map[256];
80
 
83
 
Line 81... Line 84...
81
    cairo_hash_table_t *sub_font_glyphs;
84
    cairo_hash_table_t *sub_font_glyphs;
82
    struct _cairo_sub_font *next;
85
    struct _cairo_sub_font *next;
-
 
86
} cairo_sub_font_t;
Line 83... Line 87...
83
} cairo_sub_font_t;
87
 
84
 
88
struct _cairo_scaled_font_subsets {
85
struct _cairo_scaled_font_subsets {
89
    cairo_subsets_type_t type;
86
    cairo_subsets_type_t type;
90
    cairo_bool_t use_latin_subset;
Line 104... Line 108...
104
    unsigned int subset_id;
108
    unsigned int subset_id;
105
    unsigned int subset_glyph_index;
109
    unsigned int subset_glyph_index;
106
    double       x_advance;
110
    double       x_advance;
107
    double       y_advance;
111
    double       y_advance;
Line -... Line 112...
-
 
112
 
-
 
113
    cairo_bool_t is_latin;
108
 
114
    int		 latin_character;
109
    cairo_bool_t is_mapped;
115
    cairo_bool_t is_mapped;
110
    uint32_t     unicode;
116
    uint32_t     unicode;
111
    char  	*utf8;
117
    char  	*utf8;
112
    int          utf8_len;
118
    int          utf8_len;
Line 113... Line 119...
113
} cairo_sub_font_glyph_t;
119
} cairo_sub_font_glyph_t;
114
 
120
 
115
typedef struct _cairo_sub_font_collection {
121
typedef struct _cairo_sub_font_collection {
116
    unsigned long *glyphs; /* scaled_font_glyph_index */
122
    unsigned long *glyphs; /* scaled_font_glyph_index */
-
 
123
    char       **utf8;
-
 
124
    unsigned int glyphs_size;
117
    char       **utf8;
125
    int           *to_latin_char;
118
    unsigned int glyphs_size;
126
    unsigned long *latin_to_subset_glyph_index;
Line 119... Line 127...
119
    unsigned int max_glyph;
127
    unsigned int max_glyph;
Line 143... Line 151...
143
				unsigned long		 scaled_font_glyph_index)
151
				unsigned long		 scaled_font_glyph_index)
144
{
152
{
145
    sub_font_glyph->base.hash = scaled_font_glyph_index;
153
    sub_font_glyph->base.hash = scaled_font_glyph_index;
146
}
154
}
Line 147... Line -...
147
 
-
 
148
static cairo_bool_t
-
 
149
_cairo_sub_font_glyphs_equal (const void *key_a, const void *key_b)
-
 
150
{
-
 
151
    const cairo_sub_font_glyph_t *sub_font_glyph_a = key_a;
-
 
152
    const cairo_sub_font_glyph_t *sub_font_glyph_b = key_b;
-
 
153
 
-
 
154
    return sub_font_glyph_a->base.hash == sub_font_glyph_b->base.hash;
-
 
155
}
-
 
156
 
155
 
157
static cairo_sub_font_glyph_t *
156
static cairo_sub_font_glyph_t *
158
_cairo_sub_font_glyph_create (unsigned long	scaled_font_glyph_index,
157
_cairo_sub_font_glyph_create (unsigned long	scaled_font_glyph_index,
159
			      unsigned int	subset_id,
158
			      unsigned int	subset_id,
160
			      unsigned int	subset_glyph_index,
159
			      unsigned int	subset_glyph_index,
161
                              double            x_advance,
160
                              double            x_advance,
-
 
161
                              double            y_advance,
-
 
162
			      int	        latin_character,
-
 
163
			      uint32_t          unicode,
-
 
164
			      char             *utf8,
162
                              double            y_advance)
165
			      int          	utf8_len)
163
{
166
{
Line 164... Line 167...
164
    cairo_sub_font_glyph_t *sub_font_glyph;
167
    cairo_sub_font_glyph_t *sub_font_glyph;
165
 
168
 
Line 172... Line 175...
172
    _cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index);
175
    _cairo_sub_font_glyph_init_key (sub_font_glyph, scaled_font_glyph_index);
173
    sub_font_glyph->subset_id = subset_id;
176
    sub_font_glyph->subset_id = subset_id;
174
    sub_font_glyph->subset_glyph_index = subset_glyph_index;
177
    sub_font_glyph->subset_glyph_index = subset_glyph_index;
175
    sub_font_glyph->x_advance = x_advance;
178
    sub_font_glyph->x_advance = x_advance;
176
    sub_font_glyph->y_advance = y_advance;
179
    sub_font_glyph->y_advance = y_advance;
-
 
180
    sub_font_glyph->is_latin = (latin_character >= 0);
-
 
181
    sub_font_glyph->latin_character = latin_character;
177
    sub_font_glyph->is_mapped = FALSE;
182
    sub_font_glyph->is_mapped = FALSE;
178
    sub_font_glyph->unicode = -1;
183
    sub_font_glyph->unicode = unicode;
179
    sub_font_glyph->utf8 = NULL;
184
    sub_font_glyph->utf8 = utf8;
180
    sub_font_glyph->utf8_len = 0;
185
    sub_font_glyph->utf8_len = utf8_len;
Line 181... Line 186...
181
 
186
 
182
    return sub_font_glyph;
187
    return sub_font_glyph;
Line 183... Line 188...
183
}
188
}
184
 
189
 
185
static void
190
static void
186
_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph)
-
 
187
{
191
_cairo_sub_font_glyph_destroy (cairo_sub_font_glyph_t *sub_font_glyph)
Line 188... Line 192...
188
    if (sub_font_glyph->utf8 != NULL)
192
{
189
	free (sub_font_glyph->utf8);
193
    free (sub_font_glyph->utf8);
Line 218... Line 222...
218
    /* Ensure we don't exceed the allocated bounds. */
222
    /* Ensure we don't exceed the allocated bounds. */
219
    assert (subset_glyph_index < collection->glyphs_size);
223
    assert (subset_glyph_index < collection->glyphs_size);
Line 220... Line 224...
220
 
224
 
221
    collection->glyphs[subset_glyph_index] = scaled_font_glyph_index;
225
    collection->glyphs[subset_glyph_index] = scaled_font_glyph_index;
-
 
226
    collection->utf8[subset_glyph_index] = sub_font_glyph->utf8;
-
 
227
    collection->to_latin_char[subset_glyph_index] = sub_font_glyph->latin_character;
-
 
228
    if (sub_font_glyph->is_latin)
-
 
229
	collection->latin_to_subset_glyph_index[sub_font_glyph->latin_character] = subset_glyph_index;
222
    collection->utf8[subset_glyph_index] = sub_font_glyph->utf8;
230
 
223
    if (subset_glyph_index > collection->max_glyph)
231
    if (subset_glyph_index > collection->max_glyph)
Line 224... Line 232...
224
	collection->max_glyph = subset_glyph_index;
232
	collection->max_glyph = subset_glyph_index;
225
 
233
 
Line 264... Line 272...
264
                        cairo_bool_t                     is_scaled,
272
                        cairo_bool_t                     is_scaled,
265
			cairo_bool_t                     is_composite,
273
			cairo_bool_t                     is_composite,
266
			cairo_sub_font_t               **sub_font_out)
274
			cairo_sub_font_t               **sub_font_out)
267
{
275
{
268
    cairo_sub_font_t *sub_font;
276
    cairo_sub_font_t *sub_font;
269
    cairo_status_t status;
277
    int i;
270
    cairo_scaled_font_subsets_glyph_t subset_glyph;
-
 
Line 271... Line 278...
271
 
278
 
272
    sub_font = malloc (sizeof (cairo_sub_font_t));
279
    sub_font = malloc (sizeof (cairo_sub_font_t));
273
    if (unlikely (sub_font == NULL))
280
    if (unlikely (sub_font == NULL))
Line 280... Line 287...
280
 
287
 
281
    sub_font->parent = parent;
288
    sub_font->parent = parent;
282
    sub_font->scaled_font = scaled_font;
289
    sub_font->scaled_font = scaled_font;
Line -... Line 290...
-
 
290
    sub_font->font_id = font_id;
-
 
291
 
-
 
292
    sub_font->use_latin_subset = parent->use_latin_subset;
-
 
293
 
-
 
294
    /* latin subsets of Type 3 and CID CFF fonts are not supported */
-
 
295
    if (sub_font->is_user || sub_font->is_scaled ||
-
 
296
	_cairo_cff_scaled_font_is_cid_cff (scaled_font) )
-
 
297
    {
-
 
298
	sub_font->use_latin_subset = FALSE;
-
 
299
    }
-
 
300
 
-
 
301
    if (sub_font->use_latin_subset)
283
    sub_font->font_id = font_id;
302
	sub_font->current_subset = 1; /* reserve subset 0 for latin glyphs */
-
 
303
    else
284
 
304
	sub_font->current_subset = 0;
-
 
305
 
285
    sub_font->current_subset = 0;
306
    sub_font->num_glyphs_in_current_subset = 0;
-
 
307
    sub_font->num_glyphs_in_latin_subset = 0;
-
 
308
    sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
Line 286... Line 309...
286
    sub_font->num_glyphs_in_current_subset = 0;
309
    for (i = 0; i < 256; i++)
287
    sub_font->max_glyphs_per_subset = max_glyphs_per_subset;
310
	sub_font->latin_char_map[i] = FALSE;
288
 
311
 
289
    sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal);
312
    sub_font->sub_font_glyphs = _cairo_hash_table_create (NULL);
290
    if (unlikely (sub_font->sub_font_glyphs == NULL)) {
313
    if (unlikely (sub_font->sub_font_glyphs == NULL)) {
291
	free (sub_font);
314
	free (sub_font);
292
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
293
    }
-
 
294
    sub_font->next = NULL;
-
 
295
 
-
 
296
    /* Reserve first glyph in subset for the .notdef glyph except for
-
 
297
     * Type 3 fonts */
-
 
298
    if (! is_scaled) {
-
 
299
	status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph);
-
 
300
	if (unlikely (status)) {
-
 
301
	    _cairo_hash_table_destroy (sub_font->sub_font_glyphs);
-
 
302
	    free (sub_font);
-
 
303
	    return status;
-
 
304
	}
315
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
305
    }
316
    }
306
 
317
    sub_font->next = NULL;
Line 307... Line 318...
307
    *sub_font_out = sub_font;
318
    *sub_font_out = sub_font;
Line 327... Line 338...
327
 
338
 
328
    _cairo_hash_table_remove (sub_fonts, &sub_font->base);
339
    _cairo_hash_table_remove (sub_fonts, &sub_font->base);
329
    _cairo_sub_font_destroy (sub_font);
340
    _cairo_sub_font_destroy (sub_font);
Line -... Line 341...
-
 
341
}
-
 
342
 
-
 
343
/* Characters 0x80 to 0x9f in the winansi encoding.
-
 
344
 * All other characters in the range 0x00 to 0xff map 1:1 to unicode */
-
 
345
static unsigned int _winansi_0x80_to_0x9f[] = {
-
 
346
    0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
-
 
347
    0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
-
 
348
    0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
-
 
349
    0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178
-
 
350
};
-
 
351
 
-
 
352
int
-
 
353
_cairo_unicode_to_winansi (unsigned long uni)
-
 
354
{
-
 
355
    int i;
-
 
356
 
-
 
357
    /* exclude the extra "hyphen" at 0xad to avoid duplicate glyphnames */
-
 
358
    if ((uni >= 0x20 && uni <= 0x7e) ||
-
 
359
	(uni >= 0xa1 && uni <= 0xff && uni != 0xad) ||
-
 
360
	uni == 0)
-
 
361
        return uni;
-
 
362
 
-
 
363
    for (i = 0; i < 32; i++)
-
 
364
	if (_winansi_0x80_to_0x9f[i] == uni)
-
 
365
	    return i + 0x80;
-
 
366
 
-
 
367
    return -1;
330
}
368
}
331
 
369
 
332
static cairo_status_t
370
static cairo_status_t
-
 
371
_cairo_sub_font_glyph_lookup_unicode (cairo_scaled_font_t    *scaled_font,
-
 
372
				      unsigned long	      scaled_font_glyph_index,
333
_cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
373
				      uint32_t     	     *unicode_out,
334
				      cairo_scaled_font_t    *scaled_font,
374
				      char  		    **utf8_out,
335
				      unsigned long	      scaled_font_glyph_index)
375
				      int          	     *utf8_len_out)
336
{
376
{
337
    uint32_t unicode;
377
    uint32_t unicode;
338
    char buf[8];
378
    char buf[8];
Line 354... Line 394...
354
						      &unicode);
394
						      &unicode);
355
	if (unlikely (status))
395
	if (unlikely (status))
356
	    return status;
396
	    return status;
357
    }
397
    }
Line 358... Line 398...
358
 
398
 
359
    sub_font_glyph->unicode = unicode;
399
    *unicode_out = unicode;
360
    sub_font_glyph->utf8 = NULL;
400
    *utf8_out = NULL;
361
    sub_font_glyph->utf8_len = 0;
401
    *utf8_len_out = 0;
362
    if (unicode != (uint32_t) -1) {
402
    if (unicode != (uint32_t) -1) {
363
	len = _cairo_ucs4_to_utf8 (unicode, buf);
403
	len = _cairo_ucs4_to_utf8 (unicode, buf);
364
	if (len > 0) {
404
	if (len > 0) {
365
	    sub_font_glyph->utf8 = malloc (len + 1);
405
	    *utf8_out = malloc (len + 1);
366
	    if (unlikely (sub_font_glyph->utf8 == NULL))
406
	    if (unlikely (*utf8_out == NULL))
Line 367... Line 407...
367
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
407
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
368
 
408
 
369
	    memcpy (sub_font_glyph->utf8, buf, len);
409
	    memcpy (*utf8_out, buf, len);
370
	    sub_font_glyph->utf8[len] = 0;
410
	    (*utf8_out)[len] = 0;
371
	    sub_font_glyph->utf8_len = len;
411
	    *utf8_len_out = len;
Line 372... Line 412...
372
	}
412
	}
373
    }
413
    }
Line 427... Line 467...
427
    sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
467
    sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
428
					      &key.base);
468
					      &key.base);
429
    if (sub_font_glyph != NULL) {
469
    if (sub_font_glyph != NULL) {
430
        subset_glyph->font_id = sub_font->font_id;
470
        subset_glyph->font_id = sub_font->font_id;
431
        subset_glyph->subset_id = sub_font_glyph->subset_id;
471
        subset_glyph->subset_id = sub_font_glyph->subset_id;
-
 
472
	if (sub_font_glyph->is_latin)
-
 
473
	    subset_glyph->subset_glyph_index = sub_font_glyph->latin_character;
-
 
474
	else
432
        subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
475
	    subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
-
 
476
 
433
        subset_glyph->is_scaled = sub_font->is_scaled;
477
        subset_glyph->is_scaled = sub_font->is_scaled;
434
        subset_glyph->is_composite = sub_font->is_composite;
478
        subset_glyph->is_composite = sub_font->is_composite;
-
 
479
	subset_glyph->is_latin = sub_font_glyph->is_latin;
435
        subset_glyph->x_advance = sub_font_glyph->x_advance;
480
        subset_glyph->x_advance = sub_font_glyph->x_advance;
436
        subset_glyph->y_advance = sub_font_glyph->y_advance;
481
        subset_glyph->y_advance = sub_font_glyph->y_advance;
437
	status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
482
	status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
438
						       utf8, utf8_len,
483
						       utf8, utf8_len,
439
						       &subset_glyph->utf8_is_mapped);
484
						       &subset_glyph->utf8_is_mapped);
Line 444... Line 489...
444
 
489
 
445
    return CAIRO_INT_STATUS_UNSUPPORTED;
490
    return CAIRO_INT_STATUS_UNSUPPORTED;
Line 446... Line 491...
446
}
491
}
447
 
492
 
448
static cairo_status_t
493
static cairo_status_t
-
 
494
_cairo_sub_font_add_glyph (cairo_sub_font_t	   *sub_font,
-
 
495
			   unsigned long	    scaled_font_glyph_index,
-
 
496
			   cairo_bool_t		    is_latin,
449
_cairo_sub_font_map_glyph (cairo_sub_font_t	*sub_font,
497
			   int			    latin_character,
450
			   unsigned long	 scaled_font_glyph_index,
498
			   uint32_t 		    unicode,
451
			   const char		*utf8,
499
			   char 		   *utf8,
452
			   int			 utf8_len,
500
			   int 			    utf8_len,
453
                           cairo_scaled_font_subsets_glyph_t *subset_glyph)
-
 
454
{
-
 
455
    cairo_sub_font_glyph_t key, *sub_font_glyph;
-
 
456
    cairo_status_t status;
-
 
457
 
-
 
458
    _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
-
 
459
    sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
-
 
460
					       &key.base);
501
			   cairo_sub_font_glyph_t **sub_font_glyph_out)
461
    if (sub_font_glyph == NULL) {
-
 
462
	cairo_scaled_glyph_t *scaled_glyph;
-
 
463
 
-
 
464
	if (sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
502
{
465
	{
-
 
466
	    cairo_scaled_font_subsets_glyph_t tmp_subset_glyph;
-
 
467
 
503
    cairo_scaled_glyph_t *scaled_glyph;
468
	    sub_font->current_subset++;
-
 
469
	    sub_font->num_glyphs_in_current_subset = 0;
-
 
470
 
504
    cairo_sub_font_glyph_t *sub_font_glyph;
471
	    /* Reserve first glyph in subset for the .notdef glyph
-
 
472
	     * except for Type 3 fonts */
-
 
473
	    if (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)) {
505
    int *num_glyphs_in_subset_ptr;
474
		status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &tmp_subset_glyph);
506
    double x_advance;
475
		if (unlikely (status))
-
 
476
		    return status;
-
 
Line 477... Line 507...
477
	    }
507
    double y_advance;
478
	}
508
    cairo_int_status_t status;
479
 
509
 
480
	_cairo_scaled_font_freeze_cache (sub_font->scaled_font);
510
    _cairo_scaled_font_freeze_cache (sub_font->scaled_font);
Line 486... Line 516...
486
	if (unlikely (status)) {
516
    if (unlikely (status)) {
487
	    _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
517
	_cairo_scaled_font_thaw_cache (sub_font->scaled_font);
488
	    return status;
518
	return status;
489
	}
519
    }
Line 490... Line -...
490
 
-
 
491
        sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
-
 
492
						       sub_font->current_subset,
-
 
493
						       sub_font->num_glyphs_in_current_subset,
520
 
494
                                                       scaled_glyph->metrics.x_advance,
521
    x_advance = scaled_glyph->metrics.x_advance;
495
                                                       scaled_glyph->metrics.y_advance);
522
    y_advance = scaled_glyph->metrics.y_advance;
Line -... Line 523...
-
 
523
    _cairo_scaled_font_thaw_cache (sub_font->scaled_font);
-
 
524
 
496
	_cairo_scaled_font_thaw_cache (sub_font->scaled_font);
525
    if (!is_latin && sub_font->num_glyphs_in_current_subset == sub_font->max_glyphs_per_subset)
497
 
526
    {
-
 
527
	sub_font->current_subset++;
Line -... Line 528...
-
 
528
	sub_font->num_glyphs_in_current_subset = 0;
-
 
529
    }
-
 
530
 
-
 
531
    if (is_latin)
-
 
532
	num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_latin_subset;
-
 
533
    else
-
 
534
	num_glyphs_in_subset_ptr = &sub_font->num_glyphs_in_current_subset;
-
 
535
 
-
 
536
    /* Reserve first glyph in subset for the .notdef glyph except for
-
 
537
     * Type 3 fonts */
-
 
538
    if (*num_glyphs_in_subset_ptr == 0 &&
498
	if (unlikely (sub_font_glyph == NULL))
539
	scaled_font_glyph_index != 0 &&
-
 
540
	! _cairo_font_face_is_user (sub_font->scaled_font->font_face))
499
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
541
    {
-
 
542
	status = _cairo_sub_font_add_glyph (sub_font,
-
 
543
					    0,
-
 
544
					    is_latin,
-
 
545
					    0,
500
 
546
					    0,
501
	status = _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph,
547
					    NULL,
502
						       sub_font->scaled_font,
-
 
503
						       scaled_font_glyph_index);
548
					    -1,
504
	if (unlikely (status)) {
549
					    &sub_font_glyph);
Line -... Line 550...
-
 
550
	if (unlikely (status))
-
 
551
	    return status;
-
 
552
    }
-
 
553
 
-
 
554
    sub_font_glyph = _cairo_sub_font_glyph_create (scaled_font_glyph_index,
-
 
555
						   is_latin ? 0 : sub_font->current_subset,
-
 
556
						   *num_glyphs_in_subset_ptr,
-
 
557
						   x_advance,
-
 
558
						   y_advance,
-
 
559
						   is_latin ? latin_character : -1,
-
 
560
						   unicode,
-
 
561
						   utf8,
-
 
562
						   utf8_len);
505
	    _cairo_sub_font_glyph_destroy (sub_font_glyph);
563
 
506
	    return status;
564
    if (unlikely (sub_font_glyph == NULL))
507
	}
565
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
508
 
566
 
509
	status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
567
    status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base);
Line 510... Line 568...
510
	if (unlikely (status)) {
568
    if (unlikely (status)) {
511
	    _cairo_sub_font_glyph_destroy (sub_font_glyph);
-
 
512
	    return status;
569
	_cairo_sub_font_glyph_destroy (sub_font_glyph);
513
	}
570
	return status;
514
 
571
    }
515
	sub_font->num_glyphs_in_current_subset++;
572
 
516
 
573
    (*num_glyphs_in_subset_ptr)++;
517
        if (sub_font->is_scaled) {
574
    if (sub_font->is_scaled) {
518
            if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_scaled_subset_used)
575
	if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_scaled_subset_used)
-
 
576
	    sub_font->parent->max_glyphs_per_scaled_subset_used = *num_glyphs_in_subset_ptr;
-
 
577
    } else {
-
 
578
	if (*num_glyphs_in_subset_ptr > sub_font->parent->max_glyphs_per_unscaled_subset_used)
-
 
579
	    sub_font->parent->max_glyphs_per_unscaled_subset_used = *num_glyphs_in_subset_ptr;
-
 
580
    }
-
 
581
 
-
 
582
    *sub_font_glyph_out = sub_font_glyph;
-
 
583
 
-
 
584
    return CAIRO_STATUS_SUCCESS;
-
 
585
}
-
 
586
 
-
 
587
static cairo_status_t
-
 
588
_cairo_sub_font_map_glyph (cairo_sub_font_t	*sub_font,
-
 
589
			   unsigned long	 scaled_font_glyph_index,
-
 
590
			   const char		*text_utf8,
-
 
591
			   int			 text_utf8_len,
-
 
592
                           cairo_scaled_font_subsets_glyph_t *subset_glyph)
-
 
593
{
-
 
594
    cairo_sub_font_glyph_t key, *sub_font_glyph;
-
 
595
    cairo_status_t status;
-
 
596
 
-
 
597
    _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
-
 
598
    sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
-
 
599
					       &key.base);
-
 
600
    if (sub_font_glyph == NULL) {
-
 
601
	uint32_t font_unicode;
-
 
602
	char *font_utf8;
-
 
603
	int font_utf8_len;
-
 
604
	cairo_bool_t is_latin;
-
 
605
	int latin_character;
-
 
606
 
-
 
607
	status = _cairo_sub_font_glyph_lookup_unicode (sub_font->scaled_font,
-
 
608
							   scaled_font_glyph_index,
-
 
609
							   &font_unicode,
-
 
610
							   &font_utf8,
-
 
611
							   &font_utf8_len);
-
 
612
	if (unlikely(status))
-
 
613
	    return status;
-
 
614
 
-
 
615
	/* If the supplied utf8 is a valid single character, use it
-
 
616
	 * instead of the font lookup */
-
 
617
	if (text_utf8 != NULL && text_utf8_len > 0) {
-
 
618
	    uint32_t  *ucs4;
-
 
619
	    int	ucs4_len;
-
 
620
 
-
 
621
	    status = _cairo_utf8_to_ucs4 (text_utf8, text_utf8_len,
-
 
622
					  &ucs4, &ucs4_len);
-
 
623
	    if (status == CAIRO_STATUS_SUCCESS) {
-
 
624
		if (ucs4_len == 1) {
-
 
625
		    font_unicode = ucs4[0];
-
 
626
		    free (font_utf8);
-
 
627
		    font_utf8 = malloc (text_utf8_len + 1);
-
 
628
		    if (font_utf8 == NULL) {
-
 
629
			free (ucs4);
-
 
630
			return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
631
		    }
-
 
632
		    memcpy (font_utf8, text_utf8, text_utf8_len);
-
 
633
		    font_utf8[text_utf8_len] = 0;
-
 
634
		    font_utf8_len = text_utf8_len;
-
 
635
		}
-
 
636
		free (ucs4);
-
 
637
	    }
-
 
638
	}
-
 
639
 
-
 
640
	/* If glyph is in the winansi encoding and font is not a user
-
 
641
	 * font, put glyph in the latin subset. If glyph is .notdef
-
 
642
	 * the latin subset is preferred but only if the latin subset
-
 
643
	 * already contains at least one glyph. We don't want to
-
 
644
	 * create a separate subset just for the .notdef glyph.
-
 
645
	 */
-
 
646
	is_latin = FALSE;
-
 
647
	latin_character = -1;
-
 
648
	if (sub_font->use_latin_subset &&
-
 
649
	    (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)))
-
 
650
	{
-
 
651
	    latin_character = _cairo_unicode_to_winansi (font_unicode);
-
 
652
	    if (latin_character > 0 ||
-
 
653
		(latin_character == 0 && sub_font->num_glyphs_in_latin_subset > 0))
-
 
654
	    {
-
 
655
		if (!sub_font->latin_char_map[latin_character]) {
-
 
656
		    sub_font->latin_char_map[latin_character] = TRUE;
-
 
657
		    is_latin = TRUE;
-
 
658
		}
-
 
659
	    }
-
 
660
	}
-
 
661
 
-
 
662
	status = _cairo_sub_font_add_glyph (sub_font,
-
 
663
					    scaled_font_glyph_index,
-
 
664
					    is_latin,
-
 
665
					    latin_character,
-
 
666
					    font_unicode,
519
                sub_font->parent->max_glyphs_per_scaled_subset_used = sub_font->num_glyphs_in_current_subset;
667
					    font_utf8,
Line 520... Line 668...
520
        } else {
668
					    font_utf8_len,
521
            if (sub_font->num_glyphs_in_current_subset > sub_font->parent->max_glyphs_per_unscaled_subset_used)
669
					    &sub_font_glyph);
-
 
670
	if (unlikely(status))
-
 
671
	    return status;
-
 
672
    }
522
                sub_font->parent->max_glyphs_per_unscaled_subset_used = sub_font->num_glyphs_in_current_subset;
673
 
-
 
674
    subset_glyph->font_id = sub_font->font_id;
523
        }
675
    subset_glyph->subset_id = sub_font_glyph->subset_id;
524
    }
676
    if (sub_font_glyph->is_latin)
-
 
677
	subset_glyph->subset_glyph_index = sub_font_glyph->latin_character;
525
 
678
    else
526
    subset_glyph->font_id = sub_font->font_id;
679
	subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
527
    subset_glyph->subset_id = sub_font_glyph->subset_id;
680
 
528
    subset_glyph->subset_glyph_index = sub_font_glyph->subset_glyph_index;
681
    subset_glyph->is_scaled = sub_font->is_scaled;
529
    subset_glyph->is_scaled = sub_font->is_scaled;
682
    subset_glyph->is_composite = sub_font->is_composite;
530
    subset_glyph->is_composite = sub_font->is_composite;
683
    subset_glyph->is_latin = sub_font_glyph->is_latin;
Line 531... Line 684...
531
    subset_glyph->x_advance = sub_font_glyph->x_advance;
684
    subset_glyph->x_advance = sub_font_glyph->x_advance;
532
    subset_glyph->y_advance = sub_font_glyph->y_advance;
685
    subset_glyph->y_advance = sub_font_glyph->y_advance;
Line 556... Line 709...
556
 
709
 
557
    for (i = 0; i <= sub_font->current_subset; i++) {
710
    for (i = 0; i <= sub_font->current_subset; i++) {
558
	collection->subset_id = i;
711
	collection->subset_id = i;
559
	collection->num_glyphs = 0;
712
	collection->num_glyphs = 0;
-
 
713
	collection->max_glyph = 0;
Line 560... Line 714...
560
	collection->max_glyph = 0;
714
	memset (collection->latin_to_subset_glyph_index, 0, 256*sizeof(unsigned long));
561
 
715
 
562
	_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
716
	_cairo_hash_table_foreach (sub_font->sub_font_glyphs,
563
				   _cairo_sub_font_glyph_collect, collection);
717
				   _cairo_sub_font_glyph_collect, collection);
Line 576... Line 730...
576
	subset.subset_id = i;
730
	subset.subset_id = i;
577
	subset.glyphs = collection->glyphs;
731
	subset.glyphs = collection->glyphs;
578
	subset.utf8 = collection->utf8;
732
	subset.utf8 = collection->utf8;
579
	subset.num_glyphs = collection->num_glyphs;
733
	subset.num_glyphs = collection->num_glyphs;
580
        subset.glyph_names = NULL;
734
        subset.glyph_names = NULL;
581
        /* No need to check for out of memory here. If to_unicode is NULL, the PDF
-
 
-
 
735
 
582
         * surface does not emit an ToUnicode stream */
736
	subset.is_latin = FALSE;
583
        subset.to_unicode = _cairo_malloc_ab (collection->num_glyphs, sizeof (unsigned long));
737
	if (sub_font->use_latin_subset && i == 0) {
584
        if (subset.to_unicode) {
738
	    subset.is_latin = TRUE;
585
            for (j = 0; j < collection->num_glyphs; j++) {
739
	    subset.to_latin_char = collection->to_latin_char;
586
                /* default unicode character required when mapping fails */
740
	    subset.latin_to_subset_glyph_index = collection->latin_to_subset_glyph_index;
-
 
741
	} else {
587
                subset.to_unicode[j] = 0xfffd;
742
	    subset.to_latin_char = NULL;
588
            }
743
	    subset.latin_to_subset_glyph_index = NULL;
589
        }
744
	}
-
 
745
 
590
        collection->status = (collection->font_subset_callback) (&subset,
746
        collection->status = (collection->font_subset_callback) (&subset,
591
					    collection->font_subset_callback_closure);
747
					    collection->font_subset_callback_closure);
Line 592... Line -...
592
 
-
 
593
        if (subset.to_unicode != NULL)
-
 
594
            free (subset.to_unicode);
-
 
595
 
748
 
596
	if (subset.glyph_names != NULL) {
749
	if (subset.glyph_names != NULL) {
597
            for (j = 0; j < collection->num_glyphs; j++)
750
            for (j = 0; j < collection->num_glyphs; j++)
598
		free (subset.glyph_names[j]);
751
		free (subset.glyph_names[j]);
599
	    free (subset.glyph_names);
752
	    free (subset.glyph_names);
Line 614... Line 767...
614
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
767
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
615
	return NULL;
768
	return NULL;
616
    }
769
    }
Line 617... Line 770...
617
 
770
 
-
 
771
    subsets->type = type;
618
    subsets->type = type;
772
    subsets->use_latin_subset = FALSE;
619
    subsets->max_glyphs_per_unscaled_subset_used = 0;
773
    subsets->max_glyphs_per_unscaled_subset_used = 0;
620
    subsets->max_glyphs_per_scaled_subset_used = 0;
774
    subsets->max_glyphs_per_scaled_subset_used = 0;
Line 621... Line 775...
621
    subsets->num_sub_fonts = 0;
775
    subsets->num_sub_fonts = 0;
Line 668... Line 822...
668
    _cairo_hash_table_destroy (subsets->unscaled_sub_fonts);
822
    _cairo_hash_table_destroy (subsets->unscaled_sub_fonts);
Line 669... Line 823...
669
 
823
 
670
    free (subsets);
824
    free (subsets);
Line -... Line 825...
-
 
825
}
-
 
826
 
-
 
827
void
-
 
828
_cairo_scaled_font_subsets_enable_latin_subset (cairo_scaled_font_subsets_t *font_subsets,
-
 
829
						cairo_bool_t                 use_latin)
-
 
830
{
-
 
831
    font_subsets->use_latin_subset = use_latin;
671
}
832
}
672
 
833
 
673
cairo_status_t
834
cairo_status_t
674
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
835
_cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t	*subsets,
675
				      cairo_scaled_font_t		*scaled_font,
836
				      cairo_scaled_font_t		*scaled_font,
Line 682... Line 843...
682
    cairo_scaled_glyph_t *scaled_glyph;
843
    cairo_scaled_glyph_t *scaled_glyph;
683
    cairo_font_face_t *font_face;
844
    cairo_font_face_t *font_face;
684
    cairo_matrix_t identity;
845
    cairo_matrix_t identity;
685
    cairo_font_options_t font_options;
846
    cairo_font_options_t font_options;
686
    cairo_scaled_font_t	*unscaled_font;
847
    cairo_scaled_font_t	*unscaled_font;
687
    cairo_status_t status;
848
    cairo_int_status_t status;
688
    int max_glyphs;
849
    int max_glyphs;
689
    cairo_bool_t type1_font;
850
    cairo_bool_t type1_font;
Line 690... Line 851...
690
 
851
 
691
    /* Lookup glyph in unscaled subsets */
852
    /* Lookup glyph in unscaled subsets */
Line 735... Line 896...
735
					     scaled_font_glyph_index,
896
					     scaled_font_glyph_index,
736
					     CAIRO_SCALED_GLYPH_INFO_PATH,
897
					     CAIRO_SCALED_GLYPH_INFO_PATH,
737
					     &scaled_glyph);
898
					     &scaled_glyph);
738
	_cairo_scaled_font_thaw_cache (scaled_font);
899
	_cairo_scaled_font_thaw_cache (scaled_font);
739
    }
900
    }
740
    if (_cairo_status_is_error (status))
901
    if (_cairo_int_status_is_error (status))
741
        return status;
902
        return status;
Line 742... Line 903...
742
 
903
 
743
    if (status == CAIRO_STATUS_SUCCESS &&
904
    if (status == CAIRO_INT_STATUS_SUCCESS &&
744
	subsets->type != CAIRO_SUBSETS_SCALED &&
905
	subsets->type != CAIRO_SUBSETS_SCALED &&
745
	! _cairo_font_face_is_user (scaled_font->font_face))
906
	! _cairo_font_face_is_user (scaled_font->font_face))
746
    {
907
    {
747
        /* Path available. Add to unscaled subset. */
908
        /* Path available. Add to unscaled subset. */
Line 761... Line 922...
761
                                                      &font_options);
922
                                                      &font_options);
762
	    if (unlikely (unscaled_font->status))
923
	    if (unlikely (unscaled_font->status))
763
		return unscaled_font->status;
924
		return unscaled_font->status;
Line 764... Line 925...
764
 
925
 
765
            subset_glyph->is_scaled = FALSE;
-
 
766
            type1_font = FALSE;
-
 
767
#if CAIRO_HAS_FT_FONT
926
            subset_glyph->is_scaled = FALSE;
768
            type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font);
-
 
769
#endif
927
            type1_font = _cairo_type1_scaled_font_is_type1 (unscaled_font);
770
            if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) {
928
            if (subsets->type == CAIRO_SUBSETS_COMPOSITE && !type1_font) {
771
                max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT;
929
                max_glyphs = MAX_GLYPHS_PER_COMPOSITE_FONT;
772
                subset_glyph->is_composite = TRUE;
930
                subset_glyph->is_composite = TRUE;
773
            } else {
931
            } else {
Line 879... Line 1037...
879
    if (! collection.glyphs_size)
1037
    if (! collection.glyphs_size)
880
	return CAIRO_STATUS_SUCCESS;
1038
	return CAIRO_STATUS_SUCCESS;
Line 881... Line 1039...
881
 
1039
 
882
    collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
1040
    collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long));
-
 
1041
    collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *));
-
 
1042
    collection.to_latin_char = _cairo_malloc_ab (collection.glyphs_size, sizeof(int));
883
    collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *));
1043
    collection.latin_to_subset_glyph_index = _cairo_malloc_ab (256, sizeof(unsigned long));
884
    if (unlikely (collection.glyphs == NULL || collection.utf8 == NULL)) {
1044
    if (unlikely (collection.glyphs == NULL ||
-
 
1045
		  collection.utf8 == NULL ||
-
 
1046
		  collection.to_latin_char == NULL ||
885
	if (collection.glyphs != NULL)
1047
		  collection.latin_to_subset_glyph_index == NULL)) {
886
	    free (collection.glyphs);
-
 
887
	if (collection.utf8 != NULL)
1048
	free (collection.glyphs);
-
 
1049
	free (collection.utf8);
-
 
1050
	free (collection.to_latin_char);
Line 888... Line 1051...
888
	    free (collection.utf8);
1051
	free (collection.latin_to_subset_glyph_index);
889
 
1052
 
Line 890... Line 1053...
890
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1053
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
Line 905... Line 1068...
905
 
1068
 
906
	sub_font = sub_font->next;
1069
	sub_font = sub_font->next;
907
    }
1070
    }
908
    free (collection.utf8);
1071
    free (collection.utf8);
-
 
1072
    free (collection.glyphs);
-
 
1073
    free (collection.to_latin_char);
Line 909... Line 1074...
909
    free (collection.glyphs);
1074
    free (collection.latin_to_subset_glyph_index);
910
 
1075
 
Line 911... Line 1076...
911
    return collection.status;
1076
    return collection.status;
Line 1038... Line 1203...
1038
	    if (unlikely (status))
1203
	    if (unlikely (status))
1039
		goto CLEANUP_HASH;
1204
		goto CLEANUP_HASH;
1040
	}
1205
	}
Line 1041... Line 1206...
1041
 
1206
 
-
 
1207
	if (utf16_len == 1) {
-
 
1208
	    int ch = _cairo_unicode_to_winansi (utf16[0]);
-
 
1209
	    if (ch > 0 && _cairo_winansi_to_glyphname (ch))
-
 
1210
		strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf));
1042
	if (utf16_len == 1) {
1211
	    else
-
 
1212
		snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]);
1043
	    snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]);
1213
 
1044
	    _cairo_string_init_key (&key, buf);
1214
	    _cairo_string_init_key (&key, buf);
1045
	    entry = _cairo_hash_table_lookup (names, &key.base);
1215
	    entry = _cairo_hash_table_lookup (names, &key.base);
1046
	    if (entry != NULL)
1216
	    if (entry != NULL)
1047
		snprintf (buf, sizeof (buf), "g%d", i);
1217
		snprintf (buf, sizeof (buf), "g%d", i);
1048
	} else {
1218
	} else {
1049
	    snprintf (buf, sizeof (buf), "g%d", i);
1219
	    snprintf (buf, sizeof (buf), "g%d", i);
1050
	}
-
 
1051
	if (utf16)
1220
	}
Line 1052... Line 1221...
1052
	    free (utf16);
1221
	free (utf16);
1053
 
1222
 
1054
	subset->glyph_names[i] = strdup (buf);
1223
	subset->glyph_names[i] = strdup (buf);
Line 1075... Line 1244...
1075
    if (likely (status == CAIRO_STATUS_SUCCESS))
1244
    if (likely (status == CAIRO_STATUS_SUCCESS))
1076
	return CAIRO_STATUS_SUCCESS;
1245
	return CAIRO_STATUS_SUCCESS;
Line 1077... Line 1246...
1077
 
1246
 
1078
    if (subset->glyph_names != NULL) {
1247
    if (subset->glyph_names != NULL) {
1079
	for (i = 0; i < subset->num_glyphs; i++) {
-
 
1080
	    if (subset->glyph_names[i] != NULL)
1248
	for (i = 0; i < subset->num_glyphs; i++) {
1081
		free (subset->glyph_names[i]);
1249
	    free (subset->glyph_names[i]);
Line 1082... Line 1250...
1082
	}
1250
	}
1083
 
1251