blob: 9ebf23c2ca6db7a16ed96481967c0dcfec72e410 [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 Nonakab90e08f2017-10-20 15:23:51 -070054static jlong nInit(JNIEnv* env, jclass /* unused */,
Seigo Nonaka9155fa62018-06-05 18:22:03 -070055 jint breakStrategy, jint hyphenationFrequency, jboolean isJustified, jintArray indents) {
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),
58 static_cast<minikin::HyphenationFrequency>(hyphenationFrequency),
59 isJustified,
Seigo Nonaka9155fa62018-06-05 18:22:03 -070060 jintArrayToFloatVector(env, indents)));
Seigo Nonakab90e08f2017-10-20 15:23:51 -070061}
Seigo Nonakabafe1972017-08-24 15:30:29 -070062
Seigo Nonakab90e08f2017-10-20 15:23:51 -070063static void nFinish(jlong nativePtr) {
64 delete toNative(nativePtr);
Raph Levienc94f7422015-03-06 19:19:48 -080065}
Anish Athalyec8f9e622014-07-21 15:26:34 -070066
Seigo Nonaka6f11c6e2018-07-24 11:26:18 -070067// CriticalNative
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010068static jlong nGetReleaseFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka6f11c6e2018-07-24 11:26:18 -070069 return reinterpret_cast<jlong>(nFinish);
70}
71
Seigo Nonakaab9b4792018-09-24 17:37:15 -070072static jlong nComputeLineBreaks(JNIEnv* env, jclass, jlong nativePtr,
Seigo Nonakab90e08f2017-10-20 15:23:51 -070073 // Inputs
Seigo Nonakaef94f492017-11-10 16:11:33 -080074 jcharArray javaText,
Seigo Nonaka6f1868b2017-12-01 16:24:19 -080075 jlong measuredTextPtr,
Seigo Nonakab90e08f2017-10-20 15:23:51 -070076 jint length,
77 jfloat firstWidth,
78 jint firstWidthLineCount,
79 jfloat restWidth,
Seigo Nonakad5621ed2019-03-08 16:04:37 -080080 jfloatArray variableTabStops,
81 jfloat defaultTabStop,
Seigo Nonakaab9b4792018-09-24 17:37:15 -070082 jint indentsOffset) {
Seigo Nonaka3e7deec2017-11-15 12:06:24 -080083 minikin::android::StaticLayoutNative* builder = toNative(nativePtr);
Seigo Nonakab90e08f2017-10-20 15:23:51 -070084
Seigo Nonakaef94f492017-11-10 16:11:33 -080085 ScopedCharArrayRO text(env, javaText);
Seigo Nonakad5621ed2019-03-08 16:04:37 -080086 ScopedNullableFloatArrayRO tabStops(env, variableTabStops);
Seigo Nonakaef94f492017-11-10 16:11:33 -080087
Seigo Nonakabeb16402017-11-22 12:07:16 -080088 minikin::U16StringPiece u16Text(text.get(), length);
Seigo Nonaka6f1868b2017-12-01 16:24:19 -080089 minikin::MeasuredText* measuredText = reinterpret_cast<minikin::MeasuredText*>(measuredTextPtr);
Anish Athalye88b5b0b2014-06-24 14:39:43 -070090
Seigo Nonakaab9b4792018-09-24 17:37:15 -070091 std::unique_ptr<minikin::LineBreakResult> result =
92 std::make_unique<minikin::LineBreakResult>(builder->computeBreaks(
93 u16Text, *measuredText, firstWidth, firstWidthLineCount, restWidth, indentsOffset,
94 tabStops.get(), tabStops.size(), defaultTabStop));
95 return reinterpret_cast<jlong>(result.release());
96}
Anish Athalye88b5b0b2014-06-24 14:39:43 -070097
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010098static jint nGetLineCount(CRITICAL_JNI_PARAMS_COMMA jlong ptr) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -070099 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints.size();
100}
101
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100102static jint nGetLineBreakOffset(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700103 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->breakPoints[i];
104}
105
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100106static jfloat nGetLineWidth(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700107 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->widths[i];
108}
109
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100110static jfloat nGetLineAscent(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700111 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->ascents[i];
112}
113
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100114static jfloat nGetLineDescent(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700115 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->descents[i];
116}
117
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100118static jint nGetLineFlag(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint i) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700119 return reinterpret_cast<minikin::LineBreakResult*>(ptr)->flags[i];
120}
121
122static void nReleaseResult(jlong ptr) {
123 delete reinterpret_cast<minikin::LineBreakResult*>(ptr);
124}
125
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +0100126static jlong nGetReleaseResultFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700127 return reinterpret_cast<jlong>(nReleaseResult);
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700128}
129
Daniel Micay76f6a862015-09-19 17:31:01 -0400130static const JNINativeMethod gMethods[] = {
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700131 // Fast Natives
132 {"nInit", "("
133 "I" // breakStrategy
134 "I" // hyphenationFrequency
135 "Z" // isJustified
136 "[I" // indents
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700137 ")J", (void*) nInit},
138
139 // Critical Natives
Seigo Nonaka6f11c6e2018-07-24 11:26:18 -0700140 {"nGetReleaseFunc", "()J", (void*) nGetReleaseFunc},
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700141
142 // Regular JNI
143 {"nComputeLineBreaks", "("
144 "J" // nativePtr
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700145 "[C" // text
Seigo Nonaka9d3bd082018-01-11 10:02:12 -0800146 "J" // MeasuredParagraph ptr.
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700147 "I" // length
148 "F" // firstWidth
149 "I" // firstWidthLineCount
150 "F" // restWidth
Seigo Nonakad5621ed2019-03-08 16:04:37 -0800151 "[F" // variableTabStops
152 "F" // defaultTabStop
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700153 "I" // indentsOffset
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700154 ")J", (void*) nComputeLineBreaks},
Seigo Nonakab90e08f2017-10-20 15:23:51 -0700155
Seigo Nonakaab9b4792018-09-24 17:37:15 -0700156 // Result accessors, CriticalNatives
157 {"nGetLineCount", "(J)I", (void*)nGetLineCount},
158 {"nGetLineBreakOffset", "(JI)I", (void*)nGetLineBreakOffset},
159 {"nGetLineWidth", "(JI)F", (void*)nGetLineWidth},
160 {"nGetLineAscent", "(JI)F", (void*)nGetLineAscent},
161 {"nGetLineDescent", "(JI)F", (void*)nGetLineDescent},
162 {"nGetLineFlag", "(JI)I", (void*)nGetLineFlag},
163 {"nGetReleaseResultFunc", "()J", (void*)nGetReleaseResultFunc},
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700164};
165
Seigo Nonaka70200b02018-10-01 16:04:11 -0700166int register_android_graphics_text_LineBreaker(JNIEnv* env) {
167 return RegisterMethodsOrDie(env, "android/graphics/text/LineBreaker", gMethods,
168 NELEM(gMethods));
Anish Athalye88b5b0b2014-06-24 14:39:43 -0700169}
170
171}