static cairo_status_t _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators, const char *utf8, int utf8_len) { uint16_t *utf16; int utf16_len; cairo_status_t status; int i; _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff"); if (utf8_len) { status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len); if (unlikely (status)) return status; for (i = 0; i < utf16_len; i++) { _cairo_output_stream_printf (pdf_operators->stream, "%04x", (int) (utf16[i])); } free (utf16); } _cairo_output_stream_printf (pdf_operators->stream, "> >> BDC\n"); return _cairo_output_stream_get_status (pdf_operators->stream); }
cairo_int_status_t _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset) { unsigned int i; cairo_hash_table_t *names; cairo_string_entry_t key, *entry; char buf[30]; char *utf8; uint16_t *utf16; int utf16_len; cairo_status_t status = CAIRO_STATUS_SUCCESS; names = _cairo_hash_table_create (_cairo_string_equal); if (unlikely (names == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *)); if (unlikely (subset->glyph_names == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } i = 0; if (! subset->is_scaled) { subset->glyph_names[0] = strdup (".notdef"); if (unlikely (subset->glyph_names[0] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[0], &entry); if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } i++; } for (; i < subset->num_glyphs; i++) { utf8 = subset->utf8[i]; utf16 = NULL; utf16_len = 0; if (utf8 && *utf8) { status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); if (unlikely (status)) goto CLEANUP_HASH; } if (utf16_len == 1) { int ch = _cairo_unicode_to_winansi (utf16[0]); if (ch > 0 && _cairo_winansi_to_glyphname (ch)) strncpy (buf, _cairo_winansi_to_glyphname (ch), sizeof (buf)); else snprintf (buf, sizeof (buf), "uni%04X", (int) utf16[0]); _cairo_string_init_key (&key, buf); entry = _cairo_hash_table_lookup (names, &key.base); if (entry != NULL) snprintf (buf, sizeof (buf), "g%d", i); } else { snprintf (buf, sizeof (buf), "g%d", i); } free (utf16); subset->glyph_names[i] = strdup (buf); if (unlikely (subset->glyph_names[i] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[i], &entry); if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } } CLEANUP_HASH: _cairo_hash_table_foreach (names, _pluck_entry, names); _cairo_hash_table_destroy (names); if (likely (status == CAIRO_STATUS_SUCCESS)) return CAIRO_STATUS_SUCCESS; if (subset->glyph_names != NULL) { for (i = 0; i < subset->num_glyphs; i++) { free (subset->glyph_names[i]); } free (subset->glyph_names); subset->glyph_names = NULL; } return status; }
static cairo_status_t _cairo_atsui_font_text_to_glyphs(void *abstract_font, const char *utf8, cairo_glyph_t **glyphs, int *num_glyphs) { cairo_atsui_font_t *font = abstract_font; size_t i; OSStatus err; ATSUTextLayout textLayout; ATSLayoutRecord *layoutRecords; ItemCount glyphCount; int charCount; UniChar *theText; cairo_status_t status; // liberal estimate of size charCount = strlen(utf8); if (charCount == 0) { *glyphs = NULL; *num_glyphs = 0; return CAIRO_STATUS_SUCCESS; } status = _cairo_utf8_to_utf16 (utf8, -1, &theText, &charCount); if (status) return status; err = ATSUCreateTextLayout(&textLayout); err = ATSUSetTextPointerLocation(textLayout, theText, 0, charCount, charCount); // Set the style for all of the text err = ATSUSetRunStyle(textLayout, font->unscaled_style, kATSUFromTextBeginning, kATSUToTextEnd); // Get the glyphs from the text layout object err = ATSUDirectGetLayoutDataArrayPtrFromTextLayout(textLayout, 0, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void *) &layoutRecords, &glyphCount); *num_glyphs = glyphCount - 1; *glyphs = (cairo_glyph_t *) malloc(*num_glyphs * (sizeof(cairo_glyph_t))); if (*glyphs == NULL) { return CAIRO_STATUS_NO_MEMORY; } for (i = 0; i < *num_glyphs; i++) { (*glyphs)[i].index = layoutRecords[i].glyphID; (*glyphs)[i].x = FixedToFloat(layoutRecords[i].realPos); (*glyphs)[i].y = 0; } free(theText); ATSUDirectReleaseLayoutDataArrayPtr(NULL, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void *) &layoutRecords); ATSUDisposeTextLayout(textLayout); return CAIRO_STATUS_SUCCESS; }