minor optimisations
This commit is contained in:
parent
8808ed5bfe
commit
3333b1706f
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -228,12 +228,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7865d692a156c1d31f63b8f04b5d51472d1ff30a"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
|
||||
[[package]]
|
||||
name = "hblang"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7865d692a156c1d31f63b8f04b5d51472d1ff30a"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
dependencies = [
|
||||
"hashbrown 0.15.1",
|
||||
"hbbytecode",
|
||||
|
@ -245,7 +245,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbvm"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#7865d692a156c1d31f63b8f04b5d51472d1ff30a"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#8b98c2ed1becb92046bb7b687ca00813da441248"
|
||||
dependencies = [
|
||||
"hbbytecode",
|
||||
]
|
||||
|
|
|
@ -35,17 +35,14 @@ BitmapColorHeader := packed struct {
|
|||
from := fn(bmp: ^u8): ?Surface {
|
||||
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
||||
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
||||
bmp += file_header.offset
|
||||
|
||||
if file_header.magic != 0x4D42 | info_header.width == 0 | info_header.height == 0 {
|
||||
log.error("Invalid BMP image.\0")
|
||||
return null
|
||||
}
|
||||
|
||||
width := @as(uint, info_header.width)
|
||||
height := @as(uint, info_header.height)
|
||||
lhs := Surface.(@bitcast(bmp), width, height)
|
||||
rhs := new_surface(width, height)
|
||||
lhs := Surface.(@bitcast(bmp + file_header.offset), info_header.width, info_header.height)
|
||||
rhs := new_surface(info_header.width, info_header.height)
|
||||
put_surface(rhs, lhs, .(0, 0), true)
|
||||
|
||||
return rhs
|
||||
|
|
|
@ -28,7 +28,7 @@ QuiteOkayHeader := packed struct {
|
|||
}
|
||||
|
||||
be_to_le := fn(big: u32): u32 {
|
||||
return (big & 0xFF000000) >> 24 | (big & 0xFF0000) >> 8 | (big & 0xFF00) << 8 | (big & 0xFF) << 24
|
||||
return big >> 24 | big >> 8 & 0xFF00 | big << 8 & 0xFF0000 | big << 24
|
||||
}
|
||||
|
||||
from := fn(qoi: ^u8): ?Surface {
|
||||
|
|
|
@ -20,25 +20,12 @@ new_surface := fn(width: uint, height: uint): Surface {
|
|||
)
|
||||
}
|
||||
|
||||
surface_from_ptr := fn(ptr: ^Color, width: uint, height: uint): Surface {
|
||||
return .(
|
||||
ptr,
|
||||
width,
|
||||
height,
|
||||
)
|
||||
}
|
||||
|
||||
clone_surface := fn(surface: ^Surface): Surface {
|
||||
new := new_surface(surface.width, surface.height)
|
||||
@inline(memory.copy, Color, surface.buf, new.buf, @intcast(surface.width * surface.height))
|
||||
return new
|
||||
}
|
||||
|
||||
// ! is broken, check memory.free function
|
||||
free_surface := fn(surface: Surface): void {
|
||||
return @inline(memory.free, Color, surface.buf, @intcast(surface.width * surface.height), false)
|
||||
}
|
||||
|
||||
init := fn(doublebuffer: bool): Surface {
|
||||
framebuffer = dt.get(^Color, "framebuffer/fb0/ptr\0")
|
||||
width := dt.get(uint, "framebuffer/fb0/width\0")
|
||||
|
@ -55,7 +42,6 @@ clear := fn(surface: Surface, color: Color): void {
|
|||
}
|
||||
|
||||
sync := fn(surface: Surface): void {
|
||||
// vague safety
|
||||
if surface.buf == framebuffer {
|
||||
return
|
||||
}
|
||||
|
@ -81,9 +67,8 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
|
|||
rows_to_fill := tr.y
|
||||
|
||||
loop if rows_to_fill <= 1 break else {
|
||||
// inline is broked
|
||||
memory.set(Color, &color, top_start_idx, @bitcast(tr.x))
|
||||
memory.set(Color, &color, bottom_start_idx, @bitcast(tr.x))
|
||||
@inline(memory.set, Color, &color, top_start_idx, tr.x)
|
||||
@inline(memory.set, Color, &color, bottom_start_idx, tr.x)
|
||||
|
||||
top_start_idx += surface.width
|
||||
bottom_start_idx -= surface.width
|
||||
|
@ -91,7 +76,7 @@ put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color:
|
|||
}
|
||||
|
||||
if rows_to_fill == 1 {
|
||||
@inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
|
||||
@inline(memory.set, Color, &color, top_start_idx, tr.x)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -181,30 +166,36 @@ put_line := fn(surface: Surface, p0: Vec2(uint), p1: Vec2(uint), color: Color):
|
|||
}
|
||||
|
||||
put_surface := fn(surface: Surface, top: Surface, pos: Vec2(uint), flip_v: bool): void {
|
||||
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
|
||||
src_top_cursor := top.buf
|
||||
src_bottom_cursor := top.buf + top.width * (top.height - 1)
|
||||
|
||||
dst_top_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||
dst_bottom_idx := @inline(indexptr, surface, pos.x, pos.y + top.height - 1)
|
||||
|
||||
dst_increment := surface.width
|
||||
|
||||
if flip_v {
|
||||
dst_increment = -dst_increment
|
||||
tmp := dst_top_idx
|
||||
dst_top_idx = dst_bottom_idx
|
||||
dst_bottom_idx = tmp
|
||||
}
|
||||
|
||||
rows_to_copy := top.height
|
||||
top_cursor := top.buf
|
||||
bottom_cursor := top.buf + top.width * (top.height - 1)
|
||||
|
||||
loop if rows_to_copy <= 1 break else {
|
||||
if flip_v {
|
||||
@inline(memory.copy, Color, top_cursor, bottom_start_idx, @bitcast(top.width))
|
||||
@inline(memory.copy, Color, bottom_cursor, top_start_idx, @bitcast(top.width))
|
||||
} else {
|
||||
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
|
||||
@inline(memory.copy, Color, bottom_cursor, bottom_start_idx, @bitcast(top.width))
|
||||
}
|
||||
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width)
|
||||
@inline(memory.copy, Color, src_bottom_cursor, dst_bottom_idx, top.width)
|
||||
|
||||
top_start_idx += surface.width
|
||||
bottom_start_idx -= surface.width
|
||||
top_cursor += top.width
|
||||
bottom_cursor -= top.width
|
||||
dst_top_idx += dst_increment
|
||||
dst_bottom_idx -= dst_increment
|
||||
src_top_cursor += top.width
|
||||
src_bottom_cursor -= top.width
|
||||
rows_to_copy -= 2
|
||||
}
|
||||
|
||||
if rows_to_copy == 1 {
|
||||
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(top.width))
|
||||
@inline(memory.copy, Color, src_top_cursor, dst_top_idx, top.width)
|
||||
}
|
||||
|
||||
return
|
||||
|
@ -260,126 +251,138 @@ put_hline := fn(surface: Surface, y: uint, x0: uint, x1: uint, color: Color): vo
|
|||
|
||||
return
|
||||
}
|
||||
utf8_len_table := [u8].(0, 0, 2, 3)
|
||||
|
||||
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 {
|
||||
glyph_data := memory.dangling(u8)
|
||||
max_y := surface.height - font.height
|
||||
next_line_y := font.height + font.line_gap
|
||||
char_advance := font.width + font.char_gap
|
||||
surface_width := surface.width
|
||||
|
||||
if font.unicode != null {
|
||||
code_point := @as(uint, 0)
|
||||
first_byte := *current_char
|
||||
num_bytes := 1
|
||||
loop if *str == 0 break else {
|
||||
if cursor.y > max_y break
|
||||
|
||||
if (first_byte & 0x80) == 0 {
|
||||
code_point = first_byte
|
||||
} else if (first_byte & 0xE0) == 0xC0 {
|
||||
num_bytes = 2
|
||||
code_point = first_byte & 0x1F
|
||||
} else if (first_byte & 0xF0) == 0xE0 {
|
||||
num_bytes = 3
|
||||
code_point = first_byte & 0xF
|
||||
} else if (first_byte & 0xF8) == 0xF0 {
|
||||
// handle later
|
||||
current_char += 1
|
||||
continue
|
||||
} else {
|
||||
current_char += 1
|
||||
glyph_data := @as(^u8, idk)
|
||||
code_point := @as(uint, 0)
|
||||
|
||||
if (*str & 0x80) == 0 {
|
||||
if *str == 10 {
|
||||
cursor.x = pos.x
|
||||
cursor.y += next_line_y
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
|
||||
if font.unicode == null {
|
||||
if *str > font.num_glyphs {
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
glyph_data = @inline(get_glyph, font, *str)
|
||||
} else {
|
||||
if *str < UNC_TABLE_SIZE {
|
||||
glyph_index := *(font.unicode + *str)
|
||||
if glyph_index == 0xFFFF {
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
glyph_data = font.data + glyph_index * font.bytes_per_glyph
|
||||
} else {
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
}
|
||||
str += 1
|
||||
} else if font.unicode != null {
|
||||
first_byte := *str
|
||||
num_bytes := @as(uint, 0)
|
||||
|
||||
num_bytes = utf8_len_table[first_byte >> 5 & 0x3]
|
||||
|
||||
if num_bytes == 0 {
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
|
||||
code_point = first_byte & (0x7F >> num_bytes | 0x1F)
|
||||
|
||||
valid_sequence := true
|
||||
i := 1
|
||||
loop if i >= num_bytes break else {
|
||||
current_char += 1
|
||||
// have to check twice due to odd compiler bug...?
|
||||
if *current_char == 0 | (*current_char & 0xC0) != 0x80 {
|
||||
bytes_processed := 1
|
||||
|
||||
loop if bytes_processed >= num_bytes break else {
|
||||
str += 1
|
||||
if *str == 0 | (*str & 0xC0) != 0x80 {
|
||||
valid_sequence = false
|
||||
}
|
||||
if valid_sequence == false {
|
||||
break
|
||||
}
|
||||
code_point = code_point << 6 | *current_char & 0x3F
|
||||
i += 1
|
||||
code_point = code_point << 6 | *str & 0x3F
|
||||
bytes_processed += 1
|
||||
}
|
||||
|
||||
if valid_sequence == false {
|
||||
current_char += 1
|
||||
str += 1
|
||||
continue
|
||||
}
|
||||
|
||||
current_char += 1
|
||||
str += 1
|
||||
|
||||
if code_point == 10 {
|
||||
cursor.x = pos.x
|
||||
cursor.y += font.height + font.line_gap
|
||||
cursor.y += next_line_y
|
||||
continue
|
||||
}
|
||||
|
||||
if code_point < UNC_TABLE_SIZE {
|
||||
glyph_index := *(font.unicode + code_point)
|
||||
if code_point >= UNC_TABLE_SIZE {
|
||||
continue
|
||||
}
|
||||
|
||||
if glyph_index == 0xFFFF {
|
||||
continue
|
||||
}
|
||||
glyph_data = font.data + glyph_index * font.bytes_per_glyph
|
||||
} else {
|
||||
glyph_index := *(font.unicode + code_point)
|
||||
if glyph_index == 0xFFFF {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if *current_char > font.num_glyphs {
|
||||
continue
|
||||
}
|
||||
glyph_data = @inline(get_glyph, font, *current_char)
|
||||
if *current_char == 10 {
|
||||
cursor.x = pos.x
|
||||
cursor.y += font.height + font.line_gap
|
||||
current_char += 1
|
||||
continue
|
||||
}
|
||||
current_char += 1
|
||||
glyph_data = font.data + glyph_index * font.bytes_per_glyph
|
||||
}
|
||||
|
||||
if cursor.y + font.height > surface.height break
|
||||
|
||||
if cursor.x % surface.width + font.width >= surface.width {
|
||||
if cursor.x + font.width >= surface_width {
|
||||
cursor.x = pos.x
|
||||
cursor.y += font.height + font.line_gap
|
||||
cursor.y += next_line_y
|
||||
}
|
||||
|
||||
dest := @inline(indexptr, surface, cursor.x, cursor.y)
|
||||
rows_remaining := font.height
|
||||
rows := font.height
|
||||
|
||||
loop if rows_remaining == 0 break else {
|
||||
loop if rows == 0 break else {
|
||||
byte := *glyph_data
|
||||
pixel_dest := dest
|
||||
mask := @as(u8, 0x80)
|
||||
bits_remaining := font.width
|
||||
bits := font.width
|
||||
|
||||
loop if bits_remaining == 0 break else {
|
||||
loop if bits == 0 break else {
|
||||
if (byte & mask) != 0 {
|
||||
*pixel_dest = color
|
||||
}
|
||||
pixel_dest += 1
|
||||
mask >>= 1
|
||||
if mask == 0 & bits_remaining > 0 {
|
||||
if mask == 0 & bits > 0 {
|
||||
glyph_data += 1
|
||||
byte = *glyph_data
|
||||
mask = 0x80
|
||||
}
|
||||
bits_remaining -= 1
|
||||
bits -= 1
|
||||
}
|
||||
|
||||
if mask != 0x80 {
|
||||
glyph_data += 1
|
||||
}
|
||||
dest += surface.width
|
||||
rows_remaining -= 1
|
||||
dest += surface_width
|
||||
rows -= 1
|
||||
}
|
||||
|
||||
cursor.x += font.width + font.char_gap
|
||||
cursor.x += char_advance
|
||||
}
|
||||
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue