aboutsummaryrefslogtreecommitdiffstats
path: root/text/layout.h
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-28 15:52:13 +0100
committereunhhu <[email protected]>2026-09-28 15:52:13 +0100
commita4ca275ad1b5edc15474407e2852f8fe9abaac4e (patch)
treef854692c7906627054a6b6ce98d8646bd678cb48 /text/layout.h
parent43a63f5aab95bf5fdfc4bce70286802854f7a07a (diff)
downloadvega-a4ca275ad1b5edc15474407e2852f8fe9abaac4e.tar.gz
vega-a4ca275ad1b5edc15474407e2852f8fe9abaac4e.zip
Set text in a stack of fonts: each grapheme cluster in the first that has it
vega_layout takes fonts in order of preference (VegaFonts). A grapheme cluster goes to the first font that has all its characters (default ignorables aside: shaping hides them); a cluster of Common and Inherited characters stays in the font before it when that one has it, so the spaces between Arabic words stay in the Arabic font; failing that, the first font with its first character, else the first font. Runs split where the font changes too. Positions are in the first font's units, a run's pen scaled as a whole so rounding does not add up. Callers can narrow what a font has (a symbol file holds only the glyphs its codes reach). vega_default_ignorable is shape.c's HarfBuzz 10.2 set, now public.
Diffstat (limited to 'text/layout.h')
-rw-r--r--text/layout.h37
1 files changed, 28 insertions, 9 deletions
diff --git a/text/layout.h b/text/layout.h
index 9282536..f5aeb89 100644
--- a/text/layout.h
+++ b/text/layout.h
@@ -3,14 +3,16 @@
#include "shape.h"
/* A paragraph set into lines (docs/design/004-text.md): its bidi levels
- * (UAX #9), lines broken where UAX #14 allows and they fit (spaces at a
- * line's end hang past it), and each line's runs (one level, one script)
- * shaped and put in visual order. Positions are in the font's units: x
- * from the paragraph's left edge, y up from the line's baseline. */
+ * (UAX #9), a font for each grapheme cluster, lines broken where UAX #14
+ * allows and they fit (spaces at a line's end hang past it), and each
+ * line's runs (one level, one script, one font) shaped and put in visual
+ * order. Positions are in the first font's units: x from the paragraph's
+ * left edge, y up from the line's baseline. */
typedef struct {
- uint32_t glyph; /* the font's: its symbol is VEGA_GLYPH_SYMBOLS + glyph */
+ uint32_t glyph; /* its font's: its symbol is VEGA_GLYPH_SYMBOLS + glyph */
uint32_t cluster; /* the paragraph index of the first character it came from */
int32_t x, y, advance;
+ uint32_t font; /* which of the fonts */
} VegaPlaced;
typedef struct {
size_t first, count; /* its glyphs, left to right */
@@ -29,10 +31,27 @@ typedef struct {
size_t work_size, lines_allocated, glyphs_allocated;
} VegaLayout;
-/* Set count characters in lines of at most width (0: no limit) with the
- * font's shaping; direction is VEGA_BIDI_AUTO, _LTR or _RTL. The layout
- * holds the result until it is set again; false without memory. */
-bool vega_layout(VegaLayout *, VegaShaper *, const VegaShaping *, const uint32_t *codes, size_t count, int direction,
+/* What text is set in: fonts in order of preference, each cluster in the
+ * first that has all its characters (default ignorables aside: shaping
+ * hides them), a cluster of Common and Inherited characters (spaces,
+ * digits, punctuation) in the font before it when that one has them; no
+ * font having them all, the first that has its first character, else the
+ * first font. has says whether a font has a character, NULL whether its
+ * character map does: a font whose glyphs are not all at hand can say it
+ * lacks the others. */
+enum { VEGA_LAYOUT_FONTS = 16 };
+typedef struct {
+ const VegaShaping *fonts[VEGA_LAYOUT_FONTS];
+ unsigned count;
+ bool (*has)(void *context, unsigned font, uint32_t code);
+ void *context;
+} VegaFonts;
+
+/* Set count characters in lines of at most width (0: no limit) in the
+ * fonts; direction is VEGA_BIDI_AUTO, _LTR or _RTL. The layout holds the
+ * result until it is set again; false without memory, or when a run's font
+ * has no plan for its script (nor for Common). */
+bool vega_layout(VegaLayout *, VegaShaper *, const VegaFonts *, const uint32_t *codes, size_t count, int direction,
int32_t width);
void vega_layout_free(VegaLayout *);
#endif