Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2018 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 android.widget.cts;
     18 
     19 import android.content.Context;
     20 import android.graphics.Typeface;
     21 import android.support.test.InstrumentationRegistry;
     22 import android.support.test.filters.SmallTest;
     23 import android.text.Layout;
     24 import android.text.PrecomputedText;
     25 import android.text.PrecomputedText.Params;
     26 import android.text.PrecomputedText.Params.Builder;
     27 import android.text.TextDirectionHeuristic;
     28 import android.text.TextDirectionHeuristics;
     29 import android.text.TextPaint;
     30 import android.text.TextUtils;
     31 import android.util.Pair;
     32 import android.widget.TextView;
     33 
     34 import static org.junit.Assert.fail;
     35 
     36 import org.junit.Test;
     37 import org.junit.runner.RunWith;
     38 import org.junit.runners.Parameterized;
     39 
     40 import java.util.ArrayList;
     41 import java.util.Collection;
     42 import java.util.Locale;
     43 
     44 /**
     45  * Tests for TextView with precomputed text.
     46  */
     47 @RunWith(Parameterized.class)
     48 public class TextViewPrecomputedTextTest {
     49     private static final String TEXT = "Hello, World!";
     50 
     51     @Parameterized.Parameter(0)
     52     public boolean differentTextSize;
     53     @Parameterized.Parameter(1)
     54     public boolean differentScaleX;
     55     @Parameterized.Parameter(2)
     56     public boolean differentSkewX;
     57     @Parameterized.Parameter(3)
     58     public boolean differentLetterSpacing;
     59     @Parameterized.Parameter(4)
     60     public boolean differentTextLocale;
     61     @Parameterized.Parameter(5)
     62     public boolean differentTypeface;
     63     @Parameterized.Parameter(6)
     64     public boolean differentElegantTextHeight;
     65     @Parameterized.Parameter(7)
     66     public boolean differentBreakStrategy;
     67     @Parameterized.Parameter(8)
     68     public boolean differentHyphenationFrequency;
     69     @Parameterized.Parameter(9)
     70     public boolean differentTextDir;
     71     @Parameterized.Parameter(10)
     72     public boolean differentFontVariationSettings;
     73 
     74     // text size from the default value.
     75     private Pair<Params, String[]> makeDifferentParams(Params params) {
     76         final TextPaint paint = new TextPaint(params.getTextPaint());
     77         ArrayList<String> differenceList = new ArrayList();
     78 
     79         if (differentTextSize) {
     80             paint.setTextSize(paint.getTextSize() * 2.0f + 1.0f);
     81             differenceList.add("Text Size");
     82         }
     83         if (differentScaleX) {
     84             paint.setTextScaleX(paint.getTextScaleX() * 2.0f + 1.0f);
     85             differenceList.add("Text Scale X");
     86         }
     87         if (differentSkewX) {
     88             paint.setTextSkewX(paint.getTextSkewX() * 2.0f + 1.0f);
     89             differenceList.add("Text Skew X");
     90         }
     91         if (differentLetterSpacing) {
     92             paint.setLetterSpacing(paint.getLetterSpacing() * 2.0f + 1.0f);
     93             differenceList.add("Letter Spacing");
     94         }
     95         if (differentTextLocale) {
     96             paint.setTextLocale(Locale.US.equals(paint.getTextLocale()) ? Locale.JAPAN : Locale.US);
     97         }
     98         if (differentTypeface) {
     99             final Typeface tf = paint.getTypeface();
    100             if (tf == null || tf == Typeface.DEFAULT) {
    101                 paint.setTypeface(Typeface.SERIF);
    102             } else {
    103                 paint.setTypeface(Typeface.DEFAULT);
    104             }
    105             differenceList.add("Typeface");
    106         }
    107         if (differentFontVariationSettings) {
    108             final String wght = "'wght' 700";
    109             final String wdth = "'wdth' 100";
    110 
    111             final String varSettings = paint.getFontVariationSettings();
    112             if (varSettings == null || varSettings.equals(wght)) {
    113                 paint.setFontVariationSettings(wdth);
    114             } else {
    115                 paint.setFontVariationSettings(wght);
    116             }
    117             differenceList.add("Font variation settings");
    118         }
    119         if (differentElegantTextHeight) {
    120             paint.setElegantTextHeight(!paint.isElegantTextHeight());
    121             differenceList.add("Elegant Text Height");
    122         }
    123 
    124         int strategy = params.getBreakStrategy();
    125         if (differentBreakStrategy) {
    126             strategy = strategy == Layout.BREAK_STRATEGY_SIMPLE
    127                     ?  Layout.BREAK_STRATEGY_HIGH_QUALITY : Layout.BREAK_STRATEGY_SIMPLE;
    128             differenceList.add("Break strategy");
    129         }
    130 
    131         int hyFreq = params.getHyphenationFrequency();
    132         if (differentHyphenationFrequency) {
    133             hyFreq = hyFreq == Layout.HYPHENATION_FREQUENCY_NONE
    134                     ? Layout.HYPHENATION_FREQUENCY_FULL : Layout.HYPHENATION_FREQUENCY_NONE;
    135             differenceList.add("Hyphenation Frequency");
    136         }
    137 
    138         TextDirectionHeuristic dir = params.getTextDirection();
    139         if (differentTextDir) {
    140             dir = dir == TextDirectionHeuristics.LTR
    141                     ?  TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR;
    142             differenceList.add("Text Direction");
    143         }
    144 
    145         final Params outParams = new Builder(paint).setBreakStrategy(strategy)
    146                 .setHyphenationFrequency(hyFreq).setTextDirection(dir).build();
    147         return new Pair(outParams, differenceList.toArray(new String[differenceList.size()]));
    148     }
    149 
    150     private static Context getContext() {
    151         return InstrumentationRegistry.getInstrumentation().getTargetContext();
    152     }
    153 
    154     @Parameterized.Parameters
    155     public static Collection<Object[]> getParameters() {
    156         ArrayList<Object[]> allParams = new ArrayList<>();
    157 
    158         // Compute the powerset except for all false case.
    159         final int allParameterCount = 11;
    160         // The 11-th bit is for font variation settings. Don't add test case if the system don't
    161         // have variable fonts.
    162         final int fullBits = hasVarFont()
    163                 ? (1 << allParameterCount) - 1 : (1 << (allParameterCount - 1)) - 1;
    164         for (int bits = 1; bits <= fullBits; ++bits) {
    165             Object[] param = new Object[allParameterCount];
    166             for (int j = 0; j < allParameterCount; ++j) {
    167                 param[j] = new Boolean((bits & (1 << j)) != 0);
    168             }
    169             allParams.add(param);
    170         }
    171         return allParams;
    172     }
    173 
    174     private static boolean hasVarFont() {
    175         final TextPaint copied = new TextPaint((new TextView(getContext())).getPaint());
    176         return copied.setFontVariationSettings("'wght' 400")
    177                 && copied.setFontVariationSettings("'wdth' 100");
    178     }
    179 
    180     @SmallTest
    181     @Test
    182     public void setText() {
    183         final TextView tv = new TextView(getContext());
    184         final Params tvParams = tv.getTextMetricsParams();
    185         final Pair<Params, String[]> testConfig = makeDifferentParams(tvParams);
    186         final Params pctParams = testConfig.first;
    187 
    188         final PrecomputedText pct = PrecomputedText.create(TEXT, pctParams);
    189         try {
    190             tv.setText(pct);
    191             fail("Test Case: {" + TextUtils.join(",", testConfig.second) + "}, "
    192                     + tvParams.toString() + " vs " + pctParams.toString());
    193         } catch (IllegalArgumentException e) {
    194             // pass
    195         }
    196 
    197         tv.setTextMetricsParams(pctParams);
    198         tv.setText(pct);
    199     }
    200 }
    201