358
360
goto CLEANUP_MUTEX_LOCK;
363
scaled_font = font_map->mru_scaled_font;
364
if (scaled_font != NULL) {
365
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
366
cairo_scaled_font_destroy (scaled_font);
367
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
361
370
/* remove scaled_fonts starting from the end so that font_map->holdovers
362
371
* is always in a consistent state when we release the mutex. */
363
372
while (font_map->num_holdovers) {
364
373
scaled_font = font_map->holdovers[font_map->num_holdovers-1];
366
374
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
367
375
_cairo_hash_table_remove (font_map->hash_table,
368
376
&scaled_font->hash_entry);
400
408
* The reason we have to create a fake scaled font instead of just using
401
409
* scaled_font is for lifecycle management: we need to (or rather,
402
* other code needs to) reference the scaked_font in the hash.
410
* other code needs to) reference the scaked_font in the hash table.
403
411
* We can't do that on the input scaled_font as it may be freed by
404
412
* font backend upon error.
469
477
_cairo_hash_table_remove (cairo_scaled_font_map->hash_table,
470
478
&scaled_font->hash_entry);
472
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
480
CAIRO_MUTEX_UNLOCK (placeholder_scaled_font->mutex);
474
482
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
475
483
cairo_scaled_font_destroy (placeholder_scaled_font);
480
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (cairo_scaled_font_t *scaled_font)
488
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (cairo_scaled_font_t *placeholder_scaled_font)
482
490
/* reference the place holder so it doesn't go away */
483
cairo_scaled_font_reference (scaled_font);
491
cairo_scaled_font_reference (placeholder_scaled_font);
485
493
/* now unlock the fontmap mutex so creation has a chance to finish */
486
494
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex);
488
496
/* wait on placeholder mutex until we are awaken */
489
CAIRO_MUTEX_LOCK (scaled_font->mutex);
497
CAIRO_MUTEX_LOCK (placeholder_scaled_font->mutex);
491
499
/* ok, creation done. just clean up and back out */
492
CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
500
CAIRO_MUTEX_UNLOCK (placeholder_scaled_font->mutex);
493
501
CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex);
494
cairo_scaled_font_destroy (scaled_font);
502
cairo_scaled_font_destroy (placeholder_scaled_font);
497
505
/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/)
673
681
cairo_status_t status;
674
682
double font_scale_x, font_scale_y;
676
status = _cairo_matrix_compute_scale_factors (&scaled_font->font_matrix,
684
status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->font_matrix,
677
685
&font_scale_x, &font_scale_y,
764
772
_cairo_scaled_font_init_key (&key, font_face,
765
773
font_matrix, ctm, options);
768
while (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
769
(cairo_hash_entry_t**) &scaled_font))
771
if (!scaled_font->placeholder)
774
/* If the scaled font is being created (happens for user-font),
775
* just wait until it's done, then retry */
776
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font);
779
/* Return existing scaled_font if it exists in the hash table. */
782
/* If the original reference count is 0, then this font must have
783
* been found in font_map->holdovers, (which means this caching is
784
* actually working). So now we remove it from the holdovers
786
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
789
for (i = 0; i < font_map->num_holdovers; i++)
790
if (font_map->holdovers[i] == scaled_font)
792
assert (i < font_map->num_holdovers);
794
font_map->num_holdovers--;
795
memmove (&font_map->holdovers[i],
796
&font_map->holdovers[i+1],
797
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
799
/* reset any error status */
800
scaled_font->status = CAIRO_STATUS_SUCCESS;
774
scaled_font = font_map->mru_scaled_font;
775
if (scaled_font != NULL &&
776
scaled_font->hash_entry.hash == key.hash_entry.hash &&
777
_cairo_scaled_font_keys_equal (scaled_font, &key))
779
assert (! scaled_font->placeholder);
803
781
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
804
782
/* We increment the reference count manually here, (rather
814
792
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
815
793
scaled_font->hash_entry.hash = ZOMBIE;
797
while (_cairo_hash_table_lookup (font_map->hash_table, &key.hash_entry,
798
(cairo_hash_entry_t**) &scaled_font))
800
if (! scaled_font->placeholder)
803
/* If the scaled font is being created (happens for user-font),
804
* just wait until it's done, then retry */
805
_cairo_scaled_font_placeholder_wait_for_creation_to_finish (scaled_font);
808
/* Return existing scaled_font if it exists in the hash table. */
809
if (scaled_font != NULL) {
810
/* If the original reference count is 0, then this font must have
811
* been found in font_map->holdovers, (which means this caching is
812
* actually working). So now we remove it from the holdovers
814
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
817
for (i = 0; i < font_map->num_holdovers; i++)
818
if (font_map->holdovers[i] == scaled_font)
820
assert (i < font_map->num_holdovers);
822
font_map->num_holdovers--;
823
memmove (&font_map->holdovers[i],
824
&font_map->holdovers[i+1],
825
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
827
/* reset any error status */
828
scaled_font->status = CAIRO_STATUS_SUCCESS;
831
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
832
/* We increment the reference count manually here, (rather
833
* than calling into cairo_scaled_font_reference), since we
834
* must modify the reference count while our lock is still
837
old = font_map->mru_scaled_font;
838
font_map->mru_scaled_font = scaled_font;
839
/* increment reference count for the mru cache */
840
_cairo_reference_count_inc (&scaled_font->ref_count);
841
/* and increment for the returned reference */
842
_cairo_reference_count_inc (&scaled_font->ref_count);
843
_cairo_scaled_font_map_unlock ();
845
cairo_scaled_font_destroy (old);
850
/* the font has been put into an error status - abandon the cache */
851
_cairo_hash_table_remove (font_map->hash_table, &key.hash_entry);
852
scaled_font->hash_entry.hash = ZOMBIE;
818
856
/* Otherwise create it and insert it into the hash table. */
819
857
status = font_face->backend->scaled_font_create (font_face, font_matrix,
827
865
status = _cairo_hash_table_insert (font_map->hash_table,
828
866
&scaled_font->hash_entry);
867
if (status == CAIRO_STATUS_SUCCESS) {
868
old = font_map->mru_scaled_font;
869
font_map->mru_scaled_font = scaled_font;
870
_cairo_reference_count_inc (&scaled_font->ref_count);
829
873
_cairo_scaled_font_map_unlock ();
1279
1325
* @num_glyphs: pointer to number of glyphs
1280
1326
* @clusters: pointer to array of cluster mapping information to fill, or %NULL
1281
1327
* @num_clusters: pointer to number of clusters, or %NULL
1282
* @backward: pointer to whether the text to glyphs mapping goes backward, or
1328
* @cluster_flags: pointer to location to store cluster flags corresponding to the
1329
* output @clusters, or %NULL
1285
1331
* Converts UTF-8 text to an array of glyphs, optionally with cluster
1286
1332
* mapping, that can be used to render later using @scaled_font.
1294
1340
* after the call, the user is responsible for freeing the allocated glyph
1295
1341
* array using cairo_glyph_free().
1297
* If @clusters is not %NULL, @num_clusters and @backward should not be %NULL,
1343
* If @clusters is not %NULL, @num_clusters and @cluster_flags should not be %NULL,
1298
1344
* and cluster mapping will be computed.
1299
1345
* The semantics of how cluster array allocation works is similar to the glyph
1300
1346
* array. That is,
1316
1362
* int num_glyphs;
1317
1363
* cairo_text_cluster_t *clusters = NULL;
1318
1364
* int num_clusters;
1319
* cairo_bool_t backward;
1365
* cairo_text_cluster_flags_t cluster_flags;
1321
1367
* status = cairo_scaled_font_text_to_glyphs (scaled_font,
1323
1369
* utf8, utf8_len,
1324
1370
* &glyphs, &num_glyphs,
1325
* &clusters, &num_clusters,
1371
* &clusters, &num_clusters, &cluster_flags);
1328
1373
* if (status == CAIRO_STATUS_SUCCESS) {
1329
1374
* cairo_show_text_glyphs (cr,
1330
1375
* utf8, utf8_len,
1331
1376
* *glyphs, *num_glyphs,
1332
* *clusters, *num_clusters,
1377
* *clusters, *num_clusters, *cluster_flags);
1335
1379
* cairo_glyph_free (*glyphs);
1336
1380
* cairo_text_cluster_free (*clusters);
1368
1412
* cairo_text_cluster_t stack_clusters[40];
1369
1413
* cairo_text_cluster_t *clusters = stack_clusters;
1370
1414
* int num_clusters = sizeof (stack_clusters) / sizeof (stack_clusters[0]);
1371
* cairo_bool_t backward;
1415
* cairo_text_cluster_flags_t cluster_flags;
1373
1417
* status = cairo_scaled_font_text_to_glyphs (scaled_font,
1375
1419
* utf8, utf8_len,
1376
1420
* &glyphs, &num_glyphs,
1377
* &clusters, &num_clusters,
1421
* &clusters, &num_clusters, &cluster_flags);
1380
1423
* if (status == CAIRO_STATUS_SUCCESS) {
1381
1424
* cairo_show_text_glyphs (cr,
1382
1425
* utf8, utf8_len,
1383
1426
* *glyphs, *num_glyphs,
1384
* *clusters, *num_clusters,
1427
* *clusters, *num_clusters, *cluster_flags);
1387
1429
* if (glyphs != stack_glyphs)
1388
1430
* cairo_glyph_free (*glyphs);
1392
1434
* </programlisting></informalexample>
1394
* For details of how (@clusters, @num_clusters, and @backward map input
1436
* For details of how @clusters, @num_clusters, and @cluster_flags map input
1395
1437
* UTF-8 text to the output glyphs see cairo_show_text_glyphs().
1397
1439
* The output values can be readily passed to cairo_show_text_glyphs()
1444
1486
/* No NULLs for non-NULLs! */
1445
if ((utf8_len && utf8 == NULL) ||
1446
(clusters && num_clusters == NULL) ||
1447
(clusters && backward == NULL)) {
1487
if ((utf8_len && utf8 == NULL) ||
1488
(clusters && num_clusters == NULL) ||
1489
(clusters && cluster_flags == NULL)) {
1448
1490
status = CAIRO_STATUS_NULL_POINTER;
1980
2020
cairo_status_t status;
1981
2021
cairo_image_surface_t *a1_mask;
1982
unsigned char *row, *byte_ptr, byte;
2022
uint8_t *row, *byte_ptr, byte;
1983
2023
int rows, cols, bytes_per_row;
1985
2025
double xoff, yoff;
2000
2040
bytes_per_row = (a1_mask->width + 7) / 8;
2001
2041
for (y = 0, row = a1_mask->data, rows = a1_mask->height; rows; row += a1_mask->stride, rows--, y++) {
2002
for (x = 0, byte_ptr = row, cols = (a1_mask->width + 7) / 8; cols; byte_ptr++, cols--) {
2042
for (x = 0, byte_ptr = row, cols = bytes_per_row; cols; byte_ptr++, cols--) {
2003
2043
byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
2004
2044
for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
2005
2045
if (byte & (1 << bit)) {