/* See LICENSE file for copyright and license details. */ #include "common.h" static void reverse_text(const char *restrict text, size_t text_length, char *restrict s) { size_t n, off = text_length; for (; text_length; text += n, text_length -= n) { off -= n = grapheme_next_character_break(text, text_length); memcpy(&s[off], text, n); } } int libskrift_draw_text(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t text_length, const struct libskrift_colour *colour, int16_t x, int16_t y, struct libskrift_image *image) { struct libskrift_saved_grapheme saved = LIBSKRIFT_NO_SAVED_GRAPHEME; struct libskrift_glyph *glyph; char *buffer = NULL; double xpos = 0, ypos = 0, advance; ssize_t len; int r; if (ctx->rendering.flags & LIBSKRIFT_MIRROR_TEXT) { if (text_length < 1024) { buffer = alloca(text_length + 1); } else { buffer = malloc(text_length + 1); if (!buffer) return -1; } reverse_text(text, text_length, buffer); text = buffer; if (text_length < 1024) buffer = NULL; } for (; text_length; text += len, text_length -= (size_t)len) { len = libskrift_get_cluster_glyph(ctx, text, text_length, &saved, xpos, ypos, &glyph); if (len < 0) { free(buffer); return -1; } r = libskrift_apply_glyph(ctx, glyph, colour, x, y, image); advance = glyph->advance * ctx->char_x_advancement; advance += ctx->rendering.interletter_spacing; xpos += advance * ctx->text_x_advancement; ypos += advance * ctx->text_y_advancement; free(glyph); if (r) { free(buffer); return -1; } } free(buffer); return 0; }