2014-04-25 4 views
0

Когда я вызываю функцию canvas.drawText() в моей пользовательской точки зрения, я получил странный результат, как это:Почему кернинг ошибочен, когда я использую 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

попробовать Paint.measureText, назовем его два раза: сначала с начальной == 0 и конец == I + 1 и второй раз с начала == I и конец == I + 1 и вычитать два результата – pskink

+0

Я забыл упомянуть, чтобы использовать три параметра measureText – pskink

+0

Хорошо, я попробую – user3513329

ответ

-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)); 
}; 
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; 
} 
+0

skia, похоже, поддерживает getKerningPairAdjustments, но я не нашел его открытым графикой Android в любом месте java api. https://github.com/google/skia/blob/master/include/core/SkTypeface.h#L239-L260 https://github.com/android/platform_external_skia/blob/master/src/core /SkTypeface.cpp#L261-L273 – msand

Смежные вопросы