blob: c512256ed9b9041811e2e0b472d192fa637a405d [file] [log] [blame]
Anish Athalye88b5b0b2014-06-24 14:39:43 -07001/*
2 * Copyright (C) 2014 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
Anish Athalye88b5b0b2014-06-24 14:39:43 -070017#include "utils/misc.h"
18#include "utils/Log.h"
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040019#include "graphics_jni_helpers.h"
Steven Moreland2279b252017-07-19 09:50:45 -070020#include <nativehelper/ScopedStringChars.h>
21#include <nativehelper/ScopedPrimitiveArray.h>
Seigo Nonakabeb16402017-11-22 12:07:16 -080022#include "scoped_nullable_primitive_array.h"
Anish Athalyec8f9e622014-07-21 15:26:34 -070023#include <cstdint>
Anish Athalye88b5b0b2014-06-24 14:39:43 -070024#include <vector>
Anish Athalyec8f9e622014-07-21 15:26:34 -070025#include <list>
26#include <algorithm>
Anish Athalye88b5b0b2014-06-24 14:39:43 -070027
Raph Levien70616ec2015-03-04 10:41:30 -080028#include "SkPaint.h"
29#include "SkTypeface.h"
sergeyvdccca442016-03-21 15:38:21 -070030#include <hwui/MinikinSkia.h>
31#include <hwui/MinikinUtils.h>
32#include <hwui/Paint.h>
33#include <minikin/FontCollection.h>
Seigo Nonaka3e7deec2017-11-15 12:06:24 -080034#include <minikin/AndroidLineBreakerHelper.h>
sergeyvdccca442016-03-21 15:38:21 -070035#include <minikin/MinikinFont.h>
Raph Levien4c1f12e2015-03-02 16:29:23 -080036
Anish Athalye88b5b0b2014-06-24 14:39:43 -070037namespace android {
38
Roozbeh Pournader0bba7422017-09-28 12:35:10 -070039static inline std::vector<float> jintArrayToFloatVector(JNIEnv* env, jintArray javaArray) {
40 if (javaArray == nullptr) {
41 return std::vector<float>();
42 } else {
43 ScopedIntArrayRO intArr(env, javaArray);
44 return std::vector<float>(intArr.get(), intArr.get() + intArr.size());
45 }
46}
47
Seigo Nonaka3e7deec2017-11-15 12:06:24 -080048static inline minikin::android::StaticLayoutNative* toNative(jlong ptr) {
49 return reinterpret_cast<minikin::android::StaticLayoutNative*>(ptr);
Seigo Nonakab90e08f2017-10-20 15:23:51 -070050}
51
Roozbeh Pournader95c7a132015-05-12 12:01:06 -070052// set text and set a number of parameters for creating a layout (width, tabstops, strategy,
53// hyphenFrequency)
Seigo Nonaka6e39daf2023-08-19 11:36:26 +090054static jlong nInit(JNIEnv* env, jclass /* unused */, jint breakStrategy, jint hyphenationFrequency,
55 jboolean isJustified, jintArray indents, jboolean useBoundsForWidth) {
Seigo Nonaka3e7deec2017-11-15 12:06:24 -080056 return reinterpret_cast<jlong>(new minikin::android::StaticLayoutNative(
Seigo Nonakab90e08f2017-10-20 15:23:51 -070057 static_cast<minikin::BreakStrategy>(breakStrategy),
Seigo Nonaka6e39daf2023-08-19 11:36:26 +090058 static_cast<minikin::HyphenationFrequency>(hyphenationFrequency), isJustified,
59 jintArrayToFloatVector(env, indents), useBoundsForWidth));
Seigo Nonakab90e08f2017-10-20 15:23:51 -070060}
Seigo Nonakabafe1972017-08-24 15:30:29 -070061
Seigo Nonakab90e08f2017-10-20 15:23:51 -070062static void nFinish(jlong nativePtr) {
63 delete toNative(nativePtr);
Raph Levienc94f7422015-03-06 19:19:48 -080064}
Anish Athalyec8f9e622014-07-21 15:26:34 -070065
Seigo Nonaka6f11c6e2018-07-24 11:26:18 -070066// CriticalNative
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010067static jlong nGetReleaseFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka6f11c6e2018-07-24 11:26:18 -070068 return reinterpret_cast<jlong>(nFinish);
69}
70
Seigo Nonakaab9b4792018-09-24 17:37:15 -070071static jlong nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
Seigo Nonakab90e08f2017-10-20 15:23:51 -070072 // Inputs
Seigo Nonakaef94f492017-11-10 16:11:33 -080073 jcharArray javaText,
Seigo Nonaka6f1868b2017-12-01 16:24:19 -080074 jlong measuredTextPtr,
Seigo Nonakab90e08f2017-10-20 15:23:51 -070075 jint length,
76 jfloat firstWidth,
77 jint firstWidthLineCount,
78 jfloat restWidth,
Seigo Nonakad5621ed2019-03-08 16:04:37 -080079 jfloatArray variableTabStops,
80 jfloat defaultTabStop,
Seigo Nonakaab9b4792018-09-24 17:37:15 -070081 jint indentsOffset) {
Seigo Nonaka3e7deec2017-11-15 12:06:24 -080082 minikin::android::StaticLayoutNative* builder = toNative(nativePtr);
Seigo Nonakab90e08f2017-10-20 15:23:51 -070083
Seigo Nonakaef94f492017-11-10 16:11:33 -080084 ScopedCharArrayRO text(env, javaText);
Seigo Nonakad5621ed2019-03-08 16:04:37 -080085 ScopedNullableFloatArrayRO tabStops(env, variableTabStops);
Seigo Nonakaef94f492017-11-10 16:11:33 -080086
Seigo Nonakabeb16402017-11-22 12:07:16 -080087 minikin::U16StringPiece u16Text(text.get(), length);
Seigo Nonaka6f1868b2017-12-01 16:24:19 -080088 minikin::MeasuredText* measuredText = reinterpret_cast<minikin::MeasuredText*>(measuredTextPtr);
Anish Athalye88b5b0b2014-06-24 14:39:43 -070089
Seigo Nonakaab9b4792018-09-24 17:37:15 -070090 std::unique_ptr<minikin::LineBreakResult> result =
91 std::make_unique<minikin::LineBreakResult>(builder->computeBreaks(
92 u16Text, *measuredText, firstWidth, firstWidthLineCount, restWidth, indentsOffset,
93 tabStops.get(), tabStops.size(), defaultTabStop));
94 return reinterpret_cast<jlong>(result.release());
95}
Anish Athalye88b5b0b2014-06-24 14:39:43 -070096
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010097static jint nGetLineCount(CRITICAL_JNI_PARAMS_COMMA jlong ptr) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -070098 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints.size();
99}
100
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100101static jint nGetLineBreakOffset(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700102 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints[i];
103}
104
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100105static jfloat nGetLineWidth(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700106 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->widths[i];
107}
108
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100109static jfloat nGetLineAscent(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700110 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->ascents[i];
111}
112
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100113static jfloat nGetLineDescent(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700114 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->descents[i];
115}
116
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100117static jint nGetLineFlag(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700118 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->flags[i];
119}
120
121static void nReleaseResult(jlong ptr) {
122 delete reinterpret_cast<minikin::LineBreakResult*>(ptr);
123}
124
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100125static jlong nGetReleaseResultFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700126 return reinterpret_cast<jlong>(nReleaseResult);
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700127}
128
Daniel Micay76f6a862015-09-19 17:31:01 -0400129static const JNINativeMethod gMethods[] = {
Seigo Nonaka6e39daf2023-08-19 11:36:26 +0900130 // Fast Natives
131 {"nInit",
132 "("
133 "I" // breakStrategy
134 "I" // hyphenationFrequency
135 "Z" // isJustified
136 "[I" // indents
137 "Z" // useBoundsForWidth
138 ")J",
139 (void*)nInit},
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700140
Seigo Nonaka6e39daf2023-08-19 11:36:26 +0900141 // Critical Natives
142 {"nGetReleaseFunc", "()J", (void*)nGetReleaseFunc},
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700143
Seigo Nonaka6e39daf2023-08-19 11:36:26 +0900144 // Regular JNI
145 {"nComputeLineBreaks",
146 "("
147 "J" // nativePtr
148 "[C" // text
149 "J" // MeasuredParagraph ptr.
150 "I" // length
151 "F" // firstWidth
152 "I" // firstWidthLineCount
153 "F" // restWidth
154 "[F" // variableTabStops
155 "F" // defaultTabStop
156 "I" // indentsOffset
157 ")J",
158 (void*)nComputeLineBreaks},
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700159
Seigo Nonaka6e39daf2023-08-19 11:36:26 +0900160 // Result accessors, CriticalNatives
161 {"nGetLineCount", "(J)I", (void*)nGetLineCount},
162 {"nGetLineBreakOffset", "(JI)I", (void*)nGetLineBreakOffset},
163 {"nGetLineWidth", "(JI)F", (void*)nGetLineWidth},
164 {"nGetLineAscent", "(JI)F", (void*)nGetLineAscent},
165 {"nGetLineDescent", "(JI)F", (void*)nGetLineDescent},
166 {"nGetLineFlag", "(JI)I", (void*)nGetLineFlag},
167 {"nGetReleaseResultFunc", "()J", (void*)nGetReleaseResultFunc},
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700168};
169
Seigo Nonaka70200b02018-10-01 16:04:11 -0700170int register_android_graphics_text_LineBreaker(JNIEnv* env) {
171 return RegisterMethodsOrDie(env, "android/graphics/text/LineBreaker", gMethods,
172 NELEM(gMethods));
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700173}
174
175}