1 /* 2 * Copyright (C) 2020 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.graphics.text; 18 19 import android.annotation.NonNull; 20 import android.graphics.Paint; 21 import android.text.TextDirectionHeuristic; 22 import android.text.TextPaint; 23 import android.text.TextUtils; 24 25 import com.android.internal.util.Preconditions; 26 27 import dalvik.annotation.optimization.FastNative; 28 29 /** 30 * Provides conversion from a text into glyph array. 31 * 32 * Text shaping is a preprocess for drawing text into canvas with glyphs. The glyph is a most 33 * primitive unit of the text drawing, consist of glyph identifier in the font file and its position 34 * and style. You can draw the shape result to Canvas by calling Canvas#drawGlyphs. 35 * 36 * For most of the use cases, {@link android.text.TextShaper} will provide text shaping 37 * functionalities needed. {@link TextRunShaper} is a lower level API that is used by 38 * {@link android.text.TextShaper}. 39 * 40 * @see TextRunShaper#shapeTextRun(CharSequence, int, int, int, int, float, float, boolean, Paint) 41 * @see TextRunShaper#shapeTextRun(char[], int, int, int, int, float, float, boolean, Paint) 42 * @see android.text.TextShaper#shapeText(CharSequence, int, int, TextDirectionHeuristic, TextPaint, 43 * TextShaper.GlyphsConsumer) 44 */ 45 public class TextRunShaper { TextRunShaper()46 private TextRunShaper() {} // Do not instantiate 47 48 /** 49 * Shape non-styled text. 50 * 51 * This function shapes the text of the given range under the context of given context range. 52 * Some script, e.g. Arabic or Devanagari, changes letter shape based on its location or 53 * surrounding characters. 54 * 55 * @param text a text buffer to be shaped 56 * @param start a start index of shaping target in the buffer. 57 * @param count a length of shaping target in the buffer. 58 * @param contextStart a start index of context used for shaping in the buffer. 59 * @param contextCount a length of context used for shaping in the buffer. 60 * @param xOffset an additional amount of x offset of the result glyphs. 61 * @param yOffset an additional amount of y offset of the result glyphs. 62 * @param isRtl true if this text is shaped for RTL direction, false otherwise. 63 * @param paint a paint used for shaping text. 64 * @return a shape result. 65 */ 66 @NonNull shapeTextRun( @onNull char[] text, int start, int count, int contextStart, int contextCount, float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint)67 public static PositionedGlyphs shapeTextRun( 68 @NonNull char[] text, int start, int count, int contextStart, int contextCount, 69 float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint) { 70 Preconditions.checkNotNull(text); 71 Preconditions.checkNotNull(paint); 72 return new PositionedGlyphs( 73 nativeShapeTextRun(text, start, count, contextStart, contextCount, isRtl, 74 paint.getNativeInstance()), 75 xOffset, yOffset); 76 } 77 78 /** 79 * Shape non-styled text. 80 * 81 * This function shapes the text of the given range under the context of given context range. 82 * Some script, e.g. Arabic or Devanagari, changes letter shape based on its location or 83 * surrounding characters. 84 * 85 * @param text a text buffer to be shaped. Any styled spans stored in this text are ignored. 86 * @param start a start index of shaping target in the buffer. 87 * @param count a length of shaping target in the buffer. 88 * @param contextStart a start index of context used for shaping in the buffer. 89 * @param contextCount a length of context used for shaping in the buffer. 90 * @param xOffset an additional amount of x offset of the result glyphs. 91 * @param yOffset an additional amount of y offset of the result glyphs. 92 * @param isRtl true if this text is shaped for RTL direction, false otherwise. 93 * @param paint a paint used for shaping text. 94 * @return a shape result 95 */ 96 @NonNull shapeTextRun( @onNull CharSequence text, int start, int count, int contextStart, int contextCount, float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint)97 public static PositionedGlyphs shapeTextRun( 98 @NonNull CharSequence text, int start, int count, int contextStart, int contextCount, 99 float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint) { 100 Preconditions.checkNotNull(text); 101 Preconditions.checkNotNull(paint); 102 if (text instanceof String) { 103 return new PositionedGlyphs( 104 nativeShapeTextRun( 105 (String) text, start, count, contextStart, contextCount, isRtl, 106 paint.getNativeInstance()), 107 xOffset, yOffset); 108 } else { 109 char[] buf = new char[contextCount]; 110 TextUtils.getChars(text, contextStart, contextStart + contextCount, buf, 0); 111 return new PositionedGlyphs( 112 nativeShapeTextRun( 113 buf, start - contextStart, count, 114 0, contextCount, isRtl, paint.getNativeInstance()), 115 xOffset, yOffset); 116 } 117 } 118 119 @FastNative nativeShapeTextRun( char[] text, int start, int count, int contextStart, int contextCount, boolean isRtl, long nativePaint)120 private static native long nativeShapeTextRun( 121 char[] text, int start, int count, int contextStart, int contextCount, 122 boolean isRtl, long nativePaint); 123 124 @FastNative nativeShapeTextRun( String text, int start, int count, int contextStart, int contextCount, boolean isRtl, long nativePaint)125 private static native long nativeShapeTextRun( 126 String text, int start, int count, int contextStart, int contextCount, 127 boolean isRtl, long nativePaint); 128 129 } 130