SORU
25 EYLÜL 2011, Pazar


Boya Android: .() measureText vs .()getTextBounds

Metin her iki yükseklik ve genişlik işlenecek almak isterim bu yana metin Paint.getTextBounds() kullanarak ölçüyorum. Ancak, metinde işlenen her zaman Rect bilgi getTextBounds() dolu .width() normalden biraz daha geniş.

Benim için sürpriz, .measureText(), test ettim (daha yüksek) farklı bir değer döndürür bulundu. Bir şans verdim, ve bunu doğru buldu.

Neden farklı genişlikleri rapor veriyorlar mı? Nasıl doğru yükseklik ve genişlik alabilirim? Yani, benolabilir.measureText() ama sonra .height() getTextBounds() tarafından döndürülen güven vermeli miyim, bilemiyorum kullanın.

İstendiği gibi, burada sorunu yeniden oluşturmak için en az bir kod

final String someText = "Hello. I believe I'm some text!";

Paint p = new Paint();
Rect bounds = new Rect();

for (float f = 10; f < 40; f  = 1f) {
    p.setTextSize(f);

    p.getTextBounds(someText, 0, someText.length(), bounds);

    Log.d("Test", String.format(
        "Size %f, measureText %f, getTextBounds %d",
        f,
        p.measureText(someText),
        bounds.width())
    );
}

Çıkışını gösteren fark sadece alır 1 den daha büyük (ve eğer son dakikada bir yuvarlama hatası), aynı zamanda gibi görünüyor artışla boyutu (yaklaşık Beraberlik için daha fazla sonuç ama olabilir tamamen font-bağımlı):

D/Test    (  607): Size 10.000000, measureText 135.000000, getTextBounds 134
D/Test    (  607): Size 11.000000, measureText 149.000000, getTextBounds 148
D/Test    (  607): Size 12.000000, measureText 156.000000, getTextBounds 155
D/Test    (  607): Size 13.000000, measureText 171.000000, getTextBounds 169
D/Test    (  607): Size 14.000000, measureText 195.000000, getTextBounds 193
D/Test    (  607): Size 15.000000, measureText 201.000000, getTextBounds 199
D/Test    (  607): Size 16.000000, measureText 211.000000, getTextBounds 210
D/Test    (  607): Size 17.000000, measureText 225.000000, getTextBounds 223
D/Test    (  607): Size 18.000000, measureText 245.000000, getTextBounds 243
D/Test    (  607): Size 19.000000, measureText 251.000000, getTextBounds 249
D/Test    (  607): Size 20.000000, measureText 269.000000, getTextBounds 267
D/Test    (  607): Size 21.000000, measureText 275.000000, getTextBounds 272
D/Test    (  607): Size 22.000000, measureText 297.000000, getTextBounds 294
D/Test    (  607): Size 23.000000, measureText 305.000000, getTextBounds 302
D/Test    (  607): Size 24.000000, measureText 319.000000, getTextBounds 316
D/Test    (  607): Size 25.000000, measureText 330.000000, getTextBounds 326
D/Test    (  607): Size 26.000000, measureText 349.000000, getTextBounds 346
D/Test    (  607): Size 27.000000, measureText 357.000000, getTextBounds 354
D/Test    (  607): Size 28.000000, measureText 369.000000, getTextBounds 365
D/Test    (  607): Size 29.000000, measureText 396.000000, getTextBounds 392
D/Test    (  607): Size 30.000000, measureText 401.000000, getTextBounds 397
D/Test    (  607): Size 31.000000, measureText 418.000000, getTextBounds 414
D/Test    (  607): Size 32.000000, measureText 423.000000, getTextBounds 418
D/Test    (  607): Size 33.000000, measureText 446.000000, getTextBounds 441
D/Test    (  607): Size 34.000000, measureText 455.000000, getTextBounds 450
D/Test    (  607): Size 35.000000, measureText 468.000000, getTextBounds 463
D/Test    (  607): Size 36.000000, measureText 474.000000, getTextBounds 469
D/Test    (  607): Size 37.000000, measureText 500.000000, getTextBounds 495
D/Test    (  607): Size 38.000000, measureText 506.000000, getTextBounds 501
D/Test    (  607): Size 39.000000, measureText 521.000000, getTextBounds 515

CEVAP
28 EYLÜL 2011, ÇARŞAMBA


Bu sorunu incelemek için yaptığımı yapabilirsiniz:

Araştırma kaynak kodu, paint.java kaynak, measureText ve getTextBounds yöntemleri bakın Android. MeasureText native_measureText aramalar ve Yerel Aramalar yöntemleri C uygulanmaktadır nativeGetStringBounds, getTextBounds öğrenmek istiyorum .

Hem uygulayan paint.cpp ders çalışmaya devam edersin.

native_measureText ->::MeasureText_Cİİ SkPaintGlue

nativeGetStringBounds ->::SkPaintGlue getStringBounds

Şimdi sizin çalışmada bu yöntemleri farklı olup olmadığını kontrol eder. Biraz param onayladıktan sonra, hem de arama fonksiyonu SkPaint::Skia Lib (Android parçası) measureText, ama ikisi de farklı aşırı form arayın.

Kazma daha Skia içine, her iki aramayı da aynı işlevi aynı hesaplama içine sonucu, dönüş farklı sonuç sadece bunu görüyorum.

Sorunuzun cevabı için: Hem çağrı, aynı hesaplama yapın. Sonuç Olası fark aslında bu yatıyorgetTextBoundstamsayı, süre olarak sınırlarımeasureTextgeri dönüş değeri yüzer.

Ne aracı dönüşüm sırasında hata int yuvarlama ve bu SkPaintGlue içinde Paint.cpp olur o kadar::fonksiyon SkRect arayıp doTextBounds::roundOut.

Bu iki arama hesaplanan genişliği arasındaki fark en fazla 1 olabilir.

4 Ekim 2011 DÜZENLEYİN

Görselleştirme daha iyi ne olabilir. Bu çaba, kendi keşfetmek için, ve ödül hak için aldım :) enter image description here

Bu kırmızı 60, yazı tipidiriyi bir çalışma olmuşdikdörtgen, mor neden measureText.

Sınırları soldan bazı pikseller başlar bölümünü terk ettiğini görmüş ve measureText değeri hem solda bu değer artan ve haklı. Bu bir Simge var AdvanceX değeri denir. (Skpaint.cpp kaynaklar, Skia) bu keşfettim

Test sonucu measureText getTextBounds verilen metin uyacak minimum sınırları hesaplar yaparken her iki tarafta metin için önceden biraz değer katar, o kadar.

Bu sonuç sizin için yararlı olduğunu umuyoruz.

Kodu test:

  protected void onDraw(Canvas canvas){
     final String s = "Hello. I'm some text!";

     Paint p = new Paint();
     Rect bounds = new Rect();
     p.setTextSize(60);

     p.getTextBounds(s, 0, s.length(), bounds);
     float mt = p.measureText(s);
     int bw = bounds.width();

     Log.i("LCG", String.format(
          "measureText %f, getTextBounds %d (%s)",
          mt,
          bw, bounds.toShortString())
      );
     bounds.offset(0, -bounds.top);
     p.setStyle(Style.STROKE);
     canvas.drawColor(0xff000080);
     p.setColor(0xffff0000);
     canvas.drawRect(bounds, p);
     p.setColor(0xff00ff00);
     canvas.drawText(s, 0, bounds.bottom, p);
  }

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CHISTOSITOJAJA

    CHISTOSITOJA

    27 HAZİRAN 2010
  • TheGamer2323

    TheGamer2323

    25 Ocak 2009
  • wwjoshdo

    wwjoshdo

    25 Mayıs 2009