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
|
89/<- %ebp 4/r32/esp
|
||||||
# eax = c
|
# eax = c
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
# if (c >= 128) return # characters beyond ASCII currently not supported
|
# if (c >= 4352) return false
|
||||||
3d/compare-eax-and 0x80/imm32
|
3d/compare-eax-and 0x1100/imm32
|
||||||
0f 8d/jump-if->= $wide-code-point?:end/disp32
|
0f 8d/jump-if->= $wide-code-point?:return-false/disp32
|
||||||
# var letter-bitmap/eax = font[c]
|
# var letter-bitmap/eax = font[c]
|
||||||
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
||||||
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
||||||
|
@ -147,15 +147,22 @@ $wide-code-point?:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
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
|
combining-code-point?: # c: code-point -> _/eax: boolean
|
||||||
# . prologue
|
# . prologue
|
||||||
55/push-ebp
|
55/push-ebp
|
||||||
89/<- %ebp 4/r32/esp
|
89/<- %ebp 4/r32/esp
|
||||||
# eax = c
|
# eax = c
|
||||||
8b/-> *(ebp+8) 0/r32/eax
|
8b/-> *(ebp+8) 0/r32/eax
|
||||||
# if (c >= 128) return # characters beyond ASCII currently not supported
|
# if (c >= 4352) return false
|
||||||
3d/compare-eax-and 0x80/imm32
|
3d/compare-eax-and 0x1100/imm32
|
||||||
0f 8d/jump-if->= $combining-code-point?:end/disp32
|
0f 8d/jump-if->= $combining-code-point?:return-false/disp32
|
||||||
# var letter-bitmap/eax = font[c]
|
# var letter-bitmap/eax = font[c]
|
||||||
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
69/multiply %eax 0x22/imm32/glyph-size 0/r32/eax
|
||||||
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
05/add-to-eax 0x0010000c/imm32/Font # see boot.subx
|
||||||
|
@ -168,6 +175,13 @@ $combining-code-point?:end:
|
||||||
5d/pop-to-ebp
|
5d/pop-to-ebp
|
||||||
c3/return
|
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
|
# buffer: naked address to raw screen RAM without a length
|
||||||
# letter-bitmap: naked address to 8-pixel wide font glyph
|
# 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
|
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 {
|
type screen-cell {
|
||||||
data: code-point
|
data: code-point # TODO: support combining characters overlaid on another character
|
||||||
color: int
|
color: int
|
||||||
background-color: int
|
background-color: int
|
||||||
unused?: boolean
|
unused?: boolean
|
||||||
|
@ -109,6 +109,27 @@ fn draw-code-point _screen: (addr screen), c: code-point, x: int, y: int, color:
|
||||||
return 1
|
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 {
|
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
|
var screen/esi: (addr screen) <- copy _screen
|
||||||
# ignore if out of bounds
|
# 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 xcurr/ecx: int <- copy x
|
||||||
var ycurr/edx: int <- copy y
|
var ycurr/edx: int <- copy y
|
||||||
var c/ebx: code-point <- copy 0
|
var c/ebx: code-point <- copy 0
|
||||||
|
var next-c/esi: code-point <- copy 0
|
||||||
$draw-stream-wrapping-right-then-down:loop: {
|
$draw-stream-wrapping-right-then-down:loop: {
|
||||||
var g/eax: grapheme <- read-grapheme stream
|
# read c from either next-c or stream
|
||||||
var _c/eax: code-point <- to-code-point g
|
$draw-stream-wrapping-right-then-down:read-base: {
|
||||||
c <- copy _c
|
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
|
compare c, 0xffffffff/end-of-file
|
||||||
break-if-=
|
break-if-=
|
||||||
compare c, 0xa/newline
|
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
|
break $draw-stream-wrapping-right-then-down:loop
|
||||||
}
|
}
|
||||||
var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
|
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
|
xcurr <- add offset
|
||||||
compare xcurr, xmax
|
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
|
# 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 <- 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
|
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