0

当我在自定义视图中调用该函数canvas.drawText()时,我得到了奇怪的结果,如下所示:

protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);
    canvas.translate(50, 50);
    mPaint.setTextSize(60);

    String str = "helloworld";
    float[] wids = new float[10];
    mPaint.getTextWidths(str, wids);
    float width = 0;
    for (int j = 0; j < wids.length; j++) {
        String string = String.valueOf(str.charAt(j));
        canvas.drawText(string, width, 50, mPaint);   //draw by characters
        width = width + mPaint.measureText(string);   //the start X
    }
}

和这个:

protected void onDraw(Canvas canvas) {

    super.onDraw(canvas);
    canvas.translate(50, 50);
    mPaint.setTextSize(60);
    String str = "helloworld";
    canvas.drawText(str, 0, 50, mPaint); // draw by strings
    }

为什么这两种方法运行不同?我需要按字符绘制,但它的字距是错误的!有人可以指导我吗?

4

2 回答 2

0

基于 pskink 评论中建议的自动字距调整解决方案为什么我使用 canvas.drawText 时字距是错误的? 但也支持用固定值覆盖字距(例如 SVG)

if (isKerningValueSet) {
    glyphPosition += kerningValue;
} else {
    float previousChar = paint.measureText(line, Math.max(0, index - 1), index);
    float previousAndCurrentChar = paint.measureText(line, Math.max(0, index - 1), index + 1);
    float onlyCurrentChar = paint.measureText(line, index, index + 1);
    float kernedCharWidth = previousAndCurrentChar - previousChar;
    float kerning = kernedCharWidth - onlyCurrentChar;
    glyphPosition += kerning;
}
于 2017-06-21T15:36:55.277 回答
-1

我用它来调整字距。顺便说一句,这是用咖啡脚本编写的,但很容易转换。

_fillText = Canvas.Context2d::fillText
Canvas.Context2d::fillText = (str, x, y, args...) ->

  # no kerning? default behavior
  return _fillText.apply this, arguments unless @kerning?

  # we need to remember some stuff as we loop
  offset = 0

  _.each str, (letter) =>

    _fillText.apply this, [
      letter
      x + offset + @kerning
      y
    ].concat args # in case any additional args get sent to fillText at any time

    offset += @measureText(letter).width + @kerning

然后使用它

context.kerning = 20
context.fillText(....)

这是javascript(没有args...部分,但我认为默认情况下不会向fillText发送任何其他内容)

var _fillText;

_fillText = Canvas.Context2d.prototype.fillText;

Canvas.Context2d.prototype.fillText = function(str, x, y) {
  var offset;
  // Fallback unless we need kerning
  if (this.kerning == null) {
    return _fillText.apply(this, arguments);
  }
  offset = 0;
  return _.each(str, (function(_this) {
    return function(letter) {
      _fillText.call(_this, letter, x + offset + _this.kerning, y);
      return offset += _this.measureText(letter).width + _this.kerning;
    };
  })(this));
};
于 2015-01-09T17:16:26.737 回答