aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-27 23:12:16 +0100
committereunhhu <[email protected]>2026-09-27 23:12:16 +0100
commit0d9d4c50bbd4a33a309ccb498b6bc55509c1dfed (patch)
treefea456a0da127cb40897ecf29191d5fb8f777347
parent7b93a66dbffaf2b20b0a1925786f56db54066c9b (diff)
downloadvega-0d9d4c50bbd4a33a309ccb498b6bc55509c1dfed.tar.gz
vega-0d9d4c50bbd4a33a309ccb498b6bc55509c1dfed.zip
Centre a wide character's glyph in its two cells
A Hangul or CJK glyph is one em across, less than two cells of a monospace Latin font (1.2 em for DejaVu Sans Mono), and was drawn from the left of its cells, so syllables stood apart unevenly. A cached glyph now keeps its advance in pixels, and a wide character's glyph is drawn centred in its two cells.
-rw-r--r--surfaces/pixels.c6
-rw-r--r--symbols/symbols.c2
-rw-r--r--symbols/symbols.h3
3 files changed, 8 insertions, 3 deletions
diff --git a/surfaces/pixels.c b/surfaces/pixels.c
index f671143..304e96d 100644
--- a/surfaces/pixels.c
+++ b/surfaces/pixels.c
@@ -86,8 +86,12 @@ void vega_pixels(const VegaGrid *grid, VegaFace *face, uint32_t *out, size_t str
int x = (int)c * face->cell_width, y = (int)r * face->cell_height;
const VegaBitmap *glyph = vega_glyph(face->glyphs, cell->ch);
unsigned cells = vega_width(cell->ch) == 2 ? 2 : 1;
+ /* A wide character's glyph is centred in its two cells: a CJK font's full width is
+ * less than two cells of a monospace Latin font. */
+ int centred = glyph && cells == 2 && glyph->advance < 2 * face->cell_width
+ ? (2 * face->cell_width - glyph->advance) / 2 : 0;
if (!glyph) missing(out, stride, x, y, face->cell_width * (int)cells, face->cell_height, width, color);
- else draw(out, stride, width, height, glyph, x, y + face->baseline, color);
+ else draw(out, stride, width, height, glyph, x + centred, y + face->baseline, color);
if (cell->mark && (glyph = vega_glyph(face->glyphs, cell->mark)))
draw(out, stride, width, height, glyph, x, y + face->baseline, color);
}
diff --git a/symbols/symbols.c b/symbols/symbols.c
index f00639a..2ee5d5e 100644
--- a/symbols/symbols.c
+++ b/symbols/symbols.c
@@ -237,7 +237,7 @@ const VegaBitmap *vega_glyph(VegaGlyphs *glyphs, uint32_t code) {
if (pixels)
vega_symbol_raster(glyphs->symbols, &symbol, glyphs->scale, place.left / glyphs->scale, place.top / glyphs->scale,
place.width, place.height, pixels, (size_t)place.width);
- slot->bitmap = (VegaBitmap){place, pixels};
+ slot->bitmap = (VegaBitmap){place, pixels, (int)lroundf(symbol.advance * glyphs->scale)};
return &slot->bitmap;
}
diff --git a/symbols/symbols.h b/symbols/symbols.h
index 0af3412..32f48d0 100644
--- a/symbols/symbols.h
+++ b/symbols/symbols.h
@@ -62,7 +62,8 @@ void vega_symbol_raster(const VegaSymbols *, const VegaSymbol *, double scale, d
/* Symbols drawn once at one scale and kept, for surfaces that compose them
* on the CPU: each the first time it is asked for. */
-typedef struct { VegaPlace place; const unsigned char *pixels; } VegaBitmap; /* pixels: place.width per row */
+/* pixels: place.width per row; advance: how far the pen moves after it, in whole pixels */
+typedef struct { VegaPlace place; const unsigned char *pixels; int advance; } VegaBitmap;
typedef struct VegaGlyphs VegaGlyphs;
VegaGlyphs *vega_glyphs_open(const VegaSymbols *, float scale);
/* The bitmap of code, or NULL when the file has no such symbol. */