aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-08-05 20:53:28 +0200
committerMattias Andrée <maandree@kth.se>2021-08-05 20:53:28 +0200
commita5fe9dab3f68668e3bc31326447139b7446edbc7 (patch)
tree5490cf70dacbf27406817bf759cecd61f7402219
parentmake demo flexible + minor fixes (diff)
downloadlibskrift-a5fe9dab3f68668e3bc31326447139b7446edbc7.tar.gz
libskrift-a5fe9dab3f68668e3bc31326447139b7446edbc7.tar.bz2
libskrift-a5fe9dab3f68668e3bc31326447139b7446edbc7.tar.xz
Improvements for character transformations
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--common.h6
-rw-r--r--demo.c107
-rw-r--r--libskrift_create_context.c12
-rw-r--r--libskrift_draw_text.c8
-rw-r--r--libskrift_get_cluster_glyph.c6
-rw-r--r--libskrift_get_grapheme_glyph.c2
6 files changed, 78 insertions, 63 deletions
diff --git a/common.h b/common.h
index 787ec68..d8c4a56 100644
--- a/common.h
+++ b/common.h
@@ -36,8 +36,10 @@ struct libskrift_context {
char subpixel_horizontally;
char subpixel_vertically;
char subpixel_bgr;
- double x_advancement;
- double y_advancement;
+ double char_x_advancement;
+ double char_y_advancement;
+ double text_x_advancement;
+ double text_y_advancement;
double transformation[6];
size_t nfonts;
LIBSKRIFT_FONT *fonts[];
diff --git a/demo.c b/demo.c
index c1a6488..e7d4eec 100644
--- a/demo.c
+++ b/demo.c
@@ -19,6 +19,7 @@ USAGE("[-b background-colour] [-f foreground-colour] [-a opacity] [-t character-
"[-S smoothing-method[:subpixel-order]] [-H hiniting] [-o flags] ... [-s font-size] [-F font-file] "
"[-D dpi-x:dpi-y | -D dpi] [-w width] [-h height] [-x x-position] [-y y-position] [text]");
+
static uint8_t
decode_hexbyte(char hi, char lo)
{
@@ -28,6 +29,7 @@ decode_hexbyte(char hi, char lo)
return (uint8_t)ret;
}
+
static void
parse_colour(const char *s, uint8_t *redp, uint8_t *greenp, uint8_t *bluep, uint8_t *alphap)
{
@@ -67,6 +69,7 @@ invalid:
exit(1);
}
+
_LIBSKRIFT_GCC_ONLY(__attribute__((__pure__)))
static uint16_t
parse_uint16(const char *s)
@@ -84,6 +87,7 @@ parse_uint16(const char *s)
return ret;
}
+
_LIBSKRIFT_GCC_ONLY(__attribute__((__pure__)))
static int16_t
parse_int16(const char *s, const char **end)
@@ -111,6 +115,7 @@ parse_int16(const char *s, const char **end)
return ret;
}
+
static void
parse_transformation(char *s, double matrix[6])
{
@@ -277,6 +282,26 @@ parse_transformation(char *s, double matrix[6])
#undef S0
}
+
+static double
+apply_unit(double size, const char *unit, const struct libskrift_rendering *rendering, const char *unit_for)
+{
+ if (!strcmp(unit, "px"))
+ return size;
+ if (!strcmp(unit, "pt"))
+ return libskrift_points_to_pixels(size, rendering);
+ if (!strcmp(unit, "in"))
+ return libskrift_inches_to_pixels(size, rendering);
+ if (!strcmp(unit, "mm"))
+ return libskrift_millimeters_to_pixels(size, rendering);
+ if (!strcmp(unit, "cm"))
+ return libskrift_millimeters_to_pixels(size * 10, rendering);
+
+ fprintf(stderr, "%s: valid %s units are: 'px', 'pt', 'in', 'mm', 'cm'", argv0, unit_for);
+ exit(1);
+}
+
+
int
main(int argc, char *argv[])
{
@@ -289,7 +314,8 @@ main(int argc, char *argv[])
double font_size = 72;
const char *font_size_unit = "pt";
const char *x_unit = "", *y_unit = "";
- double height, opacity = .80f, xf, yf;
+ const char *kerning_unit = "", *interletter_spacing_unit = "";
+ double height, opacity = .80f, f;
size_t size, i;
char *end, *arg;
const char *text = TEST_TEXT;
@@ -441,15 +467,17 @@ main(int argc, char *argv[])
case 'k':
errno = 0;
rendering.kerning = strtod(ARG(), &end);
- if (errno || *end)
+ if (errno)
usage();
+ kerning_unit = end;
break;
case 'i':
errno = 0;
rendering.interletter_spacing = strtod(ARG(), &end);
- if (errno || *end)
+ if (errno)
usage();
+ interletter_spacing_unit = end;
break;
case 'g':
@@ -562,64 +590,41 @@ main(int argc, char *argv[])
return 1;
}
+ if (*x_unit && strcmp(x_unit, "px")) {
+ f = (double)x;
+ f = apply_unit(f, x_unit, &rendering, "position");
+ x = (int16_t)f;
+ }
+
+ if (*y_unit && strcmp(y_unit, "px")) {
+ f = (double)y;
+ f = apply_unit(f, y_unit, &rendering, "position");
+ y = (int16_t)f;
+ }
+
+ if (*kerning_unit && strcmp(kerning_unit, "px")) {
+ f = rendering.kerning;
+ f = apply_unit(f, kerning_unit, &rendering, "spacing");
+ rendering.kerning = f;
+ }
+
+ if (*interletter_spacing_unit && strcmp(interletter_spacing_unit, "px")) {
+ f = rendering.interletter_spacing;
+ f = apply_unit(f, interletter_spacing_unit, &rendering, "spacing");
+ rendering.interletter_spacing = f;
+ }
+
if (libskrift_open_font_file(&font, font_file)) {
perror("libskrift_open_font_file");
return 1;
}
- if (!strcmp(font_size_unit, "pt")) {
- height = libskrift_points_to_pixels(font_size, &rendering);
- } else if (!strcmp(font_size_unit, "px")) {
- height = font_size;
- } else if (!strcmp(font_size_unit, "in")) {
- height = libskrift_inches_to_pixels(font_size, &rendering);
- } else if (!strcmp(font_size_unit, "mm")) {
- height = libskrift_millimeters_to_pixels(font_size, &rendering);
- } else if (!strcmp(font_size_unit, "cm")) {
- height = libskrift_millimeters_to_pixels(font_size * 10, &rendering);
- } else {
- fprintf(stderr, "%s: valid font size units are: 'pt', 'px', 'in', 'mm', 'cm'", argv0);
- return 1;
- }
+ height = apply_unit(font_size, font_size_unit, &rendering, "font size");
if (libskrift_create_context(&ctx, &font, 1, height, &rendering, NULL)) {
perror("libskrift_create_context");
return 1;
}
libskrift_close_font(font);
- if (*x_unit && strcmp(x_unit, "px")) {
- xf = (double)x;
- if (!strcmp(x_unit, "pt")) {
- xf = (int16_t)libskrift_points_to_pixels(xf, &rendering);
- } else if (!strcmp(x_unit, "in")) {
- xf = (int16_t)libskrift_inches_to_pixels(xf, &rendering);
- } else if (!strcmp(x_unit, "mm")) {
- xf = (int16_t)libskrift_millimeters_to_pixels(xf, &rendering);
- } else if (!strcmp(x_unit, "cm")) {
- xf = (int16_t)libskrift_millimeters_to_pixels(xf * 10, &rendering);
- } else {
- fprintf(stderr, "%s: valid position units are: 'pt', 'px', 'in', 'mm', 'cm'", argv0);
- return 1;
- }
- x = (int16_t)xf;
- }
-
- if (*y_unit && strcmp(y_unit, "px")) {
- yf = (double)y;
- if (!strcmp(y_unit, "pt")) {
- yf = libskrift_points_to_pixels(yf, &rendering);
- } else if (!strcmp(y_unit, "in")) {
- yf = libskrift_inches_to_pixels(yf, &rendering);
- } else if (!strcmp(y_unit, "mm")) {
- yf = libskrift_millimeters_to_pixels(yf, &rendering);
- } else if (!strcmp(y_unit, "cm")) {
- yf = libskrift_millimeters_to_pixels(yf * 10, &rendering);
- } else {
- fprintf(stderr, "%s: valid position units are: 'pt', 'px', 'in', 'mm', 'cm'", argv0);
- return 1;
- }
- y = (int16_t)yf;
- }
-
size = 4;
size *= (size_t)image.width;
size *= (size_t)image.height;
diff --git a/libskrift_create_context.c b/libskrift_create_context.c
index db6f8a4..a1d01e0 100644
--- a/libskrift_create_context.c
+++ b/libskrift_create_context.c
@@ -77,8 +77,10 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_
(*ctxp)->schrift_ctx.font = fonts[0]->font;
(*ctxp)->schrift_ctx.yScale = height;
- (*ctxp)->x_advancement = 1;
- (*ctxp)->y_advancement = 0;
+ (*ctxp)->char_x_advancement = 1;
+ (*ctxp)->char_y_advancement = 0;
+ (*ctxp)->text_x_advancement = 1;
+ (*ctxp)->text_y_advancement = 0;
(*ctxp)->nfonts = nfonts;
for (i = 0; i < nfonts; i++) {
(*ctxp)->fonts[i] = fonts[i];
@@ -126,8 +128,10 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_
fpclassify((*ctxp)->rendering.text_transformation[5]) != FP_ZERO) {
memcpy((*ctxp)->transformation, (*ctxp)->rendering.char_transformation, sizeof((*ctxp)->transformation));
libskrift_add_transformation((*ctxp)->transformation, (*ctxp)->rendering.text_transformation);
- (*ctxp)->x_advancement = (*ctxp)->rendering.text_transformation[0];
- (*ctxp)->y_advancement = (*ctxp)->rendering.text_transformation[3];
+ (*ctxp)->char_x_advancement = (*ctxp)->rendering.char_transformation[0];
+ (*ctxp)->char_y_advancement = (*ctxp)->rendering.char_transformation[3];
+ (*ctxp)->text_x_advancement = (*ctxp)->rendering.text_transformation[0];
+ (*ctxp)->text_y_advancement = (*ctxp)->rendering.text_transformation[3];
(*ctxp)->schrift_ctx.transformation_hook = transformation_hook;
}
diff --git a/libskrift_draw_text.c b/libskrift_draw_text.c
index 75645ba..e827159 100644
--- a/libskrift_draw_text.c
+++ b/libskrift_draw_text.c
@@ -18,7 +18,7 @@ libskrift_draw_text(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t text_length
struct libskrift_saved_grapheme saved = LIBSKRIFT_NO_SAVED_GRAPHEME;
struct libskrift_glyph *glyph;
char *buffer = NULL;
- double xpos = 0, ypos = 0;
+ double xpos = 0, ypos = 0, advance;
ssize_t len;
int r;
@@ -44,8 +44,10 @@ libskrift_draw_text(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t text_length
}
r = libskrift_apply_glyph(ctx, glyph, colour, x, y, image);
- xpos += (glyph->advance + ctx->rendering.interletter_spacing) * ctx->x_advancement;
- ypos += (glyph->advance + ctx->rendering.interletter_spacing) * ctx->y_advancement;
+ 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);
diff --git a/libskrift_get_cluster_glyph.c b/libskrift_get_cluster_glyph.c
index fbc3a18..6b3abaa 100644
--- a/libskrift_get_cluster_glyph.c
+++ b/libskrift_get_cluster_glyph.c
@@ -29,7 +29,8 @@ libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t tex
if (libskrift_get_grapheme_glyph(ctx, cp0, x, y, &glyph0))
return -1;
- x += glyph0->advance;
+ x += glyph0->advance * ctx->char_x_advancement;
+ y += glyph0->advance * ctx->char_y_advancement;
for (; len < text_length; cp0 = cp1, len += r) {
r = grapheme_cp_decode(&cp1, (const void *)&text[len], text_length - len);
if (grapheme_boundary(cp0, cp1, &state)) {
@@ -45,7 +46,8 @@ libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t tex
free(glyph0);
return -1;
}
- x += glyph1->advance;
+ x += glyph1->advance * ctx->char_x_advancement;
+ y += glyph1->advance * ctx->char_y_advancement;
if (libskrift_merge_glyphs(ctx, glyph0, glyph1, &glyph2)) {
free(glyph0);
diff --git a/libskrift_get_grapheme_glyph.c b/libskrift_get_grapheme_glyph.c
index fa7a8c5..515e81d 100644
--- a/libskrift_get_grapheme_glyph.c
+++ b/libskrift_get_grapheme_glyph.c
@@ -38,7 +38,7 @@ libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *ctx, libskrift_codepoint_t codep
height = (uint16_t)(sft_chr.height + top + bottom) / vmul;
size *= (size_t)width * (size_t)height;
- *glyphp = malloc(offsetof(struct libskrift_glyph, image) + size);
+ *glyphp = malloc(FLEXSTRUCTSIZE(struct libskrift_glyph, image, size));
if (!*glyphp) {
free(sft_chr.image);
return -1;