Skip to content

Commit

Permalink
Fix fonts duplication in android app. (#4284)
Browse files Browse the repository at this point in the history
  • Loading branch information
terrakok authored Feb 12, 2024
1 parent 689f631 commit fbf5dbe
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.jetbrains.compose.resources

import java.io.File

private object AndroidResourceReader

@OptIn(ExperimentalResourceApi::class)
@InternalResourceApi
actual suspend fun readResourceBytes(path: String): ByteArray {
val classLoader = Thread.currentThread().contextClassLoader ?: AndroidResourceReader.javaClass.classLoader
val resource = classLoader.getResourceAsStream(path) ?: run {
//try to find a font in the android assets
if (File(path).parentFile?.name.orEmpty() == "font") {
classLoader.getResourceAsStream("assets/$path")
} else null
} ?: throw MissingResourceException(path)
return resource.readBytes()
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import org.jetbrains.compose.desktop.application.internal.ComposeProperties
import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID
import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID
import org.jetbrains.compose.internal.utils.*
import org.jetbrains.compose.internal.utils.dependsOn
import org.jetbrains.compose.internal.utils.registerTask
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
Expand Down Expand Up @@ -74,17 +72,31 @@ private fun Project.configureAndroidComposeResources(
kotlinExtension: KotlinMultiplatformExtension,
androidExtension: BaseExtension
) {
val commonResourcesDir = projectDir.resolve("src/${KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME}/$COMPOSE_RESOURCES_DIR")

//Copy common compose resources except fonts to android resources
val copyCommonAndroidComposeResources = registerTask<CopyCommonAndroidComposeResources>(
"copyCommonAndroidComposeResources"
) {
from.set(commonResourcesDir)
outputDirectory.set(layout.buildDirectory.dir("$RES_GEN_DIR/commonAndroidComposeResources"))
}
tasks.configureEachWithType<ProcessJavaResTask> { dependsOn(copyCommonAndroidComposeResources) }

//mark all composeResources as Android resources
kotlinExtension.targets.matching { it is KotlinAndroidTarget }.all { androidTarget ->
kotlinExtension.targets.withType(KotlinAndroidTarget::class.java).all { androidTarget ->
androidTarget.compilations.all { compilation: KotlinCompilation<*> ->
compilation.defaultSourceSet.androidSourceSetInfoOrNull?.let { kotlinAndroidSourceSet ->
androidExtension.sourceSets
.matching { it.name == kotlinAndroidSourceSet.androidSourceSetName }
.all { androidSourceSet ->
(compilation.allKotlinSourceSets as ObservableSet<KotlinSourceSet>).forAll { kotlinSourceSet ->
androidSourceSet.resources.srcDir(
projectDir.resolve("src/${kotlinSourceSet.name}/$COMPOSE_RESOURCES_DIR")
)
androidSourceSet.resources.srcDir(copyCommonAndroidComposeResources.flatMap { it.outputDirectory.asFile })
(compilation.allKotlinSourceSets as? ObservableSet<KotlinSourceSet>)?.forAll { kotlinSourceSet ->
if (kotlinSourceSet.name != KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) {
androidSourceSet.resources.srcDir(
projectDir.resolve("src/${kotlinSourceSet.name}/$COMPOSE_RESOURCES_DIR")
)
}
}
}
}
Expand All @@ -93,7 +105,6 @@ private fun Project.configureAndroidComposeResources(

//copy fonts from the compose resources dir to android assets
val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return
val commonResourcesDir = projectDir.resolve("src/${KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME}/$COMPOSE_RESOURCES_DIR")
androidComponents.onVariants { variant ->
val copyFonts = registerTask<CopyAndroidFontsToAssetsTask>(
"copy${variant.name.uppercaseFirstChar()}FontsToAndroidAssets"
Expand Down Expand Up @@ -155,6 +166,27 @@ private fun Project.configureResourceGenerator(commonComposeResourcesDir: File,
}
}

internal abstract class CopyCommonAndroidComposeResources : DefaultTask() {
@get:Inject
abstract val fileSystem: FileSystemOperations

@get:InputFiles
abstract val from: Property<File>

@get:OutputDirectory
abstract val outputDirectory: DirectoryProperty

@TaskAction
fun action() {
fileSystem.copy {
it.includeEmptyDirs = false
it.from(from)
it.exclude("**/font*/*")
it.into(outputDirectory)
}
}
}

//Copy task doesn't work with 'variant.sources?.assets?.addGeneratedSourceDirectory' API
internal abstract class CopyAndroidFontsToAssetsTask : DefaultTask() {
@get:Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,12 @@ class ResourcesTest : GradlePluginTestBase() {
assertTrue(apk.exists())
ZipFile(apk).use { zip ->
commonResourcesFiles.forEach { res ->
assertNotNull(zip.getEntry(res))
//todo fix duplicate fonts
if (res == "font/emptyFont.otf") {
//android fonts should be only in assets
assertNull(zip.getEntry(res))
} else {
assertNotNull(zip.getEntry(res))
}
}
assertNotNull(zip.getEntry("assets/font/emptyFont.otf"))
val platformTxt = zip.getEntry("files/platform.txt")
Expand Down

0 comments on commit fbf5dbe

Please sign in to comment.