4

定数をドラッグして変更できるグラフィカルコードエディタを実行しています。コード内のコマンドを青い長方形で強調表示して、左右の境界線が文字の中央に配置されるようにしたいのですが、青い長方形がまだずれている場合があります。

強調表示の問題

私の考えは、最初に文字幅と文字スペースを計算し、その後、テキスト内のコマンドの位置を掛けることです。

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(紫色の線)で指定された長方形よりもわずかに大きくなっています。 ここに画像の説明を入力してください

4

1 に答える 1

1

getTextBoundsを使用する代わりに、フォントサイズがキャンバスに対して線形にスケーリングされないため、scale引数を渡す必要があります。 ここでの説明

 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
}
于 2013-03-22T12:32:17.407 に答える