From 9e7d87e78531157e6a6072650cf84e59d57133fa Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 29 Apr 2020 15:57:11 +0200 Subject: Add support for character mirroring and add functions for creating transformations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- libskrift_create_context.c | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) (limited to 'libskrift_create_context.c') diff --git a/libskrift_create_context.c b/libskrift_create_context.c index cf67826..1500b20 100644 --- a/libskrift_create_context.c +++ b/libskrift_create_context.c @@ -6,30 +6,47 @@ LIBSKRIFT_NO_AUTOKERNING) #define IMPLEMENTED_FLAGS (LIBSKRIFT_REMOVE_GAMMA |\ + LIBSKRIFT_MIRROR_CHARS |\ FORCED_FLAGS) /* libschrift does not add gamma, so not handling is required */ +#define TRANSFORMING_FLAGS (LIBSKRIFT_MIRROR_TEXT |\ + LIBSKRIFT_MIRROR_CHARS |\ + LIBSKRIFT_TRANSPOSE_TEXT |\ + LIBSKRIFT_TRANSPOSE_CHARS) + #define COPY_ARRAY(DEST_STRUCT, SRC_STRUCT, FIELD)\ memcpy((DEST_STRUCT).FIELD, (SRC_STRUCT).FIELD, sizeof((SRC_STRUCT).FIELD)) static const struct libskrift_rendering default_rendering = LIBSKRIFT_DEFAULT_RENDERING; +static void +multiply_matrices(const double a[restrict 6], const double b[restrict 6], double r[restrict 6]) +{ + r[0] = a[0] * b[0] + a[1] * b[3]; + r[1] = a[0] * b[1] + a[1] * b[4]; + r[2] = a[0] * b[2] + a[1] * b[5] + a[2]; + r[3] = a[3] * b[0] + a[4] * b[3]; + r[4] = a[3] * b[1] + a[4] * b[4]; + r[5] = a[3] * b[2] + a[4] * b[5] + a[5]; +} + static int transformation_hook(void *hook_data, double advance, double transform[6]) { LIBSKRIFT_CONTEXT *ctx = hook_data; - double r1c1b = ctx->rendering.char_transformation[0], r1c1a = transform[0]; - double r1c2b = ctx->rendering.char_transformation[1], r1c2a = transform[2]; - double r1c3b = ctx->rendering.char_transformation[2], r1c3a = transform[4]; - double r2c1b = ctx->rendering.char_transformation[3], r2c1a = transform[1]; - double r2c2b = ctx->rendering.char_transformation[4], r2c2a = transform[3]; - double r2c3b = ctx->rendering.char_transformation[5], r2c3a = transform[5]; - transform[0] = r1c1a * r1c1b + r1c2a * r2c1b; - transform[2] = r1c1a * r1c2b + r1c2a * r2c2b; - transform[4] = r1c1a * r1c3b + r1c2a * r2c3b + r1c3a; - transform[1] = r2c1a * r1c1b + r2c2a * r2c1b; - transform[3] = r2c1a * r1c2b + r2c2a * r2c2b; - transform[5] = r2c1a * r1c3b + r2c2a * r2c3b + r2c3a; - (void) advance; + double schrift[6] = {transform[0], transform[2], transform[4], + transform[1], transform[3], transform[5]}; + double m1[6] = {1, 0, 0, 0, 1, 0}, m2[6] = {1, 0, 0, 0, 1, 0}; + if (((ctx->rendering.flags / LIBSKRIFT_MIRROR_CHARS) ^ (ctx->rendering.flags / LIBSKRIFT_MIRROR_TEXT)) & 1) + multiply_matrices((double []){-1, 0, advance / schrift[0], 0, 1, 0}, m2, m1); + multiply_matrices(ctx->rendering.char_transformation, m1, m2); + multiply_matrices(schrift, m2, m1); + transform[0] = m1[0]; + transform[2] = m1[1]; + transform[4] = m1[2]; + transform[1] = m1[3]; + transform[3] = m1[4]; + transform[5] = m1[5]; return 0; } @@ -82,6 +99,7 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_ (*ctxp)->rendering.hinting = LIBSKRIFT_NONE; (*ctxp)->rendering.flags &= IMPLEMENTED_FLAGS; (*ctxp)->rendering.flags |= FORCED_FLAGS; + (*ctxp)->rendering.flags |= LIBSKRIFT_REMOVE_GAMMA; /* libschrift does not add gamma */ (*ctxp)->rendering.grid_fineness = 1; (*ctxp)->rendering.kerning = 0; (*ctxp)->rendering.interletter_spacing = 0; @@ -92,7 +110,8 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_ (*ctxp)->schrift_ctx.xScale = (*ctxp)->schrift_ctx.yScale; (*ctxp)->schrift_ctx.xScale *= (*ctxp)->rendering.horizontal_dpi / (*ctxp)->rendering.vertical_dpi; (*ctxp)->schrift_ctx.hook_data = (*ctxp); - if (fpclassify((*ctxp)->rendering.char_transformation[0] - 1) != FP_ZERO || + if (((*ctxp)->rendering.flags & TRANSFORMING_FLAGS) || + fpclassify((*ctxp)->rendering.char_transformation[0] - 1) != FP_ZERO || fpclassify((*ctxp)->rendering.char_transformation[1]) != FP_ZERO || fpclassify((*ctxp)->rendering.char_transformation[2]) != FP_ZERO || fpclassify((*ctxp)->rendering.char_transformation[3]) != FP_ZERO || -- cgit v1.2.3-70-g09d2