当我在自定义视图中调用函数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
}
为什么两种方法运行不同?我需要画角色,但它的字距是错误的! 有人可以指导我吗?
答案 0 :(得分:0)
基于pskink Why the kerning is wrong when I use 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;
}
答案 1 :(得分:-1)
我用它来进行字距调整。这是用coffeescript btw写的,虽然很容易转换它。
_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));
};