blob: 96e7fb9c8b169d14f98009fb93934f8539a3c293 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.text;
import static org.junit.Assert.assertArrayEquals;
import android.content.Context;
import android.graphics.Path;
import android.graphics.Typeface;
import android.platform.test.annotations.Presubmit;
import android.text.method.MetaKeyKeyListener;
import android.view.KeyEvent;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@Presubmit
@SmallTest
@RunWith(AndroidJUnit4.class)
public class LayoutBidiCursorPathTest {
private static final float BIDI_TEXT_SIZE = 12f;
private static final String LTR_TEXT = "hello";
private static final String RTL_TEXT = "مرحبا";
private SpannableStringBuilder mBidiText;
private TextPaint mTextPaint;
@Before
public void setup() {
mBidiText = new SpannableStringBuilder(LTR_TEXT + RTL_TEXT);
final Context context = InstrumentationRegistry.getTargetContext();
mTextPaint = new TextPaint();
mTextPaint.setTypeface(
Typeface.createFromAsset(context.getAssets(), "fonts/1em_bidi_font.ttf"));
mTextPaint.setTextSize(BIDI_TEXT_SIZE);
}
@Test
public void testGetCursorPathSegments() {
// Setup layout and Act.
final Path actualPath = new Path();
setupLayoutAndGetCursorPath(actualPath);
// Expected path.
final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
final int top = 0;
// sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
final Path expectedPath = new Path();
expectedPath.moveTo(h1, top);
expectedPath.lineTo(h1, bottom);
// Assert.
assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
}
@Test
public void testGetCursorPath_whenShiftIsPressed() {
// When shift is pressed a triangle is drawn at the bottom quarter of the cursor.
// Set up key.
final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
metaKeyKeyListener
.onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_SHIFT_RIGHT, null /*keyEvent*/);
// Setup layout and Act.
final Path actualPath = new Path();
setupLayoutAndGetCursorPath(actualPath);
// Expected path.
final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
final int top = 0;
// sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
// Draw a triangle at the bottom quarter of the cursor, thus cut the cursor to its 3/4
// length.
final int dist = (bottom - top) / 4;
bottom -= dist;
final Path expectedPath = new Path();
expectedPath.moveTo(h1, top);
expectedPath.lineTo(h1, bottom);
expectedPath.moveTo(h1, bottom);
expectedPath.lineTo(h1 - dist, bottom + dist);
expectedPath.moveTo(h1 - dist, bottom + dist - 0.5f);
expectedPath.lineTo(h1 + dist, bottom + dist - 0.5f);
expectedPath.moveTo(h1 + dist, bottom + dist);
expectedPath.lineTo(h1, bottom);
// Assert.
assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
}
@Test
public void testGetCursorPath_whenAltIsPressed() {
// When alt is pressed a triangle is drawn at the top quarter of the cursor.
// Set up key.
final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
metaKeyKeyListener
.onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_ALT_RIGHT, null /*keyEvent*/);
// Setup layout and Act.
final Path actualPath = new Path();
setupLayoutAndGetCursorPath(actualPath);
// Expected path.
final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
int top = 0;
// sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
// Draw a triangle at the top quarter of the cursor, thus cut the cursor to its 3/4 length.
final int dist = (bottom - top) / 4;
top += dist;
final Path expectedPath = new Path();
expectedPath.moveTo(h1, top);
expectedPath.lineTo(h1, bottom);
expectedPath.moveTo(h1, top);
expectedPath.lineTo(h1 - dist, top - dist);
expectedPath.moveTo(h1 - dist, top - dist + 0.5f);
expectedPath.lineTo(h1 + dist, top - dist + 0.5f);
expectedPath.moveTo(h1 + dist, top - dist);
expectedPath.lineTo(h1, top);
// Assert.
assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
}
private void setupLayoutAndGetCursorPath(Path path) {
final Layout layout = StaticLayout.Builder.obtain(
mBidiText, 0, mBidiText.length(), mTextPaint, Integer.MAX_VALUE)
.setIncludePad(false)
.build();
layout.getCursorPath(LTR_TEXT.length(), path, mBidiText);
}
}