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