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 android.annotation.NonNull;
20 
21 // Based on the native implementation of Primitive in
22 // frameworks/base/core/jni/android_text_StaticLayout.cpp revision b808260
23 public class Primitive {
24     public final @NonNull PrimitiveType type;
25     public final int location;
26     // The following fields don't make sense for all types.
27     // Box and Glue have width only.
28     // Penalty has both width and penalty.
29     // Word_break has penalty only.
30     public final float width;
31     public final float penalty;
32 
33     /**
34      * Use {@code PrimitiveType#getNewPrimitive()}
35      */
Primitive(@onNull PrimitiveType type, int location, float width, float penalty)36     private Primitive(@NonNull PrimitiveType type, int location, float width, float penalty) {
37         this.type = type;
38         this.location = location;
39         this.width = width;
40         this.penalty = penalty;
41     }
42 
43     public static enum PrimitiveType {
44         /**
45          * Something with a constant width that is to be typeset - like a character.
46          */
47         BOX,
48         /**
49          * Blank space with fixed width.
50          */
51         GLUE,
52         /**
53          * Aesthetic cost indicating how desirable breaking at this point will be. A penalty of
54          * {@link #PENALTY_INFINITY} means a forced non-break, whereas a penalty of negative
55          * {@code #PENALTY_INFINITY} means a forced break.
56          * <p/>
57          * Currently, it only stores penalty with values 0 or -infinity.
58          */
59         PENALTY,
60         /**
61          * For tabs - variable width space.
62          */
63         VARIABLE,
64         /**
65          * Possible breakpoints within a word. Think of this as a high cost {@link #PENALTY}.
66          */
67         WORD_BREAK;
68 
getNewPrimitive(int location)69         public Primitive getNewPrimitive(int location) {
70             assert this == VARIABLE;
71             return new Primitive(this, location, 0f, 0f);
72         }
73 
getNewPrimitive(int location, float value)74         public Primitive getNewPrimitive(int location, float value) {
75             assert this == BOX || this == GLUE || this == WORD_BREAK;
76             if (this == BOX || this == GLUE) {
77                 return new Primitive(this, location, value, 0f);
78             } else {
79                 return new Primitive(this, location, 0f, value);
80             }
81         }
82 
getNewPrimitive(int location, float width, float penalty)83         public Primitive getNewPrimitive(int location, float width, float penalty) {
84             assert this == PENALTY;
85             return new Primitive(this, location, width, penalty);
86         }
87 
88         // forced non-break, negative infinity is forced break.
89         public static final float PENALTY_INFINITY = 1e7f;
90     }
91 }
92 
93