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 package com.android.example.text.styling.roundedbg
17 
18 import android.os.Build
19 import android.text.Layout
20 
21 // Extension functions for Layout object
22 
23 /**
24  * Android system default line spacing extra
25  */
26 private const val DEFAULT_LINESPACING_EXTRA = 0f
27 
28 /**
29  * Android system default line spacing multiplier
30  */
31 private const val DEFAULT_LINESPACING_MULTIPLIER = 1f
32 
33 /**
34  * Get the line bottom discarding the line spacing added.
35  */
Layoutnull36 fun Layout.getLineBottomWithoutSpacing(line: Int): Int {
37     val lineBottom = getLineBottom(line)
38     val lastLineSpacingNotAdded = Build.VERSION.SDK_INT >= 19
39     val isLastLine = line == lineCount - 1
40 
41     val lineBottomWithoutSpacing: Int
42     val lineSpacingExtra = spacingAdd
43     val lineSpacingMultiplier = spacingMultiplier
44     val hasLineSpacing = lineSpacingExtra != DEFAULT_LINESPACING_EXTRA
45         || lineSpacingMultiplier != DEFAULT_LINESPACING_MULTIPLIER
46 
47     if (!hasLineSpacing || isLastLine && lastLineSpacingNotAdded) {
48         lineBottomWithoutSpacing = lineBottom
49     } else {
50         val extra: Float
51         if (lineSpacingMultiplier.compareTo(DEFAULT_LINESPACING_MULTIPLIER) != 0) {
52             val lineHeight = getLineHeight(line)
53             extra = lineHeight - (lineHeight - lineSpacingExtra) / lineSpacingMultiplier
54         } else {
55             extra = lineSpacingExtra
56         }
57 
58         lineBottomWithoutSpacing = (lineBottom - extra).toInt()
59     }
60 
61     return lineBottomWithoutSpacing
62 }
63 
64 /**
65  * Get the line height of a line.
66  */
getLineHeightnull67 fun Layout.getLineHeight(line: Int): Int {
68     return getLineTop(line + 1) - getLineTop(line)
69 }
70 
71 /**
72  * Returns the top of the Layout after removing the extra padding applied by  the Layout.
73  */
getLineTopWithoutPaddingnull74 fun Layout.getLineTopWithoutPadding(line: Int): Int {
75     var lineTop = getLineTop(line)
76     if (line == 0) {
77         lineTop -= topPadding
78     }
79     return lineTop
80 }
81 
82 /**
83  * Returns the bottom of the Layout after removing the extra padding applied by the Layout.
84  */
Layoutnull85 fun Layout.getLineBottomWithoutPadding(line: Int): Int {
86     var lineBottom = getLineBottomWithoutSpacing(line)
87     if (line == lineCount - 1) {
88         lineBottom -= bottomPadding
89     }
90     return lineBottom
91 }