1 /* <lambda>null2 * Copyright 2020 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 androidx.compose.foundation.text 18 19 import androidx.compose.runtime.getValue 20 import androidx.compose.runtime.remember 21 import androidx.compose.ui.Modifier 22 import androidx.compose.ui.composed 23 import androidx.compose.ui.layout.layout 24 import androidx.compose.ui.platform.LocalDensity 25 import androidx.compose.ui.platform.LocalFontFamilyResolver 26 import androidx.compose.ui.platform.LocalLayoutDirection 27 import androidx.compose.ui.text.TextStyle 28 import androidx.compose.ui.text.font.FontFamily 29 import androidx.compose.ui.text.font.FontStyle 30 import androidx.compose.ui.text.font.FontSynthesis 31 import androidx.compose.ui.text.font.FontWeight 32 import androidx.compose.ui.text.resolveDefaults 33 import androidx.compose.ui.unit.Density 34 import androidx.compose.ui.unit.IntSize 35 import androidx.compose.ui.unit.LayoutDirection 36 37 internal fun Modifier.textFieldMinSize(style: TextStyle) = composed { 38 val density = LocalDensity.current 39 val fontFamilyResolver = LocalFontFamilyResolver.current 40 val layoutDirection = LocalLayoutDirection.current 41 42 val resolvedStyle = remember(style, layoutDirection) { resolveDefaults(style, layoutDirection) } 43 val typeface by 44 remember(fontFamilyResolver, resolvedStyle) { 45 fontFamilyResolver.resolve( 46 resolvedStyle.fontFamily, 47 resolvedStyle.fontWeight ?: FontWeight.Normal, 48 resolvedStyle.fontStyle ?: FontStyle.Normal, 49 resolvedStyle.fontSynthesis ?: FontSynthesis.All 50 ) 51 } 52 53 val minSizeState = remember { 54 TextFieldSize(layoutDirection, density, fontFamilyResolver, style, typeface) 55 } 56 57 minSizeState.update(layoutDirection, density, fontFamilyResolver, resolvedStyle, typeface) 58 59 Modifier.layout { measurable, constraints -> 60 val minSize = minSizeState.minSize 61 62 val childConstraints = 63 constraints.copy( 64 minWidth = minSize.width.coerceIn(constraints.minWidth, constraints.maxWidth), 65 minHeight = minSize.height.coerceIn(constraints.minHeight, constraints.maxHeight) 66 ) 67 val measured = measurable.measure(childConstraints) 68 layout(measured.width, measured.height) { measured.placeRelative(0, 0) } 69 } 70 } 71 72 private class TextFieldSize( 73 var layoutDirection: LayoutDirection, 74 var density: Density, 75 var fontFamilyResolver: FontFamily.Resolver, 76 var resolvedStyle: TextStyle, 77 var typeface: Any 78 ) { 79 var minSize = computeMinSize() 80 private set 81 updatenull82 fun update( 83 layoutDirection: LayoutDirection, 84 density: Density, 85 fontFamilyResolver: FontFamily.Resolver, 86 resolvedStyle: TextStyle, 87 typeface: Any 88 ) { 89 if ( 90 layoutDirection != this.layoutDirection || 91 density != this.density || 92 fontFamilyResolver != this.fontFamilyResolver || 93 resolvedStyle != this.resolvedStyle || 94 typeface != this.typeface 95 ) { 96 this.layoutDirection = layoutDirection 97 this.density = density 98 this.fontFamilyResolver = fontFamilyResolver 99 this.resolvedStyle = resolvedStyle 100 this.typeface = typeface 101 minSize = computeMinSize() 102 } 103 } 104 computeMinSizenull105 private fun computeMinSize(): IntSize { 106 return computeSizeForDefaultText( 107 style = resolvedStyle, 108 density = density, 109 fontFamilyResolver = fontFamilyResolver 110 ) 111 } 112 } 113