1 /*
2  * Copyright 2023 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.ui.text.googlefonts
18 
19 import android.annotation.SuppressLint
20 import android.content.Context
21 import android.net.Uri
22 import androidx.annotation.FontRes
23 import androidx.core.content.res.FontResourcesParserCompat
24 import java.lang.IllegalArgumentException
25 
26 /**
27  * Load a Google Font from XML
28  *
29  * This will load only the name and besteffort parameters.
30  *
31  * Compared to the string constructor, this loader adds additional overhead. New code should prefer
32  * to use `GoogleFont(name: String)`.
33  *
34  * @param context to load font from
35  * @param fontXml fontRes to load
36  * @throws IllegalArgumentException if the fontRes does not exist or is not an xml GoogleFont
37  */
38 // This is an API for accessing Google Fonts at fonts.google.com
39 @Suppress("MentionsGoogle")
40 @SuppressLint("ResourceType")
GoogleFontnull41 fun GoogleFont(context: Context, @FontRes fontXml: Int): GoogleFont {
42     val resources = context.resources
43     val xml = resources.getXml(fontXml)
44     val loaded =
45         try {
46             FontResourcesParserCompat.parse(xml, resources)
47                 as? FontResourcesParserCompat.ProviderResourceEntry
48         } catch (cause: Exception) {
49             val resName = resources.getResourceName(fontXml)
50             throw IllegalArgumentException("Unable to load XML fontRes $resName", cause)
51         }
52 
53     requireNotNull(loaded) { "Unable to load XML fontRes ${resources.getResourceName(fontXml)}" }
54 
55     val query = Uri.parse("?" + loaded.request.query)
56     val name =
57         query.getQueryParameter("name")
58             ?: throw IllegalArgumentException(
59                 "No google font name provided in fontRes:" +
60                     " ${resources.getResourceName(fontXml)}"
61             )
62     val bestEffort = query.getQueryParameter("besteffort") ?: "true"
63     return GoogleFont(name, bestEffort == "true")
64 }
65