Move changed fragments detection to ScreenBuffer

openid
Marcin Kulik 13 years ago
parent 1e4864e51e
commit 282511b60e

@ -30,3 +30,13 @@ class AsciiIo.Brush
hash: -> hash: ->
AsciiIo.Brush.hash(this) AsciiIo.Brush.hash(this)
fgColor: ->
color = @fg || 7
color += 8 if color < 8 and @bright
color
bgColor: ->
color = @bg || 0
color += 8 if color < 8 and @blink
color

@ -13,9 +13,9 @@ class AsciiIo.Renderer.Base extends Backbone.View
@hideToggleOverlay() @hideToggleOverlay()
render: (changes, cursorX, cursorY) -> render: (changes, cursorX, cursorY) ->
for n, data of changes for n, fragments of changes
c = if parseInt(n) is cursorY then cursorX else undefined c = if parseInt(n) is cursorY then cursorX else undefined
@renderLine n, data || [], c @renderLine n, fragments || [], c
renderLine: (n, data, cursorX) -> renderLine: (n, data, cursorX) ->
throw '#renderLine not implemented' throw '#renderLine not implemented'

@ -17,54 +17,39 @@ class AsciiIo.Renderer.Canvas extends AsciiIo.Renderer.Base
@$el.attr('width', width) @$el.attr('width', width)
@$el.attr('height', height) @$el.attr('height', height)
@setFont() @setFont()
# @$el.css(width: width + 'px', height: height + 'px')
# @ctx.scale(1, 1)
setFont: -> setFont: ->
size = @$el.css('font-size') size = @$el.css('font-size')
console.log size # console.log size
family = @$el.css('font-family') family = @$el.css('font-family')
console.log family # console.log family
@font = "#{size} #{family}" @font = "#{size} #{family}"
@ctx.font = @font @ctx.font = @font
@prevFont = @font @prevFont = @font
@ctx.textBaseline = 'bottom' @ctx.textBaseline = 'bottom'
renderLine: (n, data, cursorX) -> renderLine: (n, fragments, cursorX) ->
left = 0 left = 0
width = @cols * @cellWidth width = @cols * @cellWidth
top = n * @cellHeight top = n * @cellHeight
for i in [0...@cols] for fragment in fragments
d = data[i] [text, brush] = fragment
if d @setBackgroundAttributes(brush)
[char, brush] = d @ctx.fillRect left, top, text.length * @cellWidth, @cellHeight
@setBackgroundAttributes(brush) # if char != ' '
@ctx.fillRect left + i * @cellWidth, top, @cellWidth, @cellHeight @setTextAttributes(brush)
@ctx.fillText text, left, top + @cellHeight
if char != ' ' left += text.length * @cellWidth
@setTextAttributes(brush)
@ctx.fillText char, i * @cellWidth, top + @cellHeight
setBackgroundAttributes: (brush) -> setBackgroundAttributes: (brush) ->
if brush.bg isnt undefined @ctx.fillStyle = AsciiIo.colors[brush.bgColor()]
bg = brush.bg
bg += 8 if bg < 8 and brush.blink
else
bg = 0
@ctx.fillStyle = AsciiIo.colors[bg]
setTextAttributes: (brush) -> setTextAttributes: (brush) ->
if brush.fg isnt undefined @ctx.fillStyle = AsciiIo.colors[brush.fgColor()]
fg = brush.fg
fg += 8 if fg < 8 and brush.bright
else
fg = 7
@ctx.fillStyle = AsciiIo.colors[fg]
font = @font font = @font

@ -23,11 +23,12 @@ class AsciiIo.Renderer.Pre extends AsciiIo.Renderer.Base
@fixSize() @fixSize()
initialRender: -> initialRender: ->
brush = AsciiIo.Brush.normal()
changes = {} changes = {}
i = 0 i = 0
while i < @lines while i < @lines
changes[i] = undefined changes[i] = [[' '.times(@cols), brush]]
i += 1 i += 1
@render(changes, 0, 0) @render(changes, 0, 0)
@ -41,53 +42,50 @@ class AsciiIo.Renderer.Pre extends AsciiIo.Renderer.Base
@$el.find('.cursor').removeClass('cursor') @$el.find('.cursor').removeClass('cursor')
super(changes, cursorX, cursorY) super(changes, cursorX, cursorY)
renderLine: (n, data, cursorX) -> renderLine: (n, fragments, cursorX) ->
html = [] html = []
prevBrush = undefined
for i in [0...@cols] rendered = 0
d = data[i]
if d for fragment in fragments
[char, brush] = d [text, brush] = fragment
char = char.replace('&', '&amp;').replace('<', '&lt;') if cursorX isnt undefined and rendered < cursorX < rendered + text.length
left = text.slice(0, cursorX - rendered)
cursor =
'<span class="cursor visible">' + text[cursorX - rendered] + '</span>'
right = text.slice(cursorX - rendered + 1)
if brush != prevBrush or i is cursorX or i is (cursorX + 1) t = @escape(left) + cursor + @escape(right)
if prevBrush
html.push '</span>'
html.push @spanFromBrush(brush, i is cursorX)
prevBrush = brush
html.push char
else else
html.push ' ' t = @escape(text)
html.push '</span>' if prevBrush html.push @spanFromBrush(brush)
html.push t
html.push '</span>'
rendered += text.length
@$el.find(".line:eq(" + n + ")")[0].innerHTML = '<span>' + html.join('') + '</span>' @$el.find(".line:eq(" + n + ")")[0].innerHTML = '<span>' + html.join('') + '</span>'
spanFromBrush: (brush, hasCursor) -> escape: (text) ->
key = "#{brush.hash()}_#{hasCursor}" text.replace('&', '&amp;').replace('<', '&lt;')
spanFromBrush: (brush) ->
key = brush.hash()
span = @cachedSpans[key] span = @cachedSpans[key]
if not span if not span
span = "" span = ""
if hasCursor or brush != AsciiIo.Brush.normal() if brush != AsciiIo.Brush.normal()
span = "<span class=\"" span = "<span class=\""
if brush.fg isnt undefined if brush.fg isnt undefined
fg = brush.fg span += " fg" + brush.fgColor()
fg += 8 if fg < 8 and brush.bright
span += " fg" + fg
if brush.bg isnt undefined if brush.bg isnt undefined
bg = brush.bg span += " bg" + brush.bgColor()
bg += 8 if bg < 8 and brush.blink
span += " bg" + bg
if brush.bright if brush.bright
span += " bright" span += " bright"
@ -98,7 +96,6 @@ class AsciiIo.Renderer.Pre extends AsciiIo.Renderer.Base
if brush.italic if brush.italic
span += " italic" span += " italic"
span += " cursor visible" if hasCursor
span += "\">" span += "\">"
@cachedSpans[key] = span @cachedSpans[key] = span

@ -7,7 +7,7 @@ class AsciiIo.ScreenBuffer
@cursorX = 0 @cursorX = 0
@cursorY = 0 @cursorY = 0
@setBrush AsciiIo.Brush.create({}) @setBrush AsciiIo.Brush.normal()
@setCharset 'us' @setCharset 'us'
topMargin: -> topMargin: ->
@ -17,7 +17,7 @@ class AsciiIo.ScreenBuffer
@scrollRegion.getBottom() @scrollRegion.getBottom()
updateLine: (n = @cursorY) -> updateLine: (n = @cursorY) ->
@dirtyLines[n] = @lineData[n] @dirtyLines[n] = true
updateLines: (a, b) -> updateLines: (a, b) ->
n = a n = a
@ -29,7 +29,34 @@ class AsciiIo.ScreenBuffer
@updateLine n for n in [0...@lines] @updateLine n for n in [0...@lines]
changes: -> changes: ->
@dirtyLines changes = {}
for n, _ of @dirtyLines
data = @lineData[n] || []
fragments = []
currentBrush = AsciiIo.Brush.normal()
currentText = ''
for i in [0...@cols]
d = data[i]
if d
[char, brush] = d
else
[char, brush] = [' ', currentBrush]
if brush == currentBrush
currentText += char
else
fragments.push([currentText, currentBrush]) if currentText.length > 0
currentText = char
currentBrush = brush
fragments.push([currentText, currentBrush]) if currentText.length > 0
changes[n] = fragments
changes
clearChanges: -> clearChanges: ->
@dirtyLines = {} @dirtyLines = {}

Loading…
Cancel
Save