AndroidFont.kt
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.ui.text.font
import android.content.res.AssetManager
import android.graphics.Typeface
import android.os.Build
import android.os.ParcelFileDescriptor
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Stable
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.android.InternalPlatformTextApi
import java.io.File
/**
* Create a Font declaration from a file in the assets directory. The content of the [File] is
* read during construction.
*
* @param assetManager Android AssetManager
* @param path full path starting from the assets directory (i.e. dir/myfont.ttf for
* assets/dir/myfont.ttf).
* @param weight The weight of the font. The system uses this to match a font to a font request
* that is given in a [androidx.compose.ui.text.SpanStyle].
* @param style The style of the font, normal or italic. The system uses this to match a font to a
* font request that is given in a [androidx.compose.ui.text.SpanStyle].
*/
@ExperimentalTextApi
@OptIn(InternalPlatformTextApi::class, ExperimentalTextApi::class)
@Stable
fun Font(
assetManager: AssetManager,
path: String,
weight: FontWeight = FontWeight.Normal,
style: FontStyle = FontStyle.Normal
): Font = AndroidAssetFont(assetManager, path, weight, style)
/**
* Create a Font declaration from a file. The content of the [File] is read during construction.
*
* @param file the font file.
* @param weight The weight of the font. The system uses this to match a font to a font request
* that is given in a [androidx.compose.ui.text.SpanStyle].
* @param style The style of the font, normal or italic. The system uses this to match a font to a
* font request that is given in a [androidx.compose.ui.text.SpanStyle].
*/
@ExperimentalTextApi
@OptIn(InternalPlatformTextApi::class, ExperimentalTextApi::class)
@Stable
@Suppress("StreamFiles")
fun Font(
file: File,
weight: FontWeight = FontWeight.Normal,
style: FontStyle = FontStyle.Normal
): Font = AndroidFileFont(file, weight, style)
/**
* Create a Font declaration from a [ParcelFileDescriptor]. The content of the
* [ParcelFileDescriptor] is read during construction.
*
* @param fileDescriptor the file descriptor for the font file.
* @param weight The weight of the font. The system uses this to match a font to a font request
* that is given in a [androidx.compose.ui.text.SpanStyle].
* @param style The style of the font, normal or italic. The system uses this to match a font to a
* font request that is given in a [androidx.compose.ui.text.SpanStyle].
*/
@RequiresApi(26)
@ExperimentalTextApi
@OptIn(InternalPlatformTextApi::class, ExperimentalTextApi::class)
@Stable
fun Font(
fileDescriptor: ParcelFileDescriptor,
weight: FontWeight = FontWeight.Normal,
style: FontStyle = FontStyle.Normal
): Font = AndroidFileDescriptorFont(fileDescriptor, weight, style)
internal interface AndroidFont : Font {
val typeface: Typeface
}
internal class AndroidAssetFont constructor(
val assetManager: AssetManager,
val path: String,
override val weight: FontWeight = FontWeight.Normal,
override val style: FontStyle = FontStyle.Normal
) : AndroidFont {
private val typefaceInternal = Typeface.createFromAsset(assetManager, path)
override val typeface: Typeface get() = typefaceInternal
}
internal class AndroidFileFont constructor(
val file: File,
override val weight: FontWeight = FontWeight.Normal,
override val style: FontStyle = FontStyle.Normal
) : AndroidFont {
private val typefaceInternal = Typeface.createFromFile(file)
override val typeface: Typeface get() = typefaceInternal
}
@RequiresApi(26)
internal class AndroidFileDescriptorFont constructor(
val fileDescriptor: ParcelFileDescriptor,
override val weight: FontWeight = FontWeight.Normal,
override val style: FontStyle = FontStyle.Normal
) : AndroidFont {
private val typefaceInternal = if (Build.VERSION.SDK_INT >= 26) {
AndroidFileDescriptorHelper.create(fileDescriptor)
} else {
throw IllegalArgumentException("Cannot create font from file descriptor for SDK < 26")
}
override val typeface: Typeface get() = typefaceInternal
}
@RequiresApi(26)
private object AndroidFileDescriptorHelper {
@RequiresApi(26)
@DoNotInline
fun create(fileDescriptor: ParcelFileDescriptor): Typeface {
return Typeface.Builder(fileDescriptor.fileDescriptor).build()
}
}