Skip to content

Commit

Permalink
Treat Korean characters as different kinds of chars
Browse files Browse the repository at this point in the history
  • Loading branch information
as-cii committed Oct 15, 2015
1 parent c9eb75c commit 4766c98
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 22 deletions.
11 changes: 11 additions & 0 deletions spec/display-buffer-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ describe "DisplayBuffer", ->
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe("フヒフヌᄡ○○○hello ")
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe("world this is a pretty long line")

describe "when there are korean characters", ->
it "takes them into account when finding the soft wrap column", ->
displayBuffer.setDefaultCharWidth(1, 0, 0, 10)
buffer.setText("1234세계를 향한 대화, 유니코 제10회유니코드국제")

expect(displayBuffer.tokenizedLineForScreenRow(0).text).toBe("1234세계를 ")
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toBe("향한 대화, ")
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe("유니코 ")
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe("제10회유니")
expect(displayBuffer.tokenizedLineForScreenRow(4).text).toBe("코드국제")

describe "when editor.softWrapAtPreferredLineLength is set", ->
it "uses the preferred line length as the soft wrap column when it is less than the configured soft wrap column", ->
atom.config.set('editor.preferredLineLength', 100)
Expand Down
3 changes: 2 additions & 1 deletion spec/text-editor-component-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2892,13 +2892,14 @@ describe "TextEditorComponent", ->
expect(event.abortKeyBinding).toHaveBeenCalled()

describe "when changing the font", ->
it "measures the default char, the double width char and the half width char widths ", ->
it "measures the default char, the korean char, the double width char and the half width char widths", ->
expect(editor.getDefaultCharWidth()).toBeCloseTo(12, 0)

component.setFontSize(10)
nextAnimationFrame()

expect(editor.getDefaultCharWidth()).toBeCloseTo(6, 0)
expect(editor.getKoreanCharWidth()).toBeCloseTo(9, 0)
expect(editor.getDoubleWidthCharWidth()).toBe(10)
expect(editor.getHalfWidthCharWidth()).toBe(5)

Expand Down
14 changes: 11 additions & 3 deletions spec/text-utils-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ describe 'text utilities', ->
expect(textUtils.isPairedCharacter('ae\u0301c', 4)).toBe false

describe ".isDoubleWidthCharacter(character)", ->
it "returns true when the character is either japanese, korean, chinese or a full width form", ->
it "returns true when the character is either japanese, chinese or a full width form", ->
expect(textUtils.isDoubleWidthCharacter("")).toBe(true)

expect(textUtils.isDoubleWidthCharacter("")).toBe(true)

expect(textUtils.isDoubleWidthCharacter("")).toBe(true)

expect(textUtils.isDoubleWidthCharacter("")).toBe(true)
expect(textUtils.isDoubleWidthCharacter("")).toBe(true)
expect(textUtils.isDoubleWidthCharacter("")).toBe(true)
Expand All @@ -65,4 +63,14 @@ describe 'text utilities', ->
expect(textUtils.isHalfWidthCharacter("")).toBe(true)
expect(textUtils.isHalfWidthCharacter("")).toBe(true)
expect(textUtils.isHalfWidthCharacter("")).toBe(true)

expect(textUtils.isHalfWidthCharacter("B")).toBe(false)

describe ".isKoreanCharacter(character)", ->
it "returns true when the character is a korean character", ->
expect(textUtils.isKoreanCharacter("")).toBe(true)
expect(textUtils.isKoreanCharacter("")).toBe(true)
expect(textUtils.isKoreanCharacter("")).toBe(true)
expect(textUtils.isKoreanCharacter("")).toBe(true)

expect(textUtils.isKoreanCharacter("O")).toBe(false)
10 changes: 8 additions & 2 deletions src/display-buffer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -189,19 +189,23 @@ class DisplayBuffer extends Model
getLineHeightInPixels: -> @lineHeightInPixels
setLineHeightInPixels: (@lineHeightInPixels) -> @lineHeightInPixels

getKoreanCharWidth: -> @koreanCharWidth

getHalfWidthCharWidth: -> @halfWidthCharWidth

getDoubleWidthCharWidth: -> @doubleWidthCharWidth

getDefaultCharWidth: -> @defaultCharWidth

setDefaultCharWidth: (defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth) ->
setDefaultCharWidth: (defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth) ->
doubleWidthCharWidth ?= defaultCharWidth
halfWidthCharWidth ?= defaultCharWidth
if defaultCharWidth isnt @defaultCharWidth or doubleWidthCharWidth isnt @doubleWidthCharWidth
koreanCharWidth ?= defaultCharWidth
if defaultCharWidth isnt @defaultCharWidth or doubleWidthCharWidth isnt @doubleWidthCharWidth and halfWidthCharWidth isnt @halfWidthCharWidth and koreanCharWidth isnt @koreanCharWidth
@defaultCharWidth = defaultCharWidth
@doubleWidthCharWidth = doubleWidthCharWidth
@halfWidthCharWidth = halfWidthCharWidth
@koreanCharWidth = koreanCharWidth
@updateWrappedScreenLines() if @isSoftWrapped() and @getEditorWidthInChars()?
defaultCharWidth

Expand Down Expand Up @@ -290,6 +294,8 @@ class DisplayBuffer extends Model
charWidth = @getDoubleWidthCharWidth()
else if iterator.hasHalfWidthCharacterAt(textIndex)
charWidth = @getHalfWidthCharWidth()
else if iterator.hasKoreanCharacterAt(textIndex)
charWidth = @getKoreanCharWidth()
else
charWidth = @getDefaultCharWidth()

Expand Down
5 changes: 4 additions & 1 deletion src/lines-component.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ DummyLineNode.style.visibility = 'hidden'
DummyLineNode.appendChild(document.createElement('span'))
DummyLineNode.appendChild(document.createElement('span'))
DummyLineNode.appendChild(document.createElement('span'))
DummyLineNode.appendChild(document.createElement('span'))
DummyLineNode.children[0].textContent = 'x'
DummyLineNode.children[1].textContent = ''
DummyLineNode.children[2].textContent = ''
DummyLineNode.children[3].textContent = ''

RangeForMeasurement = document.createRange()

Expand Down Expand Up @@ -88,11 +90,12 @@ class LinesComponent extends TiledComponent
defaultCharWidth = DummyLineNode.children[0].getBoundingClientRect().width
doubleWidthCharWidth = DummyLineNode.children[1].getBoundingClientRect().width
halfWidthCharWidth = DummyLineNode.children[2].getBoundingClientRect().width
koreanCharWidth = DummyLineNode.children[3].getBoundingClientRect().width

@domNode.removeChild(DummyLineNode)

@presenter.setLineHeight(lineHeightInPixels)
@presenter.setBaseCharacterWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth)
@presenter.setBaseCharacterWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)

lineNodeForLineIdAndScreenRow: (lineId, screenRow) ->
tile = @presenter.tileForRow(screenRow)
Expand Down
7 changes: 4 additions & 3 deletions src/text-editor-presenter.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1122,12 +1122,13 @@ class TextEditorPresenter
@mouseWheelScreenRow = screenRow
@didStartScrolling()

setBaseCharacterWidth: (baseCharacterWidth, doubleWidthCharWidth, halfWidthCharWidth) ->
unless @baseCharacterWidth is baseCharacterWidth and @doubleWidthCharWidth is doubleWidthCharWidth and @halfWidthCharWidth is halfWidthCharWidth
setBaseCharacterWidth: (baseCharacterWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth) ->
unless @baseCharacterWidth is baseCharacterWidth and @doubleWidthCharWidth is doubleWidthCharWidth and @halfWidthCharWidth is halfWidthCharWidth and koreanCharWidth is @koreanCharWidth
@baseCharacterWidth = baseCharacterWidth
@doubleWidthCharWidth = doubleWidthCharWidth
@halfWidthCharWidth = halfWidthCharWidth
@model.setDefaultCharWidth(baseCharacterWidth, doubleWidthCharWidth, halfWidthCharWidth)
@koreanCharWidth = koreanCharWidth
@model.setDefaultCharWidth(baseCharacterWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)
@characterWidthsChanged()

characterWidthsChanged: ->
Expand Down
6 changes: 4 additions & 2 deletions src/text-editor.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -2976,13 +2976,15 @@ class TextEditor extends Model
getLineHeightInPixels: -> @displayBuffer.getLineHeightInPixels()
setLineHeightInPixels: (lineHeightInPixels) -> @displayBuffer.setLineHeightInPixels(lineHeightInPixels)

getKoreanCharWidth: -> @displayBuffer.getKoreanCharWidth()

getHalfWidthCharWidth: -> @displayBuffer.getHalfWidthCharWidth()

getDoubleWidthCharWidth: -> @displayBuffer.getDoubleWidthCharWidth()

getDefaultCharWidth: -> @displayBuffer.getDefaultCharWidth()
setDefaultCharWidth: (defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth) ->
@displayBuffer.setDefaultCharWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth)
setDefaultCharWidth: (defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth) ->
@displayBuffer.setDefaultCharWidth(defaultCharWidth, doubleWidthCharWidth, halfWidthCharWidth, koreanCharWidth)

setHeight: (height, reentrant=false) ->
if reentrant
Expand Down
19 changes: 10 additions & 9 deletions src/text-utils.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,6 @@ isPairedCharacter = (string, index=0) ->
isVariationSequence(charCodeA, charCodeB) or
isCombinedCharacter(charCodeA, charCodeB)

isKoreanCharacter = (charCode) ->
0xAC00 <= charCode <= 0xD7A3 or
0x1100 <= charCode <= 0x11FF or
0x3130 <= charCode <= 0x318F or
0xA960 <= charCode <= 0xA97F or
0xD7B0 <= charCode <= 0xD7FF

isJapaneseCharacter = (charCode) ->
0x3000 <= charCode <= 0x30FF

Expand All @@ -77,7 +70,6 @@ isFullWidthForm = (charCode) ->
isDoubleWidthCharacter = (character) ->
charCode = character.charCodeAt(0)

isKoreanCharacter(charCode) or
isJapaneseCharacter(charCode) or
isCjkUnifiedIdeograph(charCode) or
isFullWidthForm(charCode)
Expand All @@ -88,6 +80,15 @@ isHalfWidthCharacter = (character) ->
0xFF65 <= charCode <= 0xFFDC or
0xFFE8 <= charCode <= 0xFFEE

isKoreanCharacter = (character) ->
charCode = character.charCodeAt(0)

0xAC00 <= charCode <= 0xD7A3 or
0x1100 <= charCode <= 0x11FF or
0x3130 <= charCode <= 0x318F or
0xA960 <= charCode <= 0xA97F or
0xD7B0 <= charCode <= 0xD7FF

# Does the given string contain at least surrogate pair, variation sequence,
# or combined character?
#
Expand All @@ -101,4 +102,4 @@ hasPairedCharacter = (string) ->
index++
false

module.exports = {isPairedCharacter, hasPairedCharacter, isDoubleWidthCharacter, isHalfWidthCharacter}
module.exports = {isPairedCharacter, hasPairedCharacter, isDoubleWidthCharacter, isHalfWidthCharacter, isKoreanCharacter}
5 changes: 4 additions & 1 deletion src/token-iterator.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{SoftTab, HardTab, PairedCharacter, SoftWrapIndent} = require './special-token-symbols'
{isDoubleWidthCharacter, isHalfWidthCharacter} = require './text-utils'
{isDoubleWidthCharacter, isHalfWidthCharacter, isKoreanCharacter} = require './text-utils'

module.exports =
class TokenIterator
Expand Down Expand Up @@ -89,5 +89,8 @@ class TokenIterator
hasHalfWidthCharacterAt: (charIndex) ->
isHalfWidthCharacter(@getText()[charIndex])

hasKoreanCharacterAt: (charIndex) ->
isKoreanCharacter(@getText()[charIndex])

isAtomic: ->
@isSoftTab() or @isHardTab() or @isSoftWrapIndentation() or @isPairedCharacter()

0 comments on commit 4766c98

Please sign in to comment.