Wednesday, March 7, 2012

Re: [android-developers] Problem with drawing text in scaled Canvas on Android 4.0

Actually I am using it in onDraw method this way:

        canvas.save();
       
        canvas.scale(_scale, _scale);
       
        float w = _paint.measureText(TEXT);
        float h = _fm.descent - _fm.ascent;
       
        float x = 20f;
        float y = 20f;
       
        _paint.setColor(0xff000000);
       
        canvas.drawText(TEXT, x, y - _fm.ascent, _paint);
       
        _paint.setColor(0xffff0000);
       
        canvas.drawRect(x, y, x + w, y + h, _paint);
       
        canvas.restore();

Where paint is created once and never changes:

        Paint p = new TextPaint();
       
        p.setAntiAlias(true);
        p.setSubpixelText(true);
       
        p.setTypeface(Typeface.SERIF);
        p.setTextSize(22.f);
       
        p.setColor(0xff000000);
       
        p.setStrokeWidth(0);
       
        p.setStyle(Paint.Style.STROKE);
       
        p.getFontMetrics(_fm);
       
        _paint = p;

I am attaching the sample application that demonstrates the problem. If you run it, there is a SeekBar down on the screen with which you can change the scale and see how problem appears. I also attach the screen shot with the problem. You will notice that text is little wider than the rectangle.

I have noticed that the problem occurs only if hardware acceleration is off.

The screen shot is from Galaxy Nexus with Android version 4.0.2.

On Monday, March 5, 2012 6:46:28 PM UTC+2, Romain Guy (Google) wrote:
The Canvas scale does not apply to the font size, it applies to the
vector shapes generated from the original font size. You simply cannot
this:

p.setTextSize(fontSize * scale)
result = p.measureText(...)

You must instead do this:

p.setTextSize(fontSize)
result = scale * p.measureText(...)


On Mon, Mar 5, 2012 at 12:35 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
> Hi,
>
> The measure functions are in Paint. The scale functions are in Canvas. So I
> can only measure text without any scale. And if I measure the width and
> height of some text and want to draw a rectangle around it and want to use
> the scale of canvas for zooming. On some zooms the text is a little narrower
> and on some zooms it is a little wider. That is why I wrote the above
> function because I supposed that if canvas have scale it apply scale on font
> size and then draw the text with scaled font size.
>
> Please try to understand the log in the previous message. It is a little
> strange that on closer scale levels the measured width is the same.
>
> And finally it is working as I expected on Android below 4.0. Why it is not
> working on 4.0? What is the difference?
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en

--
Romain Guy
Android framework engineer
romainguy@android.com


On Monday, March 5, 2012 6:46:28 PM UTC+2, Romain Guy (Google) wrote:
The Canvas scale does not apply to the font size, it applies to the
vector shapes generated from the original font size. You simply cannot
this:

p.setTextSize(fontSize * scale)
result = p.measureText(...)

You must instead do this:

p.setTextSize(fontSize)
result = scale * p.measureText(...)


On Mon, Mar 5, 2012 at 12:35 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
> Hi,
>
> The measure functions are in Paint. The scale functions are in Canvas. So I
> can only measure text without any scale. And if I measure the width and
> height of some text and want to draw a rectangle around it and want to use
> the scale of canvas for zooming. On some zooms the text is a little narrower
> and on some zooms it is a little wider. That is why I wrote the above
> function because I supposed that if canvas have scale it apply scale on font
> size and then draw the text with scaled font size.
>
> Please try to understand the log in the previous message. It is a little
> strange that on closer scale levels the measured width is the same.
>
> And finally it is working as I expected on Android below 4.0. Why it is not
> working on 4.0? What is the difference?
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
>
> On Sunday, March 4, 2012 10:17:30 PM UTC+2, Romain Guy (Google) wrote:
>>
>> Hi,
>>
>> This is not the proper way to measure scaled text. The font size
>> defines the height of the font, not its width. There is no guarantee
>> whatsoever that scaling a font size by a number S will scale the width
>> of the text by the same number S. The proper way is to always call
>> measureText() with the font size you are actually going to use. If you
>> apply a scale factor on the Canvas, simply multiply the result of
>> measureText() with the scale factor.
>>
>>
>> On Fri, Mar 2, 2012 at 4:02 AM, Kaloyan Donev <kdonev@gmail.com> wrote:
>> > Hi,
>> >
>> > I am using a Typeface to draw text in canvas which have scale matrix. So
>> > first I measure the width of text when scale is 1.0. Then I measure the
>> > width of text when scale is different than 1.0. And I expect that non
>> > scaled
>> > width * scale will be equal to scaled width. This is true on devices
>> > with
>> > Android OS below 4.0, but on Android 4.0 it is not true. Here is sample
>> > function that I wrote to test it.
>> >
>> >         static void checkGoodForScale(Typeface face)
>> >     {
>> >         TextPaint p = new TextPaint();
>> >
>> >         p.setAntiAlias(true);
>> >         p.setSubpixelText(true);
>> >
>> >         p.setTypeface(face);
>> >
>> >         final String text = "During that discussion, we touched a bit on
>> > the
>> > psychological impact all of this—the earthquake";
>> >         final float textSize = 22.f;
>> >
>> >         p.setTextSize(textSize);
>> >
>> >         float textWidth = p.measureText(text);
>> >
>> >         float scale = 0.05f;
>> >
>> >         while (scale < 1.509)
>> >         {
>> >             p.setTextSize(textSize * scale);
>> >             float scaledTextWidth = p.measureText(text);
>> >
>> >             if (Math.abs(scaledTextWidth - textWidth*scale) > 1.5f)
>> >             {
>> >                 Log.d("FontScaleTest", "Diff in scale width. 100% = " +
>> > textWidth*scale + " " +
>> >                         (int)(scale*100f) + "% = " + scaledTextWidth +
>> >                         " diff = " + (scaledTextWidth - textWidth*scale)
>> > );
>> >             }
>> >
>> >             scale += 0.01f;
>> >         }
>> >     }
>> >
>> > The above function didn't print any messages in log on Android below
>> > 4.0. On
>> > android 4.0 there is difference on each scale percent. I noticed that
>> > widths
>> > are separated in groups of 4-5 percents. For example for scale 45% if
>> > width
>> > is W it is the same for 46%, 47%, 48% and then on 49% it is different.
>> > May
>> > be there is some kind of cache for closer font sizes.
>> >
>> > Here is a part of my logcat:
>> >
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 686.5115 51% =
>> > 660.1074
>> > diff = -26.404053
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 699.7136 52% =
>> > 720.1172
>> > diff = 20.403564
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 712.9157 53% =
>> > 720.1172
>> > diff = 7.201477
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 726.11786 54% =
>> > 720.1172
>> > diff = -6.0006714
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 739.32 55% =
>> > 720.1172
>> > diff = -19.20282
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 752.52216 56% =
>> > 780.12695 diff = 27.604797
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 765.72424 57% =
>> > 780.12695 diff = 14.40271
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 792.12854 59% =
>> > 780.12695 diff = -12.001587
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 805.3307 60% =
>> > 780.12695
>> > diff = -25.203735
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 818.53284 61% =
>> > 840.1367
>> > diff = 21.603882
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 831.7349 62% =
>> > 840.1367
>> > diff = 8.401794
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 844.9371 63% =
>> > 840.1367
>> > diff = -4.800354
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 858.1392 64% =
>> > 840.1367
>> > diff = -18.002502
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 871.3414 65% =
>> > 900.1465
>> > diff = 28.805115
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 884.5435 66% =
>> > 900.1465
>> > diff = 15.602966
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 897.7456 67% =
>> > 900.1465
>> > diff = 2.400879
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 910.94775 68% =
>> > 900.1465
>> > diff = -10.80127
>> > D/FontScaleTest( 4408): Diff in scale width. 100% = 924.1499 69% =
>> > 900.1465
>> > diff = -24.003418
>> >
>> > Do you think this is bug in android or I am not using it the correct
>> > way.
>> >
>> > I tried this with turned on and off hardware acceleration but there is
>> > no
>> > difference.
>> >
>> > Kaloyan
>> >
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Android Developers" group.
>> > To post to this group, send email to android-developers@googlegroups.com
>> > To unsubscribe from this group, send email to
>> > android-developers+unsubscribe@googlegroups.com
>> > For more options, visit this group at
>> > http://groups.google.com/group/android-developers?hl=en
>>
>> --
>> Romain Guy
>> Android framework engineer
>> romainguy@android.com
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en

--
Romain Guy
Android framework engineer
romainguy@android.com

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

No comments:

Post a Comment