aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--README6
-rw-r--r--common.h3
-rw-r--r--demo.c2
-rw-r--r--libskrift.h11
-rw-r--r--libskrift_apply_glyph.c2
-rw-r--r--libskrift_create_context.c32
-rw-r--r--libskrift_draw_text.c29
-rw-r--r--libskrift_format_settings.c1
-rw-r--r--libskrift_get_cluster_glyph.c37
-rw-r--r--libskrift_merge_glyphs.c4
-rw-r--r--libskrift_open_font.c4
-rw-r--r--libskrift_open_font_at.c4
-rw-r--r--libskrift_open_font_fd.c3
14 files changed, 74 insertions, 66 deletions
diff --git a/LICENSE b/LICENSE
index 38e536c..c97d5c1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
ISC License
-© 2020 Mattias Andrée <maandree@kth.se>
+© 2020, 2021 Mattias Andrée <maandree@kth.se>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
diff --git a/README b/README
index 0067bc2..c34edbc 100644
--- a/README
+++ b/README
@@ -13,7 +13,7 @@ Currently implemented:
Subpixel rendering (RGB, BGR, both horizontal and vertical).
DPI support. (Points, inches, and millimeters can be
- exactly converted pixels.)
+ exactly converted to pixels.)
(Both horizonal and vertical resolution can be specified.)
Drawing coloured text with 3 primaries, alpha and opacity,
@@ -78,7 +78,7 @@ Things that require new features in libschrift
Out of scope:
- Bidirection text.
+ Bidirectional text.
Text justification.
@@ -89,3 +89,5 @@ Out of scope:
Underline, overline, strike-thought, ...
Superscript and subscript.
+
+ Mathematical formulae formating.
diff --git a/common.h b/common.h
index dc9bcbd..787ec68 100644
--- a/common.h
+++ b/common.h
@@ -19,6 +19,9 @@
#define LEN(ARR) (sizeof(ARR) / sizeof(*(ARR)))
+#define FLEXSTRUCTSIZE(STRUCT, FLEXARRAY, FLEXARRAY_LENGTH)\
+ (offsetof(STRUCT, FLEXARRAY) + (FLEXARRAY_LENGTH) * sizeof(*((STRUCT *)NULL)->FLEXARRAY))
+
struct libskrift_font {
SFT_Font *font;
void *memory_free;
diff --git a/demo.c b/demo.c
index 063721c..4920de1 100644
--- a/demo.c
+++ b/demo.c
@@ -54,7 +54,7 @@ main(void)
((uint8_t *)image.image)[i + 3] = 250U;
}
- if (libskrift_draw_text(ctx, "hello world", &colour, 0, 300, &image) < 0) {
+ if (libskrift_draw_text(ctx, "hello world", strlen("hello world"), &colour, 0, 300, &image) < 0) {
perror("libskrift_draw_text");
return -1;
}
diff --git a/libskrift.h b/libskrift.h
index d587294..fc99142 100644
--- a/libskrift.h
+++ b/libskrift.h
@@ -140,6 +140,7 @@ struct libskrift_glyph {
};
struct libskrift_saved_grapheme {
+ int have_saved;
libskrift_codepoint_t cp;
size_t len;
};
@@ -185,7 +186,7 @@ struct libskrift_colour {
.text_transformation = {1, 0, 0, 0, 1, 0},\
}
-#define LIBSKRIFT_NO_SAVED_GRAPHEME {0, 0}
+#define LIBSKRIFT_NO_SAVED_GRAPHEME {0, 0, 0}
#define LIBSKRIFT_PREMULTIPLY(OPACITY, ALPHA, RED, GREEN, BLUE)\
{(OPACITY),\
@@ -254,8 +255,8 @@ const struct libskrift_rendering *libskrift_get_rendering_settings(LIBSKRIFT_CON
_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__)))
int libskrift_get_grapheme_glyph(LIBSKRIFT_CONTEXT *, libskrift_codepoint_t, double, double, struct libskrift_glyph **);
-_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__(1, 2, 6))))
-ssize_t libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *, const char *, struct libskrift_saved_grapheme *,
+_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__(1, 2, 7))))
+ssize_t libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *, const char *, size_t, struct libskrift_saved_grapheme *,
double, double, struct libskrift_glyph **);
_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__)))
@@ -266,8 +267,8 @@ _LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__(1, 2, 6))))
int libskrift_apply_glyph(LIBSKRIFT_CONTEXT *, const struct libskrift_glyph *, const struct libskrift_colour *,
int16_t, int16_t, struct libskrift_image *);
-_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__(1, 2, 6))))
-int libskrift_draw_text(LIBSKRIFT_CONTEXT *, const char *, const struct libskrift_colour *,
+_LIBSKRIFT_GCC_ONLY(__attribute__((__nonnull__(1, 2, 7))))
+int libskrift_draw_text(LIBSKRIFT_CONTEXT *, const char *, size_t, const struct libskrift_colour *,
int16_t, int16_t, struct libskrift_image *);
diff --git a/libskrift_apply_glyph.c b/libskrift_apply_glyph.c
index 85e4bd2..3fc3fc5 100644
--- a/libskrift_apply_glyph.c
+++ b/libskrift_apply_glyph.c
@@ -95,7 +95,7 @@ libskrift_apply_glyph(LIBSKRIFT_CONTEXT *ctx, const struct libskrift_glyph *glyp
startc = (uint16_t)((int16_t)x1 - sx1);
startr = (uint16_t)((int16_t)y1 - sy1);
- /* Post-last pixel in glyph to draw*/
+ /* Post-last pixel in glyph to draw */
endc = (uint16_t)((int16_t)x2 - sx1);
endr = (uint16_t)((int16_t)y2 - sy1);
diff --git a/libskrift_create_context.c b/libskrift_create_context.c
index 18cf961..db6f8a4 100644
--- a/libskrift_create_context.c
+++ b/libskrift_create_context.c
@@ -71,7 +71,7 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_
}
}
- *ctxp = calloc(1, offsetof(LIBSKRIFT_CONTEXT, fonts) + nfonts * sizeof(*(*ctxp)->fonts));
+ *ctxp = calloc(1, FLEXSTRUCTSIZE(LIBSKRIFT_CONTEXT, fonts, nfonts));
if (!*ctxp)
return -1;
@@ -97,13 +97,13 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_
memcpy(&(*ctxp)->rendering, &default_rendering, sizeof(default_rendering));
}
- (*ctxp)->rendering.struct_version = LIBSKRIFT_RENDERING_STRUCT_VERSION;
- (*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.struct_version = LIBSKRIFT_RENDERING_STRUCT_VERSION;
+ (*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;
if (!(*ctxp)->rendering.smoothing)
(*ctxp)->rendering.smoothing = LIBSKRIFT_GREYSCALE;
@@ -113,17 +113,17 @@ libskrift_create_context(LIBSKRIFT_CONTEXT **ctxp, LIBSKRIFT_FONT **fonts, size_
(*ctxp)->schrift_ctx.hook_data = (*ctxp);
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 ||
+ fpclassify((*ctxp)->rendering.char_transformation[1]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.char_transformation[2]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.char_transformation[3]) != FP_ZERO ||
fpclassify((*ctxp)->rendering.char_transformation[4] - 1) != FP_ZERO ||
- fpclassify((*ctxp)->rendering.char_transformation[5]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.char_transformation[5]) != FP_ZERO ||
fpclassify((*ctxp)->rendering.text_transformation[0] - 1) != FP_ZERO ||
- fpclassify((*ctxp)->rendering.text_transformation[1]) != FP_ZERO ||
- fpclassify((*ctxp)->rendering.text_transformation[2]) != FP_ZERO ||
- fpclassify((*ctxp)->rendering.text_transformation[3]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.text_transformation[1]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.text_transformation[2]) != FP_ZERO ||
+ fpclassify((*ctxp)->rendering.text_transformation[3]) != FP_ZERO ||
fpclassify((*ctxp)->rendering.text_transformation[4] - 1) != FP_ZERO ||
- fpclassify((*ctxp)->rendering.text_transformation[5]) != FP_ZERO) {
+ 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];
diff --git a/libskrift_draw_text.c b/libskrift_draw_text.c
index 356468d..75645ba 100644
--- a/libskrift_draw_text.c
+++ b/libskrift_draw_text.c
@@ -2,45 +2,42 @@
#include "common.h"
static void
-reverse_text(const char *restrict text, char *restrict s, size_t off)
+reverse_text(const char *restrict text, size_t text_length, char *restrict s)
{
- size_t n;
- s[off] = '\0';
- for (; *text; text += n) {
- off -= n = grapheme_len(text);
+ size_t n, off = text_length;
+ for (; text_length; text += n, text_length -= n) {
+ off -= n = grapheme_bytelen(text);
memcpy(&s[off], text, n);
}
}
int
-libskrift_draw_text(LIBSKRIFT_CONTEXT *ctx, const char *text, const struct libskrift_colour *colour,
- int16_t x, int16_t y, struct libskrift_image *image)
+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;
ssize_t len;
- size_t n;
int r;
if (ctx->rendering.flags & LIBSKRIFT_MIRROR_TEXT) {
- n = strlen(text);
- if (n < 1024) {
- buffer = alloca(n + 1);
+ if (text_length < 1024) {
+ buffer = alloca(text_length + 1);
} else {
- buffer = malloc(n + 1);
+ buffer = malloc(text_length + 1);
if (!buffer)
return -1;
}
- reverse_text(text, buffer, n);
+ reverse_text(text, text_length, buffer);
text = buffer;
- if (n < 1024)
+ if (text_length < 1024)
buffer = NULL;
}
- for (; *text; text += len) {
- len = libskrift_get_cluster_glyph(ctx, text, &saved, xpos, ypos, &glyph);
+ 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;
diff --git a/libskrift_format_settings.c b/libskrift_format_settings.c
index aaa8255..fba2eed 100644
--- a/libskrift_format_settings.c
+++ b/libskrift_format_settings.c
@@ -32,5 +32,4 @@ const struct format_settings libskrift_format_settings[] = {
[LIBSKRIFT_RGB_LONG_DOUBLE] = {3, RGB, sizeof(long double)},
[LIBSKRIFT_ARGB_LONG_DOUBLE] = {3, ARGB, sizeof(long double)},
[LIBSKRIFT_RGBA_LONG_DOUBLE] = {3, RGBA, sizeof(long double)}
- /* REMEMBER that element count is specified in common.h */
};
diff --git a/libskrift_get_cluster_glyph.c b/libskrift_get_cluster_glyph.c
index e8d5724..fbc3a18 100644
--- a/libskrift_get_cluster_glyph.c
+++ b/libskrift_get_cluster_glyph.c
@@ -4,8 +4,8 @@
/* TODO try normalisation if not found, then try fallback fonts */
ssize_t
-libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, struct libskrift_saved_grapheme *saved,
- double x, double y, struct libskrift_glyph **glyphp)
+libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, size_t text_length,
+ struct libskrift_saved_grapheme *saved, double x, double y, struct libskrift_glyph **glyphp)
{
struct libskrift_glyph *glyph0, *glyph1, *glyph2;
uint32_t cp0, cp1;
@@ -14,36 +14,31 @@ libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, struct lib
*glyphp = NULL;
- if (saved && saved->cp) {
+ if (!text_length) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (saved && saved->have_saved) {
cp0 = saved->cp;
len = saved->len;
} else {
- len = grapheme_decode(text, &cp0);
- if (!len) {
- errno = EINVAL;
- return -1;
- }
+ len = grapheme_cp_decode(&cp0, (const void *)text, text_length);
}
if (libskrift_get_grapheme_glyph(ctx, cp0, x, y, &glyph0))
return -1;
x += glyph0->advance;
- for (; cp0; cp0 = cp1, len += r) {
- r = grapheme_decode(&text[len], &cp1);
- if (!r) {
- if (saved) {
- saved->cp = 0;
- saved->len = 0;
- }
- break;
- }
+ 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)) {
if (saved) {
+ saved->have_saved = 1;
saved->cp = cp1;
saved->len = r;
}
- break;
+ goto out;
}
if (libskrift_get_grapheme_glyph(ctx, cp1, x, y, &glyph1)) {
@@ -62,7 +57,13 @@ libskrift_get_cluster_glyph(LIBSKRIFT_CONTEXT *ctx, const char *text, struct lib
free(glyph1);
glyph0 = glyph2;
}
+ if (saved) {
+ saved->have_saved = 0;
+ saved->cp = 0;
+ saved->len = 0;
+ }
+out:
*glyphp = glyph0;
return (ssize_t)len;
diff --git a/libskrift_merge_glyphs.c b/libskrift_merge_glyphs.c
index 4df6f7a..820d0d4 100644
--- a/libskrift_merge_glyphs.c
+++ b/libskrift_merge_glyphs.c
@@ -20,7 +20,7 @@ libskrift_merge_glyphs(LIBSKRIFT_CONTEXT *ctx, const struct libskrift_glyph *gly
glyph2 = t;
}
if (!(glyph2->width | glyph2->height)) {
- size = offsetof(struct libskrift_glyph, image) + glyph1->size;
+ size = FLEXSTRUCTSIZE(struct libskrift_glyph, image, glyph1->size);
*glyphp = calloc(1, size);
if (!*glyphp)
return -1;
@@ -47,7 +47,7 @@ libskrift_merge_glyphs(LIBSKRIFT_CONTEXT *ctx, const struct libskrift_glyph *gly
size *= width = (uint16_t)(x2 - x1);
size *= height = (uint16_t)(y2 - y1);
- *glyphp = calloc(1, offsetof(struct libskrift_glyph, image) + size);
+ *glyphp = calloc(1, FLEXSTRUCTSIZE(struct libskrift_glyph, image, size));
if (!*glyphp)
return -1;
diff --git a/libskrift_open_font.c b/libskrift_open_font.c
index 1eb8ff9..d829a66 100644
--- a/libskrift_open_font.c
+++ b/libskrift_open_font.c
@@ -43,8 +43,8 @@ libskrift_open_font(LIBSKRIFT_FONT **fontp, FILE *fp)
return -1;
}
- (*fontp)->memory_free = mem;
- (*fontp)->memory_size = size;
+ (*fontp)->memory_free = mem;
+ (*fontp)->memory_size = size;
return 0;
}
diff --git a/libskrift_open_font_at.c b/libskrift_open_font_at.c
index 2927dea..8745991 100644
--- a/libskrift_open_font_at.c
+++ b/libskrift_open_font_at.c
@@ -4,7 +4,7 @@
int
libskrift_open_font_at(LIBSKRIFT_FONT **fontp, int dirfd, const char *path)
{
- int fd, ret;
+ int fd, ret, saved_errno;
if (!*path) {
return libskrift_open_font_fd(fontp, dirfd);
} else {
@@ -12,7 +12,9 @@ libskrift_open_font_at(LIBSKRIFT_FONT **fontp, int dirfd, const char *path)
if (fd < 0)
return -1;
ret = libskrift_open_font_fd(fontp, fd);
+ saved_errno = errno;
close(fd);
+ errno = saved_errno;
return ret;
}
}
diff --git a/libskrift_open_font_fd.c b/libskrift_open_font_fd.c
index c00422e..e134cd8 100644
--- a/libskrift_open_font_fd.c
+++ b/libskrift_open_font_fd.c
@@ -13,6 +13,7 @@ libskrift_open_font_fd(LIBSKRIFT_FONT **fontp, int fd)
saved_errno = errno;
if (fstat(fd, &st) < 0 || !st.st_size || !S_ISREG(st.st_mode)) {
+ fallback:
for (;;) {
if (off + 2048 > size) {
size += 8192;
@@ -39,6 +40,8 @@ libskrift_open_font_fd(LIBSKRIFT_FONT **fontp, int fd)
errno = saved_errno;
} else {
mem = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (mem == MAP_FAILED || !mem)
+ goto fallback;
size = (size_t)st.st_size;
mmapped = 1;
}