diff --git a/103grapheme.subx b/103glyph.subx similarity index 75% rename from 103grapheme.subx rename to 103glyph.subx index abcfe57c..61035f22 100644 --- a/103grapheme.subx +++ b/103glyph.subx @@ -1,4 +1,9 @@ -# Use the built-in font to draw a grapheme to real screen. +# Use the built-in font to draw glyphs to screen. +# https://en.wikipedia.org/wiki/Glyph#Typography +# The Mu computer can currently only render glyphs corresponding to single +# code points. No combining characters. +# https://en.wikipedia.org/wiki/Code_point +# https://en.wikipedia.org/wiki/Combining_character # # We need to do this in machine code because Mu doesn't have global variables # yet (for the start of the font). @@ -9,20 +14,20 @@ # The Mu computer's font is 8px wide and 16px tall. # Therefore 'x' here is in [0, 128), and 'y' is in [0, 48) # Doesn't update the cursor; where the cursor should go after printing the -# current grapheme is a higher-level concern. -draw-grapheme-on-real-screen: # g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax +# current code-point is a higher-level concern. +draw-code-point-on-real-screen: # c: code-point, x: int, y: int, color: int, background-color: int -> _/eax # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # - (draw-grapheme-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) # => eax -$draw-grapheme-on-real-screen:end: + (draw-code-point-on-screen-buffer *Video-memory-addr *(ebp+8) *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) 0x80 0x30) # => eax +$draw-code-point-on-real-screen:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return -draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int +draw-code-point-on-screen-array: # screen-data: (addr array byte), c: code-point, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -39,17 +44,17 @@ draw-grapheme-on-screen-array: # screen-data: (addr array byte), g: grapheme, x 8b/-> *(ebp+0x20) 0/r32/eax f7 4/subop/multiply-into-eax *(ebp+0x24) 81 7/subop/compare %edx 0/imm32 - 0f 85/jump-if-!= $draw-grapheme-on-screen-array:overflow/disp32 + 0f 85/jump-if-!= $draw-code-point-on-screen-array:overflow/disp32 # if (eax > ecx) abort 39/compare %eax 1/r32/ecx - 0f 8f/jump-if-> $draw-grapheme-on-screen-array:abort/disp32 + 0f 8f/jump-if-> $draw-code-point-on-screen-array:abort/disp32 } # eax = screen-data+4 (skip length) 8b/-> *(ebp+8) 0/r32/eax 05/add-to-eax 4/imm32 # - (draw-grapheme-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) # => eax -$draw-grapheme-on-screen-array:end: + (draw-code-point-on-screen-buffer %eax *(ebp+0xc) *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) # => eax +$draw-code-point-on-screen-array:end: # . restore registers 5a/pop-to-edx 59/pop-to-ecx @@ -58,30 +63,30 @@ $draw-grapheme-on-screen-array:end: 5d/pop-to-ebp c3/return -$draw-grapheme-on-screen-array:overflow: - (abort "draw-grapheme-on-screen-array: screen dimensions too large") +$draw-code-point-on-screen-array:overflow: + (abort "draw-code-point-on-screen-array: screen dimensions too large") -$draw-grapheme-on-screen-array:abort: - (abort "draw-grapheme-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?") +$draw-code-point-on-screen-array:abort: + (abort "draw-code-point-on-screen-array: coordinates are off the screen. Are the screen dimensions correct?") # 'buffer' here is not a valid Mu type: a naked address without a length. # returns number of 8x16 units printed to screen (1 or 2). -draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int +draw-code-point-on-screen-buffer: # buffer: (addr byte), c: code-point, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 56/push-esi - # switch screen-width and screen-height from grapheme to pixel units + # switch screen-width and screen-height from code-point to pixel units c1 4/subop/shift-left *(ebp+20) 3/imm8/log2-font-width c1 4/subop/shift-left *(ebp+24) 4/imm8/log2-font-height - # esi = g + # esi = c 8b/-> *(ebp+0xc) 6/r32/esi - # if (g >= 4352) return # unicode planes supported: latin, greek, cyrillic, armenian, hebrew, arabic, syriac, thaana, n'ko, indian (iscii), sinhala, thai, lao, tibetan, myanmar, georgian + # if (c >= 4352) return # unicode planes supported: latin, greek, cyrillic, armenian, hebrew, arabic, syriac, thaana, n'ko, indian (iscii), sinhala, thai, lao, tibetan, myanmar, georgian # next few to support: CJK, ethiopic, cherokee, ... 81 7/subop/compare %esi 0x1100/imm32 - 0f 8d/jump-if->= $draw-grapheme-on-screen-buffer:end/disp32 - # var letter-bitmap/esi = font[g] + 0f 8d/jump-if->= $draw-code-point-on-screen-buffer:end/disp32 + # var letter-bitmap/esi = font[c] 69/multiply %esi 0x21/imm32/glyph-size 6/r32/esi 81 0/subop/add %esi 0x0010000c/imm32/Font # see boot.subx # dispatch based on letter-bitmap->size @@ -91,13 +96,13 @@ draw-grapheme-on-screen-buffer: # buffer: (addr byte), g: grapheme, x: int, y: 3d/compare-eax-and 8/imm32 { 75/jump-if-!= break/disp8 - (draw-narrow-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + (draw-narrow-code-point-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) b8/copy-to-eax 1/imm32 - eb/jump $draw-grapheme-on-screen-buffer:end/disp8 + eb/jump $draw-code-point-on-screen-buffer:end/disp8 } - (draw-wide-grapheme-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) + (draw-wide-code-point-on-screen-buffer *(ebp+8) %esi *(ebp+0x10) *(ebp+0x14) *(ebp+0x18) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) b8/copy-to-eax 2/imm32 -$draw-grapheme-on-screen-buffer:end: +$draw-code-point-on-screen-buffer:end: # . restore registers 5e/pop-to-esi # . epilogue @@ -105,16 +110,16 @@ $draw-grapheme-on-screen-buffer:end: 5d/pop-to-ebp c3/return -wide-grapheme?: # g: grapheme -> _/eax: boolean +wide-code-point?: # c: code-point -> _/eax: boolean # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp - # eax = g + # eax = c 8b/-> *(ebp+8) 0/r32/eax - # if (g >= 128) return # characters beyond ASCII currently not supported + # if (c >= 128) return # characters beyond ASCII currently not supported 3d/compare-eax-and 0x80/imm32 - 0f 8d/jump-if->= $wide-grapheme?:end/disp32 - # var letter-bitmap/eax = font[g] + 0f 8d/jump-if->= $wide-code-point?:end/disp32 + # var letter-bitmap/eax = font[c] 69/multiply %eax 0x21/imm32/glyph-size 0/r32/eax 05/add-to-eax 0x0010000c/imm32/Font # see boot.subx # dispatch based on letter-bitmap->size @@ -122,7 +127,7 @@ wide-grapheme?: # g: grapheme -> _/eax: boolean 25/and-eax-with 0xff/imm32 3d/compare-eax-and 8/imm32 0f 95/set-if-!= %eax -$wide-grapheme?:end: +$wide-code-point?:end: # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp @@ -130,7 +135,7 @@ $wide-grapheme?:end: # buffer: naked address to raw screen RAM without a length # letter-bitmap: naked address to 8-pixel wide font glyph -draw-narrow-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, 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, screen-width: int, screen-height: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -163,7 +168,7 @@ draw-narrow-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (a # e9/jump loop/disp32 } -$draw-narrow-grapheme-on-screen-buffer:end: +$draw-narrow-code-point-on-screen-buffer:end: # . restore registers 5f/pop-to-edi 5e/pop-to-esi @@ -176,7 +181,7 @@ $draw-narrow-grapheme-on-screen-buffer:end: # buffer: naked address to raw screen RAM without a length # letter-bitmap: naked address to 16-pixel wide font glyph -draw-wide-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int +draw-wide-code-point-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (addr byte), x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -219,7 +224,7 @@ draw-wide-grapheme-on-screen-buffer: # buffer: (addr byte), letter-bitmap: (add # e9/jump loop/disp32 } -$draw-wide-grapheme-on-screen-buffer:end: +$draw-wide-code-point-on-screen-buffer:end: # . restore registers 5f/pop-to-edi 5e/pop-to-esi @@ -260,11 +265,11 @@ draw-run-of-pixels-from-glyph: # buffer: (addr byte), glyph-byte: byte, x: int, { 73/jump-if-not-CF break/disp8 (pixel-on-screen-buffer *(ebp+8) %eax *(ebp+0x14) *(ebp+0x18) *(ebp+0x20) *(ebp+0x24)) - eb/jump $draw-grapheme-on-screen-buffer:continue/disp8 + eb/jump $draw-code-point-on-screen-buffer:continue/disp8 } # otherwise use the background color (pixel-on-screen-buffer *(ebp+8) %eax *(ebp+0x14) *(ebp+0x1c) *(ebp+0x20) *(ebp+0x24)) -$draw-grapheme-on-screen-buffer:continue: +$draw-code-point-on-screen-buffer:continue: # --x 48/decrement-eax # @@ -318,7 +323,7 @@ $set-cursor-position-on-real-screen:end: # tracking what was on the screen at this position before and passing it # in again. # - does not stop showing the cursor at this location when the cursor moves -draw-cursor-on-real-screen: # g: grapheme +draw-cursor-on-real-screen: # c: code-point # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -327,7 +332,7 @@ draw-cursor-on-real-screen: # g: grapheme 51/push-ecx # (cursor-position-on-real-screen) # => eax, ecx - (draw-grapheme-on-real-screen *(ebp+8) %eax %ecx 0 7) # => eax + (draw-code-point-on-real-screen *(ebp+8) %eax %ecx 0 7) # => eax $draw-cursor-on-real-screen:end: # . restore registers 59/pop-to-ecx diff --git a/317abort.subx b/317abort.subx index e4f07971..6b0fc7c7 100644 --- a/317abort.subx +++ b/317abort.subx @@ -311,7 +311,7 @@ draw-slice-wrapping-right-then-down-from-cursor-over-full-screen: # screen: (ad 73/jump-if-addr>= break/disp8 # print *curr 8a/byte-> *ecx 0/r32/eax - (draw-grapheme-at-cursor-over-full-screen *(ebp+8) %eax *(ebp+0x14) *(ebp+0x18)) + (draw-code-point-at-cursor-over-full-screen *(ebp+8) %eax *(ebp+0x14) *(ebp+0x18)) # 41/increment-ecx # diff --git a/400.mu b/400.mu index fe2263a4..f0fe08f5 100644 --- a/400.mu +++ b/400.mu @@ -1,11 +1,11 @@ # screen sig pixel-on-real-screen x: int, y: int, color: int -sig draw-grapheme-on-real-screen g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax: int -sig draw-grapheme-on-screen-array screen-data: (addr array byte), g: grapheme, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int -sig wide-grapheme? g: grapheme -> _/eax: boolean +sig draw-code-point-on-real-screen c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int +sig draw-code-point-on-screen-array screen-data: (addr array byte), c: code-point, x: int, y: int, color: int, background-color: int, screen-width: int, screen-height: int -> _/eax: int +sig wide-code-point? c: code-point -> _/eax: boolean sig cursor-position-on-real-screen -> _/eax: int, _/ecx: int sig set-cursor-position-on-real-screen x: int, y: int -sig draw-cursor-on-real-screen g: grapheme +sig draw-cursor-on-real-screen c: code-point sig color-rgb color: int -> _/ecx: int, _/edx: int, _/ebx: int # timer diff --git a/403unicode.mu b/403unicode.mu index 6ec30c3d..be002311 100644 --- a/403unicode.mu +++ b/403unicode.mu @@ -7,18 +7,21 @@ # Graphemes may consist of multiple code points. # # Mu graphemes are always represented in utf-8, and they are required to fit -# in 4 bytes. +# in 4 bytes. (This can be confusing if you focus just on ASCII, where Mu's +# graphemes and code-points are identical.) # # Mu doesn't currently support combining code points, or graphemes made of # multiple code points. One day we will. -# We also don't currently support code points that translate into multiple -# or wide graphemes. (In particular, Tab will never be supported.) +# https://en.wikipedia.org/wiki/Combining_character + +fn to-code-point in: grapheme -> _/eax: code-point { + var g/eax: grapheme <- copy in + var result/eax: code-point <- copy g # TODO: support non-ASCII + return result +} # transliterated from tb_utf8_unicode_to_char in https://github.com/nsf/termbox # https://wiki.tcl-lang.org/page/UTF%2D8+bit+by+bit explains the algorithm -# -# The day we want to support combining characters, this function will need to -# take multiple code points. Or something. fn to-grapheme in: code-point -> _/eax: grapheme { var c/eax: int <- copy in var num-trailers/ecx: int <- copy 0 diff --git a/500fake-screen.mu b/500fake-screen.mu index 1e4f7b72..be7d9e0f 100644 --- a/500fake-screen.mu +++ b/500fake-screen.mu @@ -23,7 +23,7 @@ type screen { } type screen-cell { - data: grapheme + data: code-point color: int background-color: int unused?: boolean @@ -89,27 +89,27 @@ fn screen-size _screen: (addr screen) -> _/eax: int, _/ecx: int { # testable screen primitive # return number of 8x16 units drawn -fn draw-grapheme _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int -> _/eax: int { +fn draw-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 <- draw-grapheme-on-real-screen g, x, y, color, background-color + var result/eax: int <- draw-code-point-on-real-screen c, x, y, color, background-color return result } # fake screen - var wide?/eax: boolean <- wide-grapheme? g + var wide?/eax: boolean <- wide-code-point? c compare wide?, 0/false { break-if-= - draw-wide-grapheme-on-fake-screen screen, g, x, y, color, background-color + draw-wide-code-point-on-fake-screen screen, c, x, y, color, background-color return 2 } - draw-narrow-grapheme-on-fake-screen screen, g, x, y, color, background-color + draw-narrow-code-point-on-fake-screen screen, c, x, y, color, background-color return 1 } -fn draw-narrow-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, 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 # ignore if out of bounds { @@ -145,9 +145,9 @@ fn draw-narrow-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: i var data/eax: (addr array screen-cell) <- lookup *data-ah var offset/ecx: (offset screen-cell) <- compute-offset data, index var dest-cell/ecx: (addr screen-cell) <- index data, offset - var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data - var g2/edx: grapheme <- copy g - copy-to *dest-grapheme, g2 + var dest-code-point/eax: (addr code-point) <- get dest-cell, data + var c2/edx: code-point <- copy c + copy-to *dest-code-point, c2 var dest-color/eax: (addr int) <- get dest-cell, color var src-color/edx: int <- copy color copy-to *dest-color, src-color @@ -158,7 +158,7 @@ fn draw-narrow-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: i copy-to *dest, 0/false } -fn draw-wide-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int, y: int, color: int, background-color: int { +fn draw-wide-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 { @@ -169,7 +169,7 @@ fn draw-wide-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int { var xmax-addr/eax: (addr int) <- get screen, width var xmax/eax: int <- copy *xmax-addr - xmax <- decrement # wide graphemes need an extra unit + xmax <- decrement # wide code-points need an extra unit compare x, xmax break-if-< return @@ -193,9 +193,9 @@ fn draw-wide-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int var data/eax: (addr array screen-cell) <- lookup *data-ah var offset/ecx: (offset screen-cell) <- compute-offset data, index var dest-cell/ecx: (addr screen-cell) <- index data, offset - var dest-grapheme/eax: (addr grapheme) <- get dest-cell, data - var g2/edx: grapheme <- copy g - copy-to *dest-grapheme, g2 + var dest-code-point/eax: (addr code-point) <- get dest-cell, data + var c2/edx: code-point <- copy c + copy-to *dest-code-point, c2 var dest-color/eax: (addr int) <- get dest-cell, color var src-color/edx: int <- copy color copy-to *dest-color, src-color @@ -217,14 +217,6 @@ fn draw-wide-grapheme-on-fake-screen _screen: (addr screen), g: grapheme, x: int } } -# we can't really render non-ASCII yet, but when we do we'll be ready -# return number of 8x16 units drawn -fn draw-code-point screen: (addr screen), c: code-point, x: int, y: int, color: int, background-color: int -> _/eax: int { - var g/eax: grapheme <- copy c - var result/eax: int <- draw-grapheme screen, g, x, y, color, background-color - return result -} - # fake screens only fn screen-cell-index _screen: (addr screen), x: int, y: int -> _/ecx: int { var screen/esi: (addr screen) <- copy _screen @@ -298,18 +290,18 @@ fn set-cursor-position _screen: (addr screen), x: int, y: int { copy-to *dest, src } -fn draw-cursor screen: (addr screen), g: grapheme { +fn draw-cursor screen: (addr screen), c: code-point { { compare screen, 0 break-if-!= - draw-cursor-on-real-screen g + draw-cursor-on-real-screen c return } # fake screen var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen - var dummy/eax: int <- draw-grapheme screen, g, cursor-x, cursor-y, 0/fg, 7/bg + var dummy/eax: int <- draw-code-point screen, c, cursor-x, cursor-y, 0/fg, 7/bg } fn clear-screen _screen: (addr screen) { @@ -367,11 +359,11 @@ fn fake-screen-empty? _screen: (addr screen) -> _/eax: boolean { { compare x, *width break-if->= - var g/eax: grapheme <- screen-grapheme-at screen, x, y + var c/eax: code-point <- screen-code-point-at screen, x, y { - compare g, 0 + compare c, 0 break-if-= - compare g, 0x20/space + compare c, 0x20/space break-if-= return 0/false } @@ -506,21 +498,21 @@ fn screen-cell-unused-at-index? _screen: (addr screen), _index: int -> _/eax: bo return *src } -fn screen-grapheme-at _screen: (addr screen), x: int, y: int -> _/eax: grapheme { +fn screen-code-point-at _screen: (addr screen), x: int, y: int -> _/eax: code-point { var screen/esi: (addr screen) <- copy _screen var index/ecx: int <- screen-cell-index screen, x, y - var result/eax: grapheme <- screen-grapheme-at-index screen, index + var result/eax: code-point <- screen-code-point-at-index screen, index return result } -fn screen-grapheme-at-index _screen: (addr screen), _index: int -> _/eax: grapheme { +fn screen-code-point-at-index _screen: (addr screen), _index: int -> _/eax: code-point { var screen/esi: (addr screen) <- copy _screen var data-ah/eax: (addr handle array screen-cell) <- get screen, data var data/eax: (addr array screen-cell) <- lookup *data-ah var index/ecx: int <- copy _index var offset/ecx: (offset screen-cell) <- compute-offset data, index var cell/eax: (addr screen-cell) <- index data, offset - var src/eax: (addr grapheme) <- get cell, data + var src/eax: (addr code-point) <- get cell, data return *src } @@ -661,11 +653,11 @@ fn copy-pixels _screen: (addr screen), target-screen: (addr screen) { } } -# It turns out double-buffering graphemes is useless because rendering fonts +# It turns out double-buffering screen-cells is useless because rendering fonts # takes too long. (At least under Qemu.) -# So we'll instead convert graphemes to pixels when double-buffering. +# So we'll instead convert screen-cells to pixels when double-buffering. # 'screen' must be a fake screen. -fn convert-graphemes-to-pixels _screen: (addr screen) { +fn convert-screen-cells-to-pixels _screen: (addr screen) { var screen/esi: (addr screen) <- copy _screen var width-a/ebx: (addr int) <- get screen, width var height-a/edx: (addr int) <- get screen, height @@ -678,25 +670,25 @@ fn convert-graphemes-to-pixels _screen: (addr screen) { compare y, *height-a break-if->= var x/edi: int <- copy 0 - $convert-graphemes-to-pixels:loop-x: { + $convert-screen-cells-to-pixels:loop-x: { compare x, *width-a break-if->= { - var tmp/eax: grapheme <- screen-grapheme-at screen, x, y - # skip null graphemes that only get created when clearing screen + var tmp/eax: code-point <- screen-code-point-at screen, x, y + # skip null code-points that only get created when clearing screen # there may be other pixels drawn there, and we don't want to clobber them - # this is a situation where fake screens aren't faithful to real screens; we don't support overlap between graphemes and raw pixels + # this is a situation where fake screens aren't faithful to real screens; we don't support overlap between screen-cells and raw pixels compare tmp, 0 break-if-= - var g: grapheme - copy-to g, tmp + var c: code-point + copy-to c, tmp var tmp/eax: int <- screen-color-at screen, x, y var fg: int copy-to fg, tmp var bg/eax: int <- screen-background-color-at screen, x, y - var offset/eax: int <- draw-grapheme-on-screen-array data, g, x, y, fg, bg, *width-a, *height-a + var offset/eax: int <- draw-code-point-on-screen-array data, c, x, y, fg, bg, *width-a, *height-a x <- add offset - loop $convert-graphemes-to-pixels:loop-x + loop $convert-screen-cells-to-pixels:loop-x } x <- increment loop diff --git a/501draw-text.mu b/501draw-text.mu index 4a415ddd..0b74c160 100644 --- a/501draw-text.mu +++ b/501draw-text.mu @@ -81,11 +81,11 @@ fn move-cursor-to-left-margin-of-next-line screen: (addr screen) { set-cursor-position screen, cursor-x, cursor-y } -fn draw-grapheme-at-cursor-over-full-screen screen: (addr screen), g: grapheme, color: int, background-color: int { +fn draw-code-point-at-cursor-over-full-screen screen: (addr screen), c: code-point, color: int, background-color: int { var cursor-x/eax: int <- copy 0 var cursor-y/ecx: int <- copy 0 cursor-x, cursor-y <- cursor-position screen - var _offset/eax: int <- draw-grapheme screen, g, cursor-x, cursor-y, color, background-color + var _offset/eax: int <- draw-code-point screen, c, cursor-x, cursor-y, color, background-color var offset/edx: int <- copy _offset var width/eax: int <- copy 0 var dummy/ecx: int <- copy 0 @@ -100,11 +100,6 @@ fn draw-grapheme-at-cursor-over-full-screen screen: (addr screen), g: grapheme, } } -fn draw-code-point-at-cursor-over-full-screen screen: (addr screen), c: code-point, color: int, background-color: int { - var g/eax: grapheme <- copy c - draw-grapheme-at-cursor-over-full-screen screen, g, color, background-color -} - # draw a single line of text from x, y to xmax # return the next 'x' coordinate # if there isn't enough space, truncate @@ -125,7 +120,8 @@ fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: i var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= - var offset/eax: int <- draw-grapheme screen, g, xcurr, y, color, background-color + var c/eax: code-point <- to-code-point g + var offset/eax: int <- draw-code-point screen, c, xcurr, y, color, background-color xcurr <- add offset loop } @@ -156,8 +152,8 @@ fn draw-text-rightward-from-cursor-over-full-screen screen: (addr screen), text: draw-text-rightward-from-cursor screen, text, width, color, background-color } -fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { - compare g, 0xa/newline +fn render-code-point screen: (addr screen), c: code-point, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { + compare c, 0xa/newline var x/ecx: int <- copy x { break-if-!= @@ -167,7 +163,7 @@ fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xma increment y return x, y } - var offset/eax: int <- draw-grapheme screen, g, x, y, color, background-color + var offset/eax: int <- draw-code-point screen, c, x, y, color, background-color x <- add offset compare x, xmax { @@ -210,15 +206,16 @@ fn draw-text-wrapping-right-then-down screen: (addr screen), _text: (addr array fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int { var xcurr/eax: int <- copy x var ycurr/ecx: int <- copy y - var g/ebx: grapheme <- copy 0 + var c/ebx: code-point <- copy 0 { { - var _g/eax: grapheme <- read-grapheme stream - g <- copy _g + var g/eax: grapheme <- read-grapheme stream + var _c/eax: code-point <- to-code-point g + c <- copy _c } - compare g, 0xffffffff/end-of-file + compare c, 0xffffffff/end-of-file break-if-= - xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + xcurr, ycurr <- render-code-point screen, c, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color loop } set-cursor-position screen, xcurr, ycurr @@ -301,7 +298,8 @@ fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin: var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= - var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color + var c/eax: code-point <- to-code-point g + var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color xcurr <- add offset compare xcurr, xmax { @@ -355,7 +353,8 @@ fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xm var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= - var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color + var c/eax: code-point <- to-code-point g + var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color xcurr <- add offset compare xcurr, xmax { @@ -422,7 +421,8 @@ fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: in var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= - var dummy/eax: int <- draw-grapheme screen, g, x, ycurr, color, background-color + var c/eax: code-point <- to-code-point g + var dummy/eax: int <- draw-code-point screen, c, x, ycurr, color, background-color ycurr <- increment loop } @@ -463,7 +463,8 @@ fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr str var g/eax: grapheme <- read-grapheme stream compare g, 0xffffffff/end-of-file break-if-= - var offset/eax: int <- draw-grapheme screen, g, xcurr, ycurr, color, background-color + var c/eax: code-point <- to-code-point g + var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color ycurr <- increment compare ycurr, ymax { diff --git a/504test-screen.mu b/504test-screen.mu index aef85ac6..f43c6386 100644 --- a/504test-screen.mu +++ b/504test-screen.mu @@ -24,32 +24,33 @@ fn check-screen-row-from _screen: (addr screen), x: int, y: int, expected: (addr var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index compare unused?, 0/false break-if-!= - var _g/eax: grapheme <- screen-grapheme-at-index screen, index - var g/ebx: grapheme <- copy _g + var _c/eax: code-point <- screen-code-point-at-index screen, index + var c/ebx: code-point <- copy _c var expected-grapheme/eax: grapheme <- read-grapheme e-addr + var expected-code-point/eax: code-point <- to-code-point expected-grapheme # compare graphemes $check-screen-row-from:compare-graphemes: { - # if expected-grapheme is space, null grapheme is also ok + # if expected-code-point is space, null grapheme is also ok { - compare expected-grapheme, 0x20 + compare expected-code-point, 0x20 break-if-!= - compare g, 0 + compare c, 0 break-if-= $check-screen-row-from:compare-graphemes } - # if (g == expected-grapheme) print "." - compare g, expected-grapheme + # if (c == expected-code-point) print "." + compare c, expected-code-point break-if-= # otherwise print an error failure-count <- increment draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, expected-grapheme, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, g, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, c, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg move-cursor-to-left-margin-of-next-line 0/screen } @@ -90,21 +91,22 @@ fn check-screen-row-in-color-from _screen: (addr screen), fg: int, y: int, x: in var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index compare unused?, 0/false break-if-!= - var _g/eax: grapheme <- screen-grapheme-at-index screen, index - var g/ebx: grapheme <- copy _g - var _expected-grapheme/eax: grapheme <- read-grapheme e-addr - var expected-grapheme/edi: grapheme <- copy _expected-grapheme + var _c/eax: code-point <- screen-code-point-at-index screen, index + var c/ebx: code-point <- copy _c + var expected-grapheme/eax: grapheme <- read-grapheme e-addr + var _expected-code-point/eax: code-point <- to-code-point expected-grapheme + var expected-code-point/edi: code-point <- copy _expected-code-point $check-screen-row-in-color-from:compare-cells: { - # if expected-grapheme is space, null grapheme is also ok + # if expected-code-point is space, null grapheme is also ok { - compare expected-grapheme, 0x20 + compare expected-code-point, 0x20 break-if-!= - compare g, 0 + compare c, 0 break-if-= $check-screen-row-in-color-from:compare-cells } - # if expected-grapheme is space, a different color is ok + # if expected-code-point is space, a different color is ok { - compare expected-grapheme, 0x20 + compare expected-code-point, 0x20 break-if-!= var color/eax: int <- screen-color-at-index screen, index compare color, fg @@ -112,8 +114,8 @@ fn check-screen-row-in-color-from _screen: (addr screen), fg: int, y: int, x: in } # compare graphemes $check-screen-row-in-color-from:compare-graphemes: { - # if (g == expected-grapheme) print "." - compare g, expected-grapheme + # if (c == expected-code-point) print "." + compare c, expected-code-point { break-if-!= draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg @@ -123,13 +125,13 @@ fn check-screen-row-in-color-from _screen: (addr screen), fg: int, y: int, x: in count-test-failure draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, expected-grapheme, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, g, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, c, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg move-cursor-to-left-margin-of-next-line 0/screen } @@ -145,7 +147,7 @@ fn check-screen-row-in-color-from _screen: (addr screen), fg: int, y: int, x: in count-test-failure draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, expected-grapheme, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg @@ -183,21 +185,22 @@ fn check-screen-row-in-background-color-from _screen: (addr screen), bg: int, y: var unused?/eax: boolean <- screen-cell-unused-at-index? screen, index compare unused?, 0/false break-if-!= - var _g/eax: grapheme <- screen-grapheme-at-index screen, index - var g/ebx: grapheme <- copy _g - var _expected-grapheme/eax: grapheme <- read-grapheme e-addr - var expected-grapheme/edi: grapheme <- copy _expected-grapheme + var _g/eax: code-point <- screen-code-point-at-index screen, index + var g/ebx: code-point <- copy _g + var expected-grapheme/eax: grapheme <- read-grapheme e-addr + var _expected-code-point/eax: code-point <- to-code-point expected-grapheme + var expected-code-point/edi: code-point <- copy _expected-code-point $check-screen-row-in-background-color-from:compare-cells: { - # if expected-grapheme is space, null grapheme is also ok + # if expected-code-point is space, null grapheme is also ok { - compare expected-grapheme, 0x20 + compare expected-code-point, 0x20 break-if-!= compare g, 0 break-if-= $check-screen-row-in-background-color-from:compare-cells } - # if expected-grapheme is space, a different background-color is ok + # if expected-code-point is space, a different background-color is ok { - compare expected-grapheme, 0x20 + compare expected-code-point, 0x20 break-if-!= var background-color/eax: int <- screen-background-color-at-index screen, index compare background-color, bg @@ -205,8 +208,8 @@ fn check-screen-row-in-background-color-from _screen: (addr screen), bg: int, y: } # compare graphemes $check-screen-row-in-background-color-from:compare-graphemes: { - # if (g == expected-grapheme) print "." - compare g, expected-grapheme + # if (g == expected-code-point) print "." + compare g, expected-code-point { break-if-!= draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg/cyan, 0/bg @@ -216,13 +219,13 @@ fn check-screen-row-in-background-color-from _screen: (addr screen), bg: int, y: count-test-failure draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, expected-grapheme, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, y, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ") but observed '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, g, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, g, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "'", 3/fg/cyan, 0/bg move-cursor-to-left-margin-of-next-line 0/screen break $check-screen-row-in-background-color-from:compare-graphemes @@ -239,7 +242,7 @@ fn check-screen-row-in-background-color-from _screen: (addr screen), bg: int, y: count-test-failure draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, msg, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ": expected '", 3/fg/cyan, 0/bg - draw-grapheme-at-cursor-over-full-screen 0/screen, expected-grapheme, 3/cyan, 0/bg + draw-code-point-at-cursor-over-full-screen 0/screen, expected-code-point, 3/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "' at (", 3/fg/cyan, 0/bg draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, x, 3/fg/cyan, 0/bg draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ", ", 3/fg/cyan, 0/bg diff --git a/513grapheme-stack.mu b/513grapheme-stack.mu index 2db873a0..40deb052 100644 --- a/513grapheme-stack.mu +++ b/513grapheme-stack.mu @@ -98,7 +98,12 @@ fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _sel compare i, *top-addr break-if->= { - var g/esi: (addr grapheme) <- index data, i + var c: code-point + { + var g/eax: (addr grapheme) <- index data, i + var tmp/eax: code-point <- to-code-point *g + copy-to c, tmp + } var fg: int { var tmp/eax: int <- copy color @@ -109,7 +114,7 @@ fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _sel break-if-!= copy-to fg, 0xf/highlight } - x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, fg, background-color + x, y <- render-code-point screen, c, xmin, ymin, xmax, ymax, x, y, fg, background-color } i <- increment loop @@ -152,8 +157,13 @@ fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: break-if-= compare i, 0 break-if-< - var g/esi: (addr grapheme) <- index data, i - x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, background-color, color + var c: code-point + { + var g/eax: (addr grapheme) <- index data, i + var tmp/eax: code-point <- to-code-point *g + copy-to c, tmp + } + x, y <- render-code-point screen, c, xmin, ymin, xmax, ymax, x, y, background-color, color i <- decrement } # remaining iterations @@ -172,8 +182,13 @@ fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: copy-to fg, 0xf/highlight } # - var g/esi: (addr grapheme) <- index data, i - x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, fg, background-color + var c: code-point + { + var g/eax: (addr grapheme) <- index data, i + var tmp/eax: code-point <- to-code-point *g + copy-to c, tmp + } + x, y <- render-code-point screen, c, xmin, ymin, xmax, ymax, x, y, fg, background-color i <- decrement loop } diff --git a/514gap-buffer.mu b/514gap-buffer.mu index 39745d1f..4acab54d 100644 --- a/514gap-buffer.mu +++ b/514gap-buffer.mu @@ -409,8 +409,8 @@ fn render-gap-buffer-wrapping-right-then-down screen: (addr screen), _gap: (addr bg <- copy color } # print a grapheme either way so that cursor position doesn't affect printed width - var space/edx: grapheme <- copy 0x20 - x2, y2 <- render-grapheme screen, space, xmin, ymin, xmax, ymax, x2, y2, fg, bg + var space/edx: code-point <- copy 0x20 + x2, y2 <- render-code-point screen, space, xmin, ymin, xmax, ymax, x2, y2, fg, bg return x2, y2 } diff --git a/apps/colors.mu b/apps/colors.mu index c58fec35..3d9f1bc1 100644 --- a/apps/colors.mu +++ b/apps/colors.mu @@ -27,8 +27,8 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) loop-if-= var key2/eax: int <- copy key append-byte in, key2 - var g/eax: grapheme <- copy key2 - draw-grapheme-at-cursor-over-full-screen screen, g, 0xf/fg, 0/bg + var c/eax: code-point <- copy key2 # TODO: unicode input + draw-code-point-at-cursor-over-full-screen screen, c, 0xf/fg, 0/bg loop } clear-screen screen diff --git a/apps/rpn.mu b/apps/rpn.mu index ac54457d..4fd8ccb6 100644 --- a/apps/rpn.mu +++ b/apps/rpn.mu @@ -19,7 +19,7 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) var in-storage: (stream byte 0x80) var in/esi: (addr stream byte) <- address in-storage var y/ecx: int <- copy 0 - var space/edx: grapheme <- copy 0x20 + var space/edx: code-point <- copy 0x20 # read-eval-print loop { # print prompt @@ -35,12 +35,12 @@ fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) loop-if-= var key2/eax: int <- copy key append-byte in, key2 - var g/eax: grapheme <- copy key2 - draw-grapheme-at-cursor-over-full-screen screen, g, 0xf/fg, 0/bg + var c/eax: code-point <- copy key2 + draw-code-point-at-cursor-over-full-screen screen, c, 0xf/fg, 0/bg loop } # clear cursor - draw-grapheme-at-cursor-over-full-screen screen, space, 3/fg/never-used, 0/bg + draw-code-point-at-cursor-over-full-screen screen, space, 3/fg/never-used, 0/bg # parse and eval var out/eax: int <- simplify in # print diff --git a/browse-slack/environment.mu b/browse-slack/environment.mu index 0b829d1d..6277d53a 100644 --- a/browse-slack/environment.mu +++ b/browse-slack/environment.mu @@ -378,7 +378,7 @@ fn render-search-input screen: (addr screen), _env: (addr environment) { compare x, 0x4a/end-search break-if-> var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x5f/underscore, 0/xmin 1/ymin, 0x80/xmax, 1/ymax, x, 1/y, 0xf/fg 0/bg + x, y <- render-code-point screen, 0x5f/underscore, 0/xmin 1/ymin, 0x80/xmax, 1/ymax, x, 1/y, 0xf/fg 0/bg loop } } @@ -580,17 +580,17 @@ fn draw-json-stream-wrapping-right-then-down screen: (addr screen), stream: (add var xcurr/eax: int <- copy x var ycurr/ecx: int <- copy y { - var g/ebx: grapheme <- read-json-grapheme stream - compare g, 0xffffffff/end-of-file + var c/ebx: code-point <- read-json-code-point stream + compare c, 0xffffffff/end-of-file break-if-= $draw-json-stream-wrapping-right-then-down:render-grapheme: { - compare g, 0x5c/backslash + compare c, 0x5c/backslash { break-if-!= - xcurr, ycurr <- render-json-escaped-grapheme screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + xcurr, ycurr <- render-json-escaped-code-point screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color break $draw-json-stream-wrapping-right-then-down:render-grapheme } - xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + xcurr, ycurr <- render-code-point screen, c, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color } loop } @@ -599,15 +599,16 @@ fn draw-json-stream-wrapping-right-then-down screen: (addr screen), stream: (add } # just return a different register -fn read-json-grapheme stream: (addr stream byte) -> _/ebx: grapheme { - var result/eax: grapheme <- read-grapheme stream +fn read-json-code-point stream: (addr stream byte) -> _/ebx: code-point { + var g/eax: grapheme <- read-grapheme stream + var result/eax: code-point <- to-code-point g return result } # '\' encountered # https://www.json.org/json-en.html -fn render-json-escaped-grapheme screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int { - var g/ebx: grapheme <- read-json-grapheme stream +fn render-json-escaped-code-point screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int { + var g/ebx: code-point <- read-json-code-point stream compare g, 0xffffffff/end-of-file { break-if-!= @@ -647,16 +648,16 @@ fn render-json-escaped-grapheme screen: (addr screen), stream: (addr stream byte { compare g, 0x75/u break-if-!= - x, y <- render-json-escaped-unicode-grapheme screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-json-escaped-unicode-code-point screen, stream, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # most characters escape to themselves - x, y <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # '\u' encountered -fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int { +fn render-json-escaped-unicode-code-point screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, xcurr: int, ycurr: int, color: int, background-color: int -> _/eax: int, _/ecx: int { var ustream-storage: (stream byte 4) var ustream/esi: (addr stream byte) <- address ustream-storage # slurp 4 bytes exactly @@ -679,7 +680,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u2014 = - @@ -689,7 +690,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x2d/dash, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u2018 = ' @@ -699,7 +700,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u2019 = ' @@ -709,7 +710,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x27/quote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u201c = " @@ -719,7 +720,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u201d = " @@ -729,7 +730,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x22/dquote, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u2022 = * @@ -739,7 +740,7 @@ fn render-json-escaped-unicode-grapheme screen: (addr screen), stream: (addr str break-if-= var x/eax: int <- copy 0 var y/ecx: int <- copy 0 - x, y <- render-grapheme screen, 0x2a/asterisk, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color + x, y <- render-code-point screen, 0x2a/asterisk, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color return x, y } # \u2026 = ... diff --git a/linux/403unicode.mu b/linux/403unicode.mu index 9f857c7f..2baefd9f 100644 --- a/linux/403unicode.mu +++ b/linux/403unicode.mu @@ -11,14 +11,11 @@ # # Mu doesn't currently support combining code points, or graphemes made of # multiple code points. One day we will. -# We also don't currently support code points that translate into multiple -# or wide graphemes. (In particular, Tab will never be supported.) +# On Linux, we also don't currently support code points that translate into +# multiple or wide graphemes. (In particular, Tab will never be supported.) # transliterated from tb_utf8_unicode_to_char in https://github.com/nsf/termbox # https://wiki.tcl-lang.org/page/UTF%2D8+bit+by+bit explains the algorithm -# -# The day we want to support combining characters, this function will need to -# take multiple code points. Or something. fn to-grapheme in: code-point -> _/eax: grapheme { var c/eax: int <- copy in var num-trailers/ecx: int <- copy 0 diff --git a/shell/primitives.mu b/shell/primitives.mu index d38eedbc..e955b531 100644 --- a/shell/primitives.mu +++ b/shell/primitives.mu @@ -3493,7 +3493,7 @@ fn apply-blit _args-ah: (addr handle cell), out: (addr handle cell), trace: (add var dest-ah/eax: (addr handle screen) <- get second, screen-data var dest/eax: (addr screen) <- lookup *dest-ah # - convert-graphemes-to-pixels src + convert-screen-cells-to-pixels src copy-pixels src, dest } diff --git a/shell/sandbox.mu b/shell/sandbox.mu index eb752b14..d50f47f0 100644 --- a/shell/sandbox.mu +++ b/shell/sandbox.mu @@ -255,8 +255,8 @@ fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmi fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int { var target-screen/esi: (addr screen) <- copy _target-screen - convert-graphemes-to-pixels target-screen # might overwrite existing pixel data with graphemes - # overlapping the two is not supported + convert-screen-cells-to-pixels target-screen # might overwrite existing pixel data with screen cells + # overlapping the two is not supported # pixel data { # screen top left pixels x y width height @@ -383,10 +383,10 @@ fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen var index/ecx: int <- screen-cell-index target, x, y var offset/ecx: (offset screen-cell) <- compute-offset data, index var src-cell/esi: (addr screen-cell) <- index data, offset - var src-grapheme/eax: (addr grapheme) <- get src-cell, data + var src-code-point/eax: (addr code-point) <- get src-cell, data var src-color/ecx: (addr int) <- get src-cell, color var src-background-color/edx: (addr int) <- get src-cell, background-color - draw-grapheme-at-cursor-over-full-screen screen, *src-grapheme, *src-color, *src-background-color + draw-code-point-at-cursor-over-full-screen screen, *src-code-point, *src-color, *src-background-color } fn render-sandbox-edit-menu screen: (addr screen), _self: (addr sandbox) {