1 /*
2  * Copyright (C) 2023 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 /** @hide */
20 public class GraphemeBreak {
GraphemeBreak()21     private GraphemeBreak() { }
22 
23     /**
24      * Util method that checks if the offsets in given range are grapheme break.
25      *
26      * @param advances the advances of characters in the given text. It contains the font
27      *                information used by the algorithm to determine the grapheme break. It's useful
28      *                 when some character is missing in the font. For example, if the smile emoji
29      *                 "0xD83D 0xDE0A" is not found in the font and is displayed as 2 characters.
30      *                 We can't treat it as a single grapheme cluster.
31      * @param text the text to be processed.
32      * @param start the start offset of the queried range, inclusive.
33      * @param end the end offset of the queried range, exclusive.
34      * @param isGraphemeBreak the array to receive the result. The i-th element of the
35      *                       array will be set to true if the offset (start + i) is a grapheme
36      *                       break; otherwise, it will be set to false.
37      */
isGraphemeBreak(float[] advances, char[] text, int start, int end, boolean[] isGraphemeBreak)38     public static void isGraphemeBreak(float[] advances, char[] text, int start, int end,
39             boolean[] isGraphemeBreak) {
40         if (start > end) {
41             throw new IllegalArgumentException("start is greater than end: start = " + start
42                     + " end = " + end);
43         }
44         if (advances.length < end) {
45             throw new IllegalArgumentException("the length of advances is less than end"
46                     + "advances.length = " + advances.length
47                     + " end = " + end);
48         }
49         if (isGraphemeBreak.length < end - start) {
50             throw new IndexOutOfBoundsException("isGraphemeBreak doesn't have enough space to "
51                     + "receive the result, isGraphemeBreak.length: " + isGraphemeBreak.length
52                     + " needed space: " + (end - start));
53         }
54         nIsGraphemeBreak(advances, text, start, end, isGraphemeBreak);
55     }
56 
nIsGraphemeBreak(float[] advances, char[] text, int start, int end, boolean[] isGraphemeBreak)57     private static native void nIsGraphemeBreak(float[] advances, char[] text, int start, int end,
58             boolean[] isGraphemeBreak);
59 }
60