forked from AbleOS/ableos
unoptimised text load & render
This commit is contained in:
parent
5af5631755
commit
eaace7d9c1
BIN
sysdata/consolefonts/tamsyn/10x20b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/10x20b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/10x20r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/10x20r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/5x9b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/5x9b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/5x9r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/5x9r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/6x12b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/6x12b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/6x12r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/6x12r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/7x13b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/7x13b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/7x13r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/7x13r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/7x14b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/7x14b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/7x14r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/7x14r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/8x15b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/8x15b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/8x15r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/8x15r.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/8x16b.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/8x16b.psf
Normal file
Binary file not shown.
BIN
sysdata/consolefonts/tamsyn/8x16r.psf
Normal file
BIN
sysdata/consolefonts/tamsyn/8x16r.psf
Normal file
Binary file not shown.
10
sysdata/consolefonts/tamsyn/LICENSE
Normal file
10
sysdata/consolefonts/tamsyn/LICENSE
Normal file
|
@ -0,0 +1,10 @@
|
|||
Tamsyn font is free. You are hereby granted permission to use, copy, modify,
|
||||
and distribute it as you see fit.
|
||||
|
||||
Tamsyn font is provided "as is" without any express or implied warranty.
|
||||
|
||||
The author makes no representations about the suitability of this font for
|
||||
a particular purpose.
|
||||
|
||||
In no event will the author be held liable for damages arising from the use
|
||||
of this font.
|
|
@ -5,13 +5,10 @@
|
|||
- Animation
|
||||
|
||||
# API
|
||||
- Font Loader
|
||||
- VGA fonts
|
||||
- Colour operations:
|
||||
- Alpha Composite
|
||||
- Invert
|
||||
- Surface Operations:
|
||||
- FlipV
|
||||
- FlipH
|
||||
- Resize
|
||||
- Wrap the colour operations
|
||||
|
@ -20,8 +17,8 @@
|
|||
- Draw operations:
|
||||
- Curve raster algorithm
|
||||
- VGA font fast blit
|
||||
- VGA font render
|
||||
- Polygon
|
||||
- Rounded rects
|
||||
|
||||
# Backend
|
||||
- SVGA Driver
|
||||
|
|
|
@ -36,7 +36,7 @@ surface_from_bmp := fn(bmp: ^u8): Surface {
|
|||
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
||||
if file_header.img_type != 0x4D42 {
|
||||
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
||||
return @as(Surface, idk)
|
||||
return idk
|
||||
}
|
||||
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
||||
bmp += file_header.offset
|
||||
|
@ -68,7 +68,7 @@ new_surface_from_bmp := fn(bmp: ^u8): Surface {
|
|||
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
||||
if file_header.img_type != 0x4D42 {
|
||||
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
||||
return @as(Surface, idk)
|
||||
return idk
|
||||
}
|
||||
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
||||
bmp += file_header.offset
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
software := @use("software.hb")
|
||||
image := @use("image.hb")
|
||||
text := @use("text.hb")
|
||||
|
||||
// default mode
|
||||
mode := software
|
||||
|
@ -40,6 +41,7 @@ put_filled_rect := mode.put_filled_rect
|
|||
put_line := mode.put_line
|
||||
clear := mode.clear
|
||||
put_surface := mode.put_surface
|
||||
put_text := mode.put_text
|
||||
// thanks peony for these three!
|
||||
put_trirect := mode.put_trirect
|
||||
put_vline := mode.put_vline
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
.{math, memory, dt} := @use("../../stn/src/lib.hb");
|
||||
.{Color} := @use("lib.hb");
|
||||
.{Color, text} := @use("lib.hb");
|
||||
.{get_glyph, Font} := text;
|
||||
.{Vec2} := math
|
||||
|
||||
Surface := struct {
|
||||
|
@ -255,5 +256,65 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
|
|||
}
|
||||
@inline(memory.set, Color, &color, @inline(indexptr, surface, x0, y), @bitcast(x1 - x0 - 1))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
put_text := fn(surface: Surface, font: Font, pos: Vec2(uint), color: Color, str: ^u8): void {
|
||||
cursor := Vec2(uint).(pos.x, pos.y)
|
||||
current_char := str
|
||||
|
||||
loop if *current_char == 0 break else {
|
||||
if *current_char == 10 {
|
||||
cursor.x = pos.x
|
||||
cursor.y += font.height + font.line_gap
|
||||
current_char += 1
|
||||
continue
|
||||
}
|
||||
|
||||
glyph_data := @inline(get_glyph, font, @intcast(*current_char))
|
||||
if glyph_data == idk {
|
||||
current_char += 1
|
||||
continue
|
||||
}
|
||||
|
||||
if cursor.x % surface.width + font.width >= surface.width {
|
||||
cursor.x = pos.x
|
||||
cursor.y += font.height + font.line_gap
|
||||
}
|
||||
if cursor.y + font.height > surface.height break
|
||||
|
||||
dest := @inline(indexptr, surface, cursor.x, cursor.y)
|
||||
src := glyph_data
|
||||
rows_remaining := font.height
|
||||
|
||||
loop if rows_remaining == 0 break else {
|
||||
byte := *glyph_data
|
||||
pixel_dest := dest
|
||||
mask := @as(u8, 0x80)
|
||||
bits_remaining := font.width
|
||||
|
||||
loop if bits_remaining == 0 break else {
|
||||
if (byte & mask) != 0 {
|
||||
*pixel_dest = color
|
||||
}
|
||||
pixel_dest += 1
|
||||
mask >>= 1
|
||||
if mask == 0 {
|
||||
glyph_data += 1
|
||||
byte = *glyph_data
|
||||
mask = 0x80
|
||||
}
|
||||
bits_remaining -= 1
|
||||
}
|
||||
|
||||
glyph_data += 1
|
||||
dest += surface.width
|
||||
rows_remaining -= 1
|
||||
}
|
||||
|
||||
cursor.x += font.width + font.char_gap
|
||||
current_char += 1
|
||||
}
|
||||
|
||||
return
|
||||
}
|
75
sysdata/libraries/render/src/text.hb
Normal file
75
sysdata/libraries/render/src/text.hb
Normal file
|
@ -0,0 +1,75 @@
|
|||
.{log} := @use("../../stn/src/lib.hb")
|
||||
|
||||
PSF1Header := packed struct {
|
||||
magic: u16,
|
||||
font_mode: u8,
|
||||
character_size: u8,
|
||||
}
|
||||
|
||||
PSF2Header := packed struct {
|
||||
magic: u32,
|
||||
version: u32,
|
||||
header_size: u32,
|
||||
flags: u32,
|
||||
num_glyph: u32,
|
||||
bytes_per_glyph: u32,
|
||||
height: u32,
|
||||
width: u32,
|
||||
}
|
||||
|
||||
Font := struct {
|
||||
data: ^u8,
|
||||
width: uint,
|
||||
height: uint,
|
||||
num_glyphs: uint,
|
||||
bytes_per_glyph: uint,
|
||||
has_unicode_table: bool,
|
||||
line_gap: uint,
|
||||
char_gap: uint,
|
||||
}
|
||||
|
||||
font_from_psf1 := fn(psf: ^u8): Font {
|
||||
header := @as(^PSF1Header, @bitcast(psf))
|
||||
if header.magic != 0x436 {
|
||||
log.error("failed to load psf font: not a psf1 font, idiot\0")
|
||||
return idk
|
||||
}
|
||||
|
||||
psf += @sizeof(PSF1Header)
|
||||
|
||||
return .(
|
||||
psf,
|
||||
8,
|
||||
@intcast(header.character_size),
|
||||
256,
|
||||
@intcast(header.character_size),
|
||||
false,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
font_from_psf2 := fn(psf: ^u8): Font {
|
||||
header := @as(^PSF2Header, @bitcast(psf))
|
||||
if header.magic != 0x864AB572 {
|
||||
log.error("failed to load psf font: not a psf2 font, idiot\0")
|
||||
return idk
|
||||
}
|
||||
|
||||
psf += header.header_size
|
||||
|
||||
return .(
|
||||
psf,
|
||||
@intcast(header.width),
|
||||
@intcast(header.height),
|
||||
@intcast(header.num_glyph),
|
||||
@intcast(header.bytes_per_glyph),
|
||||
(header.flags & 1) != 0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
get_glyph := fn(font: Font, index: uint): ^u8 {
|
||||
return font.data + index * font.bytes_per_glyph
|
||||
}
|
BIN
sysdata/libraries/stn/src/assets/sin_table
Normal file
BIN
sysdata/libraries/stn/src/assets/sin_table
Normal file
Binary file not shown.
0
sysdata/libraries/stn/src/assets/this-is-temporary
Normal file
0
sysdata/libraries/stn/src/assets/this-is-temporary
Normal file
|
@ -30,26 +30,30 @@ Vec2 := fn($Expr: type): type {
|
|||
return struct {x: Expr, y: Expr}
|
||||
}
|
||||
|
||||
SIN_TABLE := [int].(0, 174, 348, 523, 697, 871, 1045, 1218, 1391, 1564, 1736, 1908, 2079, 2249, 2419, 2588, 2756, 2923, 3090, 3255, 3420, 3583, 3746, 3907, 4067, 4226, 4384, 4540, 4695, 4848, 5000, 5150, 5299, 5446, 5591, 5735, 5877, 6018, 6156, 6293, 6427, 6560, 6691, 6819, 6946, 7071, 7193, 7313, 7431, 7547, 7660, 7771, 7880, 7986, 8090, 8191, 8290, 8386, 8480, 8571, 8660, 8746, 8829, 8910, 8987, 9063, 9135, 9205, 9271, 9335, 9396, 9455, 9510, 9563, 9612, 9659, 9702, 9743, 9781, 9816, 9848, 9877, 9902, 9925, 9945, 9961, 9975, 9986, 9993, 9998, 10000)
|
||||
SIN_TABLE := @as([int; 91], @bitcast(@embed("./assets/sin_table")))
|
||||
|
||||
sin_i := fn(theta_deg: int, amplitude: int): int {
|
||||
theta := theta_deg % 360
|
||||
sin := fn(theta: int, amplitude: uint): int {
|
||||
if theta < 0 {
|
||||
theta += 360
|
||||
theta += (-theta / 360 + 1) * 360
|
||||
} else if theta >= 360 {
|
||||
theta -= theta / 360 * 360
|
||||
}
|
||||
|
||||
quadrant := theta / 90
|
||||
theta = theta % 90
|
||||
index := theta % 90
|
||||
|
||||
sign := 1 - ((quadrant & 2) >> 1) * 2
|
||||
complement := quadrant & 1
|
||||
if @as(u8, @intcast(quadrant)) == @as(u8, 1) {
|
||||
index = 90 - index
|
||||
}
|
||||
|
||||
index := theta * (1 - complement) + (90 - theta) * complement
|
||||
sin_value := SIN_TABLE[index] * sign
|
||||
value := SIN_TABLE[@bitcast(index)]
|
||||
if quadrant >= 2 {
|
||||
value = -value
|
||||
}
|
||||
|
||||
return (sin_value * amplitude + 5000) / 10000
|
||||
return (value * @bitcast(amplitude) + 5000) / 10000
|
||||
}
|
||||
|
||||
cos_i := fn(theta_deg: int, amplitude: int): int {
|
||||
return @inline(sin_i, theta_deg + 90, amplitude)
|
||||
cos := fn(theta: int, amplitude: uint): int {
|
||||
return @inline(sin, theta + 90, amplitude)
|
||||
}
|
23
sysdata/programs/render_example/src/examples/text.hb
Normal file
23
sysdata/programs/render_example/src/examples/text.hb
Normal file
|
@ -0,0 +1,23 @@
|
|||
.{Vec2, sin, cos} := @use("../../../../libraries/stn/src/lib.hb").math
|
||||
render := @use("../../../../libraries/render/src/lib.hb")
|
||||
|
||||
/* expected result:
|
||||
words */
|
||||
|
||||
psf := @embed("../../../../consolefonts/tamsyn/10x20r.psf")
|
||||
|
||||
example := fn(): void {
|
||||
screen := render.init(true)
|
||||
font := render.text.font_from_psf2(@bitcast(&psf))
|
||||
t := 0
|
||||
str := "Hello, World!
|
||||
This is a test
|
||||
of multiline rendering\0"
|
||||
loop {
|
||||
render.clear(screen, render.black)
|
||||
render.put_text(screen, font, .(t, t % screen.height), render.red, str)
|
||||
render.sync(screen)
|
||||
t += 1
|
||||
}
|
||||
return
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
.{example} := @use("./examples/surface.hb")
|
||||
.{example} := @use("./examples/text.hb")
|
||||
|
||||
main := example
|
|
@ -28,8 +28,8 @@ resolution = "1024x768x24"
|
|||
# [boot.limine.ableos.modules.diskio_driver]
|
||||
# path = "boot:///diskio_driver.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.render_example]
|
||||
# path = "boot:///render_example.hbf"
|
||||
[boot.limine.ableos.modules.render_example]
|
||||
path = "boot:///render_example.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.serial_driver]
|
||||
# path = "boot:///serial_driver.hbf"
|
||||
|
@ -37,11 +37,11 @@ resolution = "1024x768x24"
|
|||
# [boot.limine.ableos.modules.serial_driver_test]
|
||||
# path = "boot:///serial_driver_test.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.horizon]
|
||||
path = "boot:///horizon.hbf"
|
||||
# [boot.limine.ableos.modules.horizon]
|
||||
# path = "boot:///horizon.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.horizon_testing_program]
|
||||
path = "boot:///horizon_testing_program.hbf"
|
||||
# [boot.limine.ableos.modules.horizon_testing_program]
|
||||
# path = "boot:///horizon_testing_program.hbf"
|
||||
|
||||
# [boot.limine.ableos.modules.dt_buffer_test]
|
||||
# path = "boot:///dt_buffer_test.hbf"
|
||||
|
|
Loading…
Reference in a new issue