text: Add methods for rasterizing single glyphs

This commit is contained in:
K. Lange 2022-08-22 12:28:39 +09:00
parent 89910dc2f2
commit d7f73b3970
2 changed files with 82 additions and 3 deletions

View File

@ -1,14 +1,30 @@
#pragma once #pragma once
/**
* @file toaru/text.h
* @brief TrueType glyph rasterizer.
*
* Exposed API for the TrueType renderer.
*/
#include <stdint.h> #include <stdint.h>
/* Methods for loading fonts */
extern struct TT_Font * tt_font_from_file(const char * fileName); extern struct TT_Font * tt_font_from_file(const char * fileName);
extern struct TT_Font * tt_font_from_shm(const char * identifier); extern struct TT_Font * tt_font_from_shm(const char * identifier);
extern int tt_glyph_for_codepoint(struct TT_Font * font, unsigned int codepoint);
extern void tt_draw_glyph(gfx_context_t * ctx, struct TT_Font * font, int x_offset, int y_offset, unsigned int glyph, uint32_t color); /* Methods for changing font sizes */
extern void tt_set_size(struct TT_Font * font, float sizeInEm); extern void tt_set_size(struct TT_Font * font, float sizeInEm);
extern void tt_set_size_px(struct TT_Font * font, float sizeInPx); extern void tt_set_size_px(struct TT_Font * font, float sizeInPx);
/* Methods for dealing with glyphs */
extern void tt_draw_glyph(gfx_context_t * ctx, struct TT_Font * font, int x_offset, int y_offset, unsigned int glyph, uint32_t color);
extern int tt_glyph_for_codepoint(struct TT_Font * font, unsigned int codepoint);
extern int tt_xadvance_for_glyph(struct TT_Font * font, unsigned int ind); extern int tt_xadvance_for_glyph(struct TT_Font * font, unsigned int ind);
extern float tt_glyph_width(struct TT_Font * font, unsigned int glyph);
extern sprite_t * tt_bake_glyph(struct TT_Font * font, unsigned int glyph, uint32_t color, int *_x, int *_y);
/* Convenience functions for dealing with whole strings */
extern int tt_string_width(struct TT_Font * font, const char * s); extern int tt_string_width(struct TT_Font * font, const char * s);
extern int tt_string_width_int(struct TT_Font * font, const char * s);
extern int tt_draw_string(gfx_context_t * ctx, struct TT_Font * font, int x, int y, const char * s, uint32_t color); extern int tt_draw_string(gfx_context_t * ctx, struct TT_Font * font, int x, int y, const char * s, uint32_t color);
extern void tt_draw_string_shadow(gfx_context_t * ctx, struct TT_Font * font, char * string, int font_size, int left, int top, uint32_t text_color, uint32_t shadow_color, int blur); extern void tt_draw_string_shadow(gfx_context_t * ctx, struct TT_Font * font, char * string, int font_size, int left, int top, uint32_t text_color, uint32_t shadow_color, int blur);

View File

@ -682,6 +682,50 @@ static struct TT_Contour * tt_draw_glyph_into(struct TT_Contour * contour, struc
return contour; return contour;
} }
sprite_t * tt_bake_glyph(struct TT_Font * font, unsigned int glyph, uint32_t color, int *_x, int *_y) {
struct TT_Contour * contour = tt_contour_start(0, 0);
contour = tt_draw_glyph_into(contour,font,100,100,glyph);
if (!contour->edgeCount) {
*_x = 0;
*_y = 0;
free(contour);
return NULL;
}
/* Calculate bounds to render a sprite */
struct TT_Shape * shape = tt_contour_finish(contour);
int width = shape->lastX - shape->startX + 2;
int height = shape->lastY - shape->startY + 2;
int off_x = shape->startX - 2; shape->startX -= off_x; shape->lastX -= off_x;
int off_y = shape->startY - 2; shape->startY -= off_y; shape->lastY -= off_y;
/* Adjust the entire shape */
for (size_t i = 0; i < shape->edgeCount; ++i) {
shape->edges[i].start.x -= off_x;
shape->edges[i].end.x -= off_x;
shape->edges[i].start.y -= off_y;
shape->edges[i].end.y -= off_y;
}
*_x = off_x - 100;
*_y = off_y - 100;
/* Create sprite */
sprite_t * out = create_sprite(width,height,ALPHA_EMBEDDED);
gfx_context_t * ctx = init_graphics_sprite(out);
/* Fill to clear */
draw_fill(ctx, 0);
tt_path_paint(ctx, shape, color);
free(ctx);
free(shape);
free(contour);
return out;
}
void tt_draw_glyph(gfx_context_t * ctx, struct TT_Font * font, int x, int y, unsigned int glyph, uint32_t color) { void tt_draw_glyph(gfx_context_t * ctx, struct TT_Font * font, int x, int y, unsigned int glyph, uint32_t color) {
struct TT_Contour * contour = tt_contour_start(0, 0); struct TT_Contour * contour = tt_contour_start(0, 0);
contour = tt_draw_glyph_into(contour,font,x,y,glyph); contour = tt_draw_glyph_into(contour,font,x,y,glyph);
@ -708,6 +752,25 @@ int tt_string_width(struct TT_Font * font, const char * s) {
return x_offset; return x_offset;
} }
int tt_string_width_int(struct TT_Font * font, const char * s) {
int x_offset = 0;
uint32_t cp = 0;
uint32_t istate = 0;
for (const unsigned char * c = (const unsigned char*)s; *c; ++c) {
if (!decode(&istate, &cp, *c)) {
unsigned int glyph = tt_glyph_for_codepoint(font, cp);
x_offset += tt_xadvance_for_glyph(font, glyph) * font->scale;
}
}
return x_offset;
}
float tt_glyph_width(struct TT_Font * font, unsigned int glyph) {
return tt_xadvance_for_glyph(font, glyph) * font->scale;
}
int tt_draw_string(gfx_context_t * ctx, struct TT_Font * font, int x, int y, const char * s, uint32_t color) { int tt_draw_string(gfx_context_t * ctx, struct TT_Font * font, int x, int y, const char * s, uint32_t color) {
struct TT_Contour * contour = tt_contour_start(0, 0); struct TT_Contour * contour = tt_contour_start(0, 0);