• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 com.android.layoutlib.bridge.impl.DelegateManager;
20 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
21 
22 import android.annotation.NonNull;
23 import android.graphics.BidiRenderer;
24 import android.graphics.Paint;
25 import android.graphics.Paint_Delegate;
26 import android.graphics.RectF;
27 import android.graphics.text.LineBreaker_Delegate.Builder;
28 import android.graphics.text.LineBreaker_Delegate.Run;
29 
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 
33 /**
34  * Delegate that provides implementation for native methods in
35  * {@link android.graphics.text.MeasuredText}
36  * <p/>
37  * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
38  * by calls to methods of the same name in this delegate class.
39  *
40  */
41 public class MeasuredText_Builder_Delegate {
42     // ---- Builder delegate manager ----
43     protected static final DelegateManager<MeasuredText_Builder_Delegate>
44             sBuilderManager =
45             new DelegateManager<>(MeasuredText_Builder_Delegate.class);
46 
47     protected final ArrayList<Run> mRuns = new ArrayList<>();
48 
49     @LayoutlibDelegate
nInitBuilder()50     /*package*/ static long nInitBuilder() {
51         return sBuilderManager.addNewDelegate(new MeasuredText_Builder_Delegate());
52     }
53 
54     /**
55      * Apply style to make native measured text.
56      *
57      * @param nativeBuilderPtr The native NativeMeasuredParagraph builder pointer.
58      * @param paintPtr The native paint pointer to be applied.
59      * @param start The start offset in the copied buffer.
60      * @param end The end offset in the copied buffer.
61      * @param isRtl True if the text is RTL.
62      */
63     @LayoutlibDelegate
nAddStyleRun(long nativeBuilderPtr, long paintPtr, int start, int end, boolean isRtl)64     /*package*/ static void nAddStyleRun(long nativeBuilderPtr, long paintPtr, int start,
65             int end, boolean isRtl) {
66         MeasuredText_Builder_Delegate builder = sBuilderManager.getDelegate(nativeBuilderPtr);
67         if (builder == null) {
68             return;
69         }
70         builder.mRuns.add(new StyleRun(paintPtr, start, end, isRtl));
71     }
72 
73     /**
74      * Apply ReplacementRun to make native measured text.
75      *
76      * @param nativeBuilderPtr The native NativeMeasuredParagraph builder pointer.
77      * @param paintPtr The native paint pointer to be applied.
78      * @param start The start offset in the copied buffer.
79      * @param end The end offset in the copied buffer.
80      * @param width The width of the replacement.
81      */
82     @LayoutlibDelegate
nAddReplacementRun(long nativeBuilderPtr, long paintPtr, int start, int end, float width)83     /*package*/ static void nAddReplacementRun(long nativeBuilderPtr, long paintPtr, int start,
84             int end, float width) {
85         MeasuredText_Builder_Delegate builder = sBuilderManager.getDelegate(nativeBuilderPtr);
86         if (builder == null) {
87             return;
88         }
89         builder.mRuns.add(new ReplacementRun(start, end, width));
90     }
91 
92     @LayoutlibDelegate
nBuildMeasuredText(long nativeBuilderPtr, long hintMtPtr, @NonNull char[] text, boolean computeHyphenation, boolean computeLayout)93     /*package*/ static long nBuildMeasuredText(long nativeBuilderPtr, long hintMtPtr,
94             @NonNull char[] text, boolean computeHyphenation, boolean computeLayout) {
95         MeasuredText_Delegate delegate = new MeasuredText_Delegate();
96         delegate.mNativeBuilderPtr = nativeBuilderPtr;
97         return MeasuredText_Delegate.sManager.addNewDelegate(delegate);
98     }
99 
100     @LayoutlibDelegate
nFreeBuilder(long nativeBuilderPtr)101     /*package*/ static void nFreeBuilder(long nativeBuilderPtr) {
102         sBuilderManager.removeJavaReferenceFor(nativeBuilderPtr);
103     }
104 
measureText(long nativePaint, char[] text, int index, int count, float[] widths, int bidiFlags)105     private static float measureText(long nativePaint, char[] text, int index, int count,
106             float[] widths, int bidiFlags) {
107         Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
108         RectF bounds =
109                 new BidiRenderer(null, paint, text).renderText(index, index + count, bidiFlags,
110                         widths, 0, false);
111         return bounds.right - bounds.left;
112     }
113 
114     private static class StyleRun extends Run {
115         private final long mNativePaint;
116         private final boolean mIsRtl;
117 
StyleRun(long nativePaint, int start, int end, boolean isRtl)118         private StyleRun(long nativePaint, int start, int end, boolean isRtl) {
119             super(start, end);
120             mNativePaint = nativePaint;
121             mIsRtl = isRtl;
122         }
123 
124         @Override
addTo(Builder builder)125         void addTo(Builder builder) {
126             int bidiFlags = mIsRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
127             measureText(mNativePaint, builder.mText, mStart, mEnd - mStart, builder.mWidths,
128                     bidiFlags);
129         }
130     }
131 
132     private static class ReplacementRun extends Run {
133         private final float mWidth;
134 
ReplacementRun(int start, int end, float width)135         private ReplacementRun(int start, int end, float width) {
136             super(start, end);
137             mWidth = width;
138         }
139 
140         @Override
addTo(Builder builder)141         void addTo(Builder builder) {
142             builder.mWidths[mStart] = mWidth;
143             Arrays.fill(builder.mWidths, mStart + 1, mEnd, 0.0f);
144         }
145     }
146 }
147