support combining characters in streams of text
Fake screens can't handle them yet.
This commit is contained in:
parent
3f953ea5c8
commit
60a50c9245
|
@ -130,9 +130,9 @@ wide-code-point?: # c: code-point -> _/eax: boolean
|
|||
89/<- %ebp 4/r32/esp
|
||||
# eax = c
|
||||
8b/-> *(ebp+8) 0/r32/eax
|
||||
# if (c >= 128) return # characters beyond ASCII currently not supported
|
||||
3d/compare-eax-and 0x80/imm32
|
||||
0f 8d/jump-if->= $wide-code-point?:end/disp32
|
||||
# if (c >= 4352) return false
|
||||
3d/compare-eax-and 0x1100/imm32
|
||||
0f 8d/jump-if->= $wide-code-point?:return-false/disp32
|
||||
# var letter-bitmap/eax = font[c]
|
||||
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
||||
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
||||
|
@ -147,15 +147,22 @@ $wide-code-point?:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
$wide-code-point?:return-false:
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
combining-code-point?: # c: code-point -> _/eax: boolean
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# eax = c
|
||||
8b/-> *(ebp+8) 0/r32/eax
|
||||
# if (c >= 128) return # characters beyond ASCII currently not supported
|
||||
3d/compare-eax-and 0x80/imm32
|
||||
0f 8d/jump-if->= $combining-code-point?:end/disp32
|
||||
# if (c >= 4352) return false
|
||||
3d/compare-eax-and 0x1100/imm32
|
||||
0f 8d/jump-if->= $combining-code-point?:return-false/disp32
|
||||
# var letter-bitmap/eax = font[c]
|
||||
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
||||
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
||||
|
@ -168,6 +175,13 @@ $combining-code-point?:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
$combining-code-point?:return-false:
|
||||
b8/copy-to-eax 0/imm32/false
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# buffer: naked address to raw screen RAM without a length
|
||||
# letter-bitmap: naked address to 8-pixel wide font glyph
|
||||
draw-narrow-code-point-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, overlay?: boolean, screen-width: int, screen-height: int
|
||||
|
|
|
@ -23,7 +23,7 @@ type screen {
|
|||
}
|
||||
|
||||
type screen-cell {
|
||||
data: code-point
|
||||
data: code-point # TODO: support combining characters overlaid on another character
|
||||
color: int
|
||||
background-color: int
|
||||
unused?: boolean
|
||||
|
@ -109,6 +109,27 @@ fn draw-code-point _screen: (addr screen), c: code-point, x: int, y: int, color:
|
|||
return 1
|
||||
}
|
||||
|
||||
fn overlay-code-point _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int {
|
||||
var screen/esi: (addr screen) <- copy _screen
|
||||
{
|
||||
compare screen, 0
|
||||
break-if-!=
|
||||
var result/eax: int <- overlay-code-point-on-real-screen c, x, y, color, background-color
|
||||
return result
|
||||
}
|
||||
# fake screen
|
||||
# TODO: support overlays in fake screen
|
||||
var wide?/eax: boolean <- wide-code-point? c
|
||||
compare wide?, 0/false
|
||||
{
|
||||
break-if-=
|
||||
draw-wide-code-point-on-fake-screen screen, c, x, y, color, background-color
|
||||
return 2
|
||||
}
|
||||
draw-narrow-code-point-on-fake-screen screen, c, x, y, color, background-color
|
||||
return 1
|
||||
}
|
||||
|
||||
fn draw-narrow-code-point-on-fake-screen _screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int {
|
||||
var screen/esi: (addr screen) <- copy _screen
|
||||
# ignore if out of bounds
|
||||
|
|
|
@ -207,10 +207,21 @@ fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr str
|
|||
var xcurr/ecx: int <- copy x
|
||||
var ycurr/edx: int <- copy y
|
||||
var c/ebx: code-point <- copy 0
|
||||
var next-c/esi: code-point <- copy 0
|
||||
$draw-stream-wrapping-right-then-down:loop: {
|
||||
var g/eax: grapheme <- read-grapheme stream
|
||||
var _c/eax: code-point <- to-code-point g
|
||||
c <- copy _c
|
||||
# read c from either next-c or stream
|
||||
$draw-stream-wrapping-right-then-down:read-base: {
|
||||
compare next-c, 0
|
||||
{
|
||||
break-if-=
|
||||
c <- copy next-c
|
||||
next-c <- copy 0
|
||||
break $draw-stream-wrapping-right-then-down:read-base
|
||||
}
|
||||
var g/eax: grapheme <- read-grapheme stream
|
||||
var _c/eax: code-point <- to-code-point g
|
||||
c <- copy _c
|
||||
}
|
||||
compare c, 0xffffffff/end-of-file
|
||||
break-if-=
|
||||
compare c, 0xa/newline
|
||||
|
@ -223,6 +234,29 @@ fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr str
|
|||
break $draw-stream-wrapping-right-then-down:loop
|
||||
}
|
||||
var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
|
||||
# overlay a combining character if necessary
|
||||
$draw-stream-wrapping-right-then-down:read-combiner: {
|
||||
var done?/eax: boolean <- stream-empty? stream
|
||||
compare done?, 0/false
|
||||
break-if-!=
|
||||
# read a character
|
||||
var g/eax: grapheme <- read-grapheme stream
|
||||
var c/eax: code-point <- to-code-point g
|
||||
# if not a combining character, save for next iteration and loop
|
||||
{
|
||||
var combining-code-point?/eax: boolean <- combining-code-point? c
|
||||
compare combining-code-point?, 0/false
|
||||
}
|
||||
{
|
||||
break-if-!=
|
||||
next-c <- copy c
|
||||
break $draw-stream-wrapping-right-then-down:read-combiner
|
||||
}
|
||||
# otherwise overlay it without saving its width
|
||||
# This means strange results if a base and its combiner have different
|
||||
# widths. We'll always follow the base width.
|
||||
var dummy/eax: int <- overlay-code-point screen, c, xcurr, ycurr, color, background-color
|
||||
}
|
||||
xcurr <- add offset
|
||||
compare xcurr, xmax
|
||||
{
|
||||
|
|
55
apps/ex15.mu
55
apps/ex15.mu
|
@ -77,4 +77,59 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk)
|
|||
# kaha
|
||||
var dummy/eax: int <- draw-code-point-on-real-screen 0x0915/devanagari-letter-ka, 0x13/x 9/y, 3/fg 0/bg
|
||||
var dummy/eax: int <- overlay-code-point-on-real-screen 0x0903/devanagari-visarga, 0x13/x 9/y, 3/fg 0/bg
|
||||
|
||||
# render the same letters as a single stream of utf-8 graphemes rather than individual code-points.
|
||||
var text-storage: (stream byte 0x200)
|
||||
var text/esi: (addr stream byte) <- address text-storage
|
||||
var g/eax: grapheme <- to-grapheme 0x0915/devanagari-letter-ka
|
||||
var ka/ecx: grapheme <- copy g
|
||||
# ka
|
||||
write-grapheme text, ka
|
||||
# kaa
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x093e/devanagari-vowel-aa
|
||||
write-grapheme text, g
|
||||
# ki
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x093f/devanagari-vowel-i
|
||||
write-grapheme text, g
|
||||
# kee
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0940/devanagari-vowel-ii
|
||||
write-grapheme text, g
|
||||
# ku
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0941/devanagari-vowel-u
|
||||
write-grapheme text, g
|
||||
# koo
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0942/devanagari-vowel-oo
|
||||
write-grapheme text, g
|
||||
# kay
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0947/devanagari-vowel-E
|
||||
write-grapheme text, g
|
||||
# kai
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0948/devanagari-vowel-ai
|
||||
write-grapheme text, g
|
||||
# ko
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x094b/devanagari-vowel-o
|
||||
write-grapheme text, g
|
||||
# kow
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x094f/devanagari-vowel-aw
|
||||
write-grapheme text, g
|
||||
# kan
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0902/devanagari-anusvara
|
||||
write-grapheme text, g
|
||||
# kaha
|
||||
write-grapheme text, ka
|
||||
g <- to-grapheme 0x0903/devanagari-visarga
|
||||
write-grapheme text, g
|
||||
# render everything
|
||||
set-cursor-position screen, 4/x 0xe/y
|
||||
draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen, text, 3/fg 0/bg
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue