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 @android.ravenwood.annotation.RavenwoodKeepWholeClass 44 public class TextRunShaper { TextRunShaper()45 private TextRunShaper() {} // Do not instantiate 46 47 /** 48 * Shape non-styled text. 49 * 50 * This function shapes the text of the given range under the context of given context range. 51 * Some script, e.g. Arabic or Devanagari, changes letter shape based on its location or 52 * surrounding characters. 53 * 54 * @param text a text buffer to be shaped 55 * @param start a start index of shaping target in the buffer. 56 * @param count a length of shaping target in the buffer. 57 * @param contextStart a start index of context used for shaping in the buffer. 58 * @param contextCount a length of context used for shaping in the buffer. 59 * @param xOffset an additional amount of x offset of the result glyphs. 60 * @param yOffset an additional amount of y offset of the result glyphs. 61 * @param isRtl true if this text is shaped for RTL direction, false otherwise. 62 * @param paint a paint used for shaping text. 63 * @return a shape result. 64 */ 65 @NonNull shapeTextRun( @onNull char[] text, int start, int count, int contextStart, int contextCount, float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint)66 public static PositionedGlyphs shapeTextRun( 67 @NonNull char[] text, int start, int count, int contextStart, int contextCount, 68 float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint) { 69 Preconditions.checkNotNull(text); 70 Preconditions.checkNotNull(paint); 71 return new PositionedGlyphs( 72 nativeShapeTextRun(text, start, count, contextStart, contextCount, isRtl, 73 paint.getNativeInstance()), 74 xOffset, yOffset); 75 } 76 77 /** 78 * Shape non-styled text. 79 * 80 * This function shapes the text of the given range under the context of given context range. 81 * Some script, e.g. Arabic or Devanagari, changes letter shape based on its location or 82 * surrounding characters. 83 * 84 * @param text a text buffer to be shaped. Any styled spans stored in this text are ignored. 85 * @param start a start index of shaping target in the buffer. 86 * @param count a length of shaping target in the buffer. 87 * @param contextStart a start index of context used for shaping in the buffer. 88 * @param contextCount a length of context used for shaping in the buffer. 89 * @param xOffset an additional amount of x offset of the result glyphs. 90 * @param yOffset an additional amount of y offset of the result glyphs. 91 * @param isRtl true if this text is shaped for RTL direction, false otherwise. 92 * @param paint a paint used for shaping text. 93 * @return a shape result 94 */ 95 @NonNull shapeTextRun( @onNull CharSequence text, int start, int count, int contextStart, int contextCount, float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint)96 public static PositionedGlyphs shapeTextRun( 97 @NonNull CharSequence text, int start, int count, int contextStart, int contextCount, 98 float xOffset, float yOffset, boolean isRtl, @NonNull Paint paint) { 99 Preconditions.checkNotNull(text); 100 Preconditions.checkNotNull(paint); 101 if (text instanceof String) { 102 return new PositionedGlyphs( 103 nativeShapeTextRun( 104 (String) text, start, count, contextStart, contextCount, isRtl, 105 paint.getNativeInstance()), 106 xOffset, yOffset); 107 } else { 108 char[] buf = new char[contextCount]; 109 TextUtils.getChars(text, contextStart, contextStart + contextCount, buf, 0); 110 return new PositionedGlyphs( 111 nativeShapeTextRun( 112 buf, start - contextStart, count, 113 0, contextCount, isRtl, paint.getNativeInstance()), 114 xOffset, yOffset); 115 } 116 } 117 nativeShapeTextRun( char[] text, int start, int count, int contextStart, int contextCount, boolean isRtl, long nativePaint)118 private static native long nativeShapeTextRun( 119 char[] text, int start, int count, int contextStart, int contextCount, 120 boolean isRtl, long nativePaint); 121 nativeShapeTextRun( String text, int start, int count, int contextStart, int contextCount, boolean isRtl, long nativePaint)122 private static native long nativeShapeTextRun( 123 String text, int start, int count, int contextStart, int contextCount, 124 boolean isRtl, long nativePaint); 125 126 } 127