2013-03-22 126 views
3

我正在做一個圖形代碼編輯器,我可以通過拖動它們來修改常量。 我想強調與藍色矩形,使得左右邊框中的字符中間躺着的代碼的命令,但藍色的矩形仍失準在某些情況下:Android等寬字體大小

Highlighting problem

我的想法是首先計算字符寬度和字符空間,然後再乘以我的文本中的命令位置。

val mCodePaint = new TextPaint() 
mCodePaint.setTypeface(Typeface.MONOSPACE) 
mCodePaint.setAntiAlias(true) 
mCodePaint.setSubpixelText(true) 
mCodePaint.setColor(0xFF000000) 
val dimText = new Rect() 
val dimText1 = new Rect() 
val dimText2 = new Rect() 

final val s1 = "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" 
final val s2 = "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" 
// dimText1.width() = char_length * s1.length + space_between_chars*(s1.length-1) 
// dimText2.width() = char_length * s2.length + space_between_chars*(s2.length-1) 
def getCharWidth(): Float = { 
    mCodePaint.getTextBounds(s1, 0, s1.length, dimText1) 
    mCodePaint.getTextBounds(s2, 0, s2.length, dimText2) 
    (dimText2.width() * (s1.length - 1) - dimText1.width() *(s2.length - 1))/(s1.length - s2.length) 
} 

def getIntercharWidth(): Float = { 
    mCodePaint.getTextBounds(s1, 0, s1.length, dimText1) 
    mCodePaint.getTextBounds(s2, 0, s2.length, dimText2) 
    (dimText1.width * s2.length - dimText2.width * s1.length)/(s1.length - s2.length) 
} 

// The main function that draw the text 
def drawRuleCode(canvas: Canvas, ...): Unit = { 
    var char_width = getCharWidth() // At run time, equals 29 
    var space_width = getIntercharWidth() // At run time, equals -10 

    for(action <- ...) { 
    ... 
    val column = action.column 
    val length = action.length 
    val x1 = left_x+8 + column*char_width + (column-1)*space_width - 0.5f*space_width 
    val x2 = x1 + length*char_width + (length-1)*space_width + 1*space_width 
    rectFData.set(x1, y1, x2, y2) 
    canvas.drawRoundRect(rectFData, 5, 5, selectPaint) 
    } 


    for(line <- ...) { 
    ... 
    canvas.drawText(s, left_x + 8, ..., mCodePaint) 
    } 

對於如何克服小對齊問題你有什麼想法嗎?有時它會產生巨大的差異,特別是當表達很長時。

編輯:我繪製了計算文本邊界,實際上他們是錯誤的。該文本是比getTextBounds(紫線)給出的矩形稍大: enter image description here

回答

1

的使用getTextBounds,我需要通過大規模的說法相反,因爲字體大小不會與畫布線性比例: Explanation here

var c = new Matrix() 
val c_array = new Array[Float](9) 

// The main function that draw the text 
def drawRuleCode(canvas: Canvas, ...): Unit = { 
    var box_width = getBoxWidth() 

    canvas.getMatrix(c) 
    c.getValues(c_array) 
    val scale = c_array(Matrix.MSCALE_X) // Compute the current matrix scale 
    var box_width = getBoxWidth(scale) 

    for(action <- ...) { 
    ... 
    val column = action.column 
    val length = action.length 
    val x1 = left_x+8 + column*box_width 
    val x2 = x1 + length*box_width 
    rectFData.set(x1, y1, x2, y2) 
    canvas.drawRoundRect(rectFData, 5, 5, selectPaint) 
    } 

def getBoxWidth(scale: Float): Float = { 
    mCodePaint.setTextSize(fontSize * scale) 
    val result = mCodePaint.measureText(s1).toFloat/s1.length/scale 
    mCodePaint.setTextSize(fontSize) 
    result 
}