Skip to content

Commit

Permalink
Merge pull request #474 from as-cii/use-new-display-layers-apis
Browse files Browse the repository at this point in the history
Start using new DisplayLayer APIs
  • Loading branch information
abe33 committed Apr 21, 2016
2 parents 2c32395 + c3a1376 commit ae7b9bc
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 36 deletions.
2 changes: 1 addition & 1 deletion lib/adapters/legacy-adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default class LegacyAdater {
if (this.maxScrollTopCache != null && this.useCache) {
return this.maxScrollTopCache
}
var maxScrollTop = this.textEditor.displayBuffer.getMaxScrollTop()
var maxScrollTop = this.textEditor.getMaxScrollTop()
var lineHeight = this.textEditor.getLineHeightInPixels()

if (this.scrollPastEnd) {
Expand Down
3 changes: 2 additions & 1 deletion lib/minimap.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ export default class Minimap {
resulting in extra lines appearing at the end of the minimap.
Forcing a whole repaint to fix that bug is suboptimal but works.
*/
subs.add(this.textEditor.displayBuffer.onDidTokenize(() => {
let tokenizedBuffer = this.textEditor.tokenizedBuffer ? this.textEditor.tokenizedBuffer : this.textEditor.displayBuffer.tokenizedBuffer
subs.add(tokenizedBuffer.onDidTokenize(() => {
this.emitter.emit('did-change-config')
}))
}
Expand Down
119 changes: 89 additions & 30 deletions lib/mixins/canvas-drawer.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ export default class CanvasDrawer extends Mixin {
for (let i = 0, len = ranges.length; i < len; i++) {
const range = ranges[i]

method.call(this, currentRow, range.start - 1, currentRow - firstRow)
method.call(this, currentRow, range.start, currentRow - firstRow)

currentRow = range.end
}
Expand Down Expand Up @@ -401,6 +401,56 @@ export default class CanvasDrawer extends Mixin {

renderData.context.fill()
}

/**
* Returns an array of tokens by line.
*
* @param {number} startRow The start row
* @param {number} endRow The end row
* @return {Array<Array>} An array of tokens by line
* @access private
*/
tokenLinesForScreenRows (startRow, endRow) {
const editor = this.getTextEditor()
let tokenLines = []
if (typeof editor.tokenizedLinesForScreenRows === 'function') {
for (let tokenizedLine of editor.tokenizedLinesForScreenRows(startRow, endRow)) {
const invisibleRegExp = this.getInvisibleRegExpForLine(tokenizedLine)
tokenLines.push(tokenizedLine.tokens.map((token) => {
return {
value: token.value.replace(invisibleRegExp, ' '),
scopes: token.scopes.slice()
}
}))
}
} else {
const displayLayer = editor.displayLayer
const invisibleRegExp = this.getInvisibleRegExp()
const screenLines = displayLayer.getScreenLines(startRow, endRow)
for (let {lineText, tagCodes} of screenLines) {
let tokens = []
let scopes = []
let textIndex = 0
for (let tagCode of tagCodes) {
if (displayLayer.isOpenTagCode(tagCode)) {
scopes.push(displayLayer.tagForCode(tagCode))
} else if (displayLayer.isCloseTagCode(tagCode)) {
scopes.pop()
} else {
tokens.push({
value: lineText.substr(textIndex, tagCode).replace(invisibleRegExp, ' '),
scopes: scopes.slice()
})
textIndex += tagCode
}
}

tokenLines.push(tokens)
}
}
return tokenLines
}

/**
* Draws lines on the corresponding layer.
*
Expand All @@ -417,42 +467,28 @@ export default class CanvasDrawer extends Mixin {
if (firstRow > lastRow) { return }

const devicePixelRatio = this.minimap.getDevicePixelRatio()
const lines = this.getTextEditor().tokenizedLinesForScreenRows(firstRow, lastRow)
const lineHeight = this.minimap.getLineHeight() * devicePixelRatio
const charHeight = this.minimap.getCharHeight() * devicePixelRatio
const charWidth = this.minimap.getCharWidth() * devicePixelRatio
const displayCodeHighlights = this.displayCodeHighlights
const context = this.tokensLayer.context
const {width: canvasWidth} = this.tokensLayer.getSize()

let line = lines[0]
const invisibleRegExp = this.getInvisibleRegExp(line)

for (let i = 0, len = lines.length; i < len; i++) {
line = lines[i]
const yRow = (offsetRow + i) * lineHeight
let y = offsetRow * lineHeight
for (let tokens of this.tokenLinesForScreenRows(firstRow, lastRow)) {
let x = 0

if ((line != null ? line.tokens : void 0) != null) {
const tokens = line.tokens
for (let j = 0, tokensCount = tokens.length; j < tokensCount; j++) {
const token = tokens[j]
const w = token.screenDelta
if (!token.isOnlyWhitespace()) {
const color = displayCodeHighlights ? this.getTokenColor(token) : this.getDefaultColor()

let value = token.value
if (invisibleRegExp != null) {
value = value.replace(invisibleRegExp, ' ')
}
x = this.drawToken(context, value, color, x, yRow, charWidth, charHeight)
} else {
x += w * charWidth
}

if (x > canvasWidth) { break }
context.clearRect(x, y, canvasWidth, lineHeight)
for (let token of tokens) {
if (/^\s+$/.test(token.value)) {
x += token.value.length * charWidth
} else {
const color = displayCodeHighlights ? this.getTokenColor(token) : this.getDefaultColor()
x = this.drawToken(context, token.value, color, x, y, charWidth, charHeight)
}
if (x > canvasWidth) { break }
}

y += lineHeight
}

context.fill()
Expand All @@ -462,12 +498,30 @@ export default class CanvasDrawer extends Mixin {
* Returns the regexp to replace invisibles substitution characters
* in editor lines.
*
* @param {TokenizedLine} line a tokenized lize to read the invisible
* characters
* @return {RegExp} the regular expression to match invisible characters
* @access private
*/
getInvisibleRegExp (line) {
getInvisibleRegExp () {
let invisibles = this.getTextEditor().getInvisibles()
let regexp = ''
if (invisibles.cr != null) { regexp += invisibles.cr + '|' }
if (invisibles.eol != null) { regexp += invisibles.eol + '|' }
if (invisibles.space != null) { regexp += invisibles.space + '|' }
if (invisibles.tab != null) { regexp += invisibles.tab + '|' }

return new RegExp(_.escapeRegExp(regexp.slice(0, -1)), 'g')
}

/**
* Returns the regexp to replace invisibles substitution characters
* in editor lines.
*
* @param {Object} line the tokenized line
* @return {RegExp} the regular expression to match invisible characters
* @deprecated Is used only to support Atom version before display layer API
* @access private
*/
getInvisibleRegExpForLine (line) {
if ((line != null) && (line.invisibles != null)) {
const invisibles = []
if (line.invisibles.cr != null) { invisibles.push(line.invisibles.cr) }
Expand Down Expand Up @@ -540,6 +594,11 @@ export default class CanvasDrawer extends Mixin {
drawDecorations (screenRow, decorations, renderData, types) {
let decorationsToRender = []

renderData.context.clearRect(
0, renderData.yRow,
renderData.canvasWidth, renderData.lineHeight
)

for (let i in types) {
decorationsToRender = decorationsToRender.concat(
decorations[i] != null ? decorations[i][screenRow] || [] : []
Expand Down
2 changes: 0 additions & 2 deletions lib/mixins/decoration-management.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,6 @@ export default class DecorationManagement extends Mixin {
* @access private
*/
emitDecorationChanges (type, decoration) {
if (decoration.marker.displayBuffer.isDestroyed()) { return }

this.invalidateDecorationForScreenRowsCache()

let range = decoration.marker.getScreenRange()
Expand Down
2 changes: 1 addition & 1 deletion spec/minimap-element-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ describe('MinimapElement', () => {

expect(minimapElement.drawLines).toHaveBeenCalled()
expect(minimapElement.drawLines.argsForCall[0][0]).toEqual(100)
expect(minimapElement.drawLines.argsForCall[0][1]).toEqual(101)
expect(minimapElement.drawLines.argsForCall[0][1]).toEqual(102)
})
})
})
Expand Down
2 changes: 1 addition & 1 deletion spec/minimap-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ describe('Minimap', () => {
it('adjust the scrolling ratio', () => {
editorElement.setScrollTop(editorElement.getScrollHeight())

let maxScrollTop = editorElement.getScrollHeight() - editorElement.getHeight() - (editorElement.getHeight() - 3 * editor.displayBuffer.getLineHeightInPixels())
let maxScrollTop = editorElement.getScrollHeight() - editorElement.getHeight() - (editorElement.getHeight() - 3 * editor.getLineHeightInPixels())

expect(minimap.getTextEditorScrollRatio()).toEqual(editorElement.getScrollTop() / maxScrollTop)
})
Expand Down

0 comments on commit ae7b9bc

Please sign in to comment.