Home | History | Annotate | Download | only in bidi
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.bidi;
     18 
     19 import android.content.Context;
     20 import android.graphics.Canvas;
     21 import android.graphics.Color;
     22 import android.graphics.Paint;
     23 import android.graphics.Rect;
     24 import android.text.TextPaint;
     25 import android.util.AttributeSet;
     26 import android.util.Log;
     27 import android.view.View;
     28 
     29 public class BiDiTestView extends View {
     30 
     31     private static final String TAG = "BiDiTestView";
     32 
     33     private static final int BORDER_PADDING = 4;
     34     private static final int TEXT_PADDING = 16;
     35     private static final int TEXT_SIZE = 16;
     36     private static final int ORIGIN = 80;
     37 
     38     private static final float DEFAULT_ITALIC_SKEW_X = -0.25f;
     39 
     40     private Rect rect = new Rect();
     41 
     42     private String NORMAL_TEXT;
     43     private String NORMAL_LONG_TEXT;
     44     private String NORMAL_LONG_TEXT_2;
     45     private String NORMAL_LONG_TEXT_3;
     46     private String ITALIC_TEXT;
     47     private String BOLD_TEXT;
     48     private String BOLD_ITALIC_TEXT;
     49     private String ARABIC_TEXT;
     50     private String CHINESE_TEXT;
     51     private String MIXED_TEXT_1;
     52     private String HEBREW_TEXT;
     53     private String RTL_TEXT;
     54     private String THAI_TEXT;
     55 
     56     private int currentTextSize;
     57 
     58     public BiDiTestView(Context context) {
     59         super(context);
     60         init(context);
     61     }
     62 
     63     public BiDiTestView(Context context, AttributeSet attrs) {
     64         super(context, attrs);
     65         init(context);
     66     }
     67 
     68     public BiDiTestView(Context context, AttributeSet attrs, int defStyle) {
     69         super(context, attrs, defStyle);
     70         init(context);
     71     }
     72 
     73     private void init(Context context) {
     74         NORMAL_TEXT = context.getString(R.string.normal_text);
     75         NORMAL_LONG_TEXT = context.getString(R.string.normal_long_text);
     76         NORMAL_LONG_TEXT_2 = context.getString(R.string.normal_long_text_2);
     77         NORMAL_LONG_TEXT_3 = context.getString(R.string.normal_long_text_3);
     78         ITALIC_TEXT = context.getString(R.string.italic_text);
     79         BOLD_TEXT = context.getString(R.string.bold_text);
     80         BOLD_ITALIC_TEXT = context.getString(R.string.bold_italic_text);
     81         ARABIC_TEXT = context.getString(R.string.arabic_text);
     82         CHINESE_TEXT = context.getString(R.string.chinese_text);
     83         MIXED_TEXT_1 = context.getString(R.string.mixed_text_1);
     84         HEBREW_TEXT = context.getString(R.string.hebrew_text);
     85         RTL_TEXT = context.getString(R.string.rtl);
     86         THAI_TEXT = context.getString(R.string.pointer_location);
     87     }
     88 
     89     public void setCurrentTextSize(int size) {
     90         currentTextSize = size;
     91         invalidate();
     92     }
     93 
     94     @Override
     95     public void onDraw(Canvas canvas) {
     96         drawInsideRect(canvas, new Paint(), Color.BLACK);
     97 
     98         int deltaX = 0;
     99 
    100         deltaX  = testString(canvas, NORMAL_TEXT, ORIGIN, ORIGIN,
    101                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    102 
    103         deltaX += testString(canvas, ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
    104                 true, false,  Paint.DIRECTION_LTR, currentTextSize);
    105 
    106         deltaX += testString(canvas, BOLD_TEXT, ORIGIN + deltaX, ORIGIN,
    107                 false, true,  Paint.DIRECTION_LTR, currentTextSize);
    108 
    109         deltaX += testString(canvas, BOLD_ITALIC_TEXT, ORIGIN + deltaX, ORIGIN,
    110                 true, true,  Paint.DIRECTION_LTR, currentTextSize);
    111 
    112         // Test with a long string
    113         deltaX = testString(canvas, NORMAL_LONG_TEXT, ORIGIN, ORIGIN + 2 * currentTextSize,
    114                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    115 
    116         // Test with a long string
    117         deltaX = testString(canvas, NORMAL_LONG_TEXT_2, ORIGIN, ORIGIN + 4 * currentTextSize,
    118                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    119 
    120         // Test with a long string
    121         deltaX = testString(canvas, NORMAL_LONG_TEXT_3, ORIGIN, ORIGIN + 6 * currentTextSize,
    122                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    123 
    124         // Test Arabic ligature
    125         deltaX = testString(canvas, ARABIC_TEXT, ORIGIN, ORIGIN + 8 * currentTextSize,
    126                 false, false,  Paint.DIRECTION_RTL, currentTextSize);
    127 
    128         // Test Chinese
    129         deltaX = testString(canvas, CHINESE_TEXT, ORIGIN, ORIGIN + 10 * currentTextSize,
    130                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    131 
    132         // Test Mixed (English and Arabic)
    133         deltaX = testString(canvas, MIXED_TEXT_1, ORIGIN, ORIGIN + 12 * currentTextSize,
    134                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    135 
    136         // Test Hebrew
    137         deltaX = testString(canvas, RTL_TEXT, ORIGIN, ORIGIN + 14 * currentTextSize,
    138                 false, false,  Paint.DIRECTION_RTL, currentTextSize);
    139 
    140         // Test Thai
    141         deltaX = testString(canvas, THAI_TEXT, ORIGIN, ORIGIN + 16 * currentTextSize,
    142                 false, false,  Paint.DIRECTION_LTR, currentTextSize);
    143     }
    144 
    145     private int testString(Canvas canvas, String text, int x, int y,
    146             boolean isItalic, boolean isBold, int dir, int textSize) {
    147 
    148         TextPaint paint = new TextPaint();
    149         paint.setAntiAlias(true);
    150 
    151         // Set paint properties
    152         boolean oldFakeBold = paint.isFakeBoldText();
    153         paint.setFakeBoldText(isBold);
    154 
    155         float oldTextSkewX = paint.getTextSkewX();
    156         if (isItalic) {
    157             paint.setTextSkewX(DEFAULT_ITALIC_SKEW_X);
    158         }
    159 
    160         paint.setTextSize(textSize);
    161         paint.setColor(Color.WHITE);
    162         canvas.drawText(text, x, y, paint);
    163 
    164         int length = text.length();
    165         float[] advances = new float[length];
    166         float textWidthHB = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0);
    167         setPaintDir(paint, dir);
    168         float textWidthICU = paint.getTextRunAdvances(text, 0, length, 0, length, dir, advances, 0,
    169                 1 /* use ICU */);
    170 
    171         logAdvances(text, textWidthHB, textWidthICU, advances);
    172         drawMetricsAroundText(canvas, x, y, textWidthHB, textWidthICU, textSize, Color.RED, Color.GREEN);
    173 
    174         // Restore old paint properties
    175         paint.setFakeBoldText(oldFakeBold);
    176         paint.setTextSkewX(oldTextSkewX);
    177 
    178         return (int) Math.ceil(textWidthHB) + TEXT_PADDING;
    179     }
    180 
    181     private void setPaintDir(Paint paint, int dir) {
    182         Log.v(TAG, "Setting Paint dir=" + dir);
    183         paint.setBidiFlags(dir);
    184     }
    185 
    186     private void drawInsideRect(Canvas canvas, Paint paint, int color) {
    187         paint.setColor(color);
    188         int width = getWidth();
    189         int height = getHeight();
    190         rect.set(BORDER_PADDING, BORDER_PADDING, width - BORDER_PADDING, height - BORDER_PADDING);
    191         canvas.drawRect(rect, paint);
    192     }
    193 
    194     private void drawMetricsAroundText(Canvas canvas, int x, int y, float textWidthHB,
    195             float textWidthICU, int textSize, int color, int colorICU) {
    196         Paint paint = new Paint();
    197         paint.setColor(color);
    198         canvas.drawLine(x, y - textSize, x, y + 8, paint);
    199         canvas.drawLine(x, y + 8, x + textWidthHB, y + 8, paint);
    200         canvas.drawLine(x + textWidthHB, y - textSize, x + textWidthHB, y + 8, paint);
    201         paint.setColor(colorICU);
    202         canvas.drawLine(x + textWidthICU, y - textSize, x + textWidthICU, y + 8, paint);
    203     }
    204 
    205     private void logAdvances(String text, float textWidth, float textWidthICU, float[] advances) {
    206         Log.v(TAG, "Advances for text: " + text + " total= " + textWidth + " - totalICU= " + textWidthICU);
    207 //        int length = advances.length;
    208 //        for(int n=0; n<length; n++){
    209 //            Log.v(TAG, "adv[" + n + "]=" + advances[n]);
    210 //        }
    211     }
    212 }
    213