Initial commit: Schunix as it stands before the SchOS rename
An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
This commit is contained in:
commit
d0f7acf9eb
275 changed files with 51417 additions and 0 deletions
86
include/text.h
Normal file
86
include/text.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#pragma once
|
||||
|
||||
// Text rendering.
|
||||
//
|
||||
// The console draws text by indexing `font_data[256][16]` and stepping the
|
||||
// cursor eight pixels. That is a *character cell grid*, and it is the thing in
|
||||
// the way -- not the font. A grid cannot do variable-width glyphs, cannot
|
||||
// position text anywhere except on a multiple of eight, cannot anti-alias, and
|
||||
// cannot represent a codepoint above 255. Swapping the bitmap for a nicer
|
||||
// bitmap changes none of that.
|
||||
//
|
||||
// So this is a layer, not a font. Three things it fixes:
|
||||
//
|
||||
// *Glyphs have metrics.* A glyph knows its own size, its bearing and how far
|
||||
// to advance afterwards. That is what variable-width text is; everything else
|
||||
// follows from it.
|
||||
//
|
||||
// *It draws into a surface, not into the screen.* A compositor draws into an
|
||||
// off-screen buffer and presents it. Rendering that writes straight to the
|
||||
// VGA aperture is unusable to it, which is why this takes a target.
|
||||
//
|
||||
// *The font is behind an interface.* The bitmap font is one implementation.
|
||||
// A TrueType rasteriser is another, and arrives without any caller changing:
|
||||
// glyphs carry 8-bit coverage, so an anti-aliased outline renderer already
|
||||
// has somewhere to put its output.
|
||||
|
||||
struct font;
|
||||
|
||||
// Somewhere to draw. Deliberately not a `struct device` or a framebuffer: the
|
||||
// same code has to work on the virtio-gpu back buffer, on a window's own
|
||||
// buffer, and on the VGA aperture, and none of those know about each other.
|
||||
struct surface {
|
||||
void *pixels; // 32-bit 0x00RRGGBB, the format everything here uses
|
||||
uint32 stride; // bytes per row, not pixels -- they differ on real hardware
|
||||
int width, height;
|
||||
};
|
||||
|
||||
// One rendered glyph. `cov` is 8-bit coverage, not a bitmap: 0 is background,
|
||||
// 255 is solid, and everything between is an anti-aliased edge. A bitmap font
|
||||
// fills it with 0 and 255 only, and costs nothing for the generality.
|
||||
struct glyph {
|
||||
const unsigned char *cov; // w*h bytes, row-major
|
||||
int w, h; // size of the coverage bitmap
|
||||
int bearing_x, bearing_y; // offset from the pen to the top-left of `cov`
|
||||
int advance; // how far the pen moves afterwards
|
||||
};
|
||||
|
||||
struct font_ops {
|
||||
// Fill `out` for `cp`. Returns 0, or -1 if the font has no such glyph --
|
||||
// callers substitute rather than failing, because a missing glyph must not
|
||||
// stop a line of text.
|
||||
int (*glyph)(struct font *, uint32 cp, struct glyph *out);
|
||||
int (*height)(struct font *); // line height
|
||||
int (*baseline)(struct font *); // pen offset from the top of the line
|
||||
};
|
||||
|
||||
struct font {
|
||||
const struct font_ops *ops;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
// The built-in bitmap font, as a font provider. Always available, needs no
|
||||
// allocation, and is what the console falls back to before any filesystem
|
||||
// exists to load a real typeface from.
|
||||
struct font *font_builtin(void);
|
||||
|
||||
// Draw one UTF-8 string. Returns the x advance.
|
||||
//
|
||||
// `x, y` is the pen position on the *baseline*, which is how every text API
|
||||
// that is not a terminal works -- glyphs of different heights then sit on a
|
||||
// common line instead of being top-aligned.
|
||||
int text_draw(struct surface *, struct font *, int x, int y,
|
||||
const char *utf8, uint32 color);
|
||||
|
||||
// Width the same string would occupy, without drawing it. Needed before you
|
||||
// draw, for centring and for laying out anything at all.
|
||||
int text_measure(struct font *, const char *utf8);
|
||||
|
||||
// One glyph, for callers doing their own layout.
|
||||
int text_draw_glyph(struct surface *, struct font *, int x, int y,
|
||||
uint32 cp, uint32 color);
|
||||
|
||||
// Decode one UTF-8 sequence. Returns the codepoint and advances *p.
|
||||
// Malformed input yields U+FFFD and consumes one byte, so a decoder loop
|
||||
// always terminates.
|
||||
uint32 utf8_next(const char **p);
|
||||
Loading…
Reference in a new issue