Skip to content

Commit

Permalink
package: support generating icon mipmap-(xxx)(h/m)dpi entries via `…
Browse files Browse the repository at this point in the history
…--icon-mipmaps`
  • Loading branch information
larpon committed Oct 15, 2024
1 parent e054344 commit a99aa3f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
79 changes: 76 additions & 3 deletions android/package.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module android

import os
import stbi
import regex
import semver
import vab.java
Expand All @@ -20,6 +21,7 @@ pub const default_min_sdk_version = int($d('vab:default_min_sdk_version', 21))
pub const default_base_files_path = get_default_base_files_path()
pub const supported_package_formats = ['apk', 'aab']
pub const supported_lib_folders = ['armeabi', 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64']
pub const mipmap_icon_sizes = [192, 144, 96, 72, 48]! // xxxhdpi, xxhdpi, xhdpi, hdpi, mdpi

// PackageFormat holds all supported package formats
pub enum PackageFormat {
Expand All @@ -43,6 +45,7 @@ pub:
package_id string
activity_name string
icon string
icon_mipmaps bool
version_code int
v_flags []string
input string
Expand Down Expand Up @@ -1223,14 +1226,27 @@ fn prepare_assets(opt PackageOptions) !string {

opt.verbose(1, 'Copying assets...')

icon_path := os.join_path(package_path, 'res', 'mipmap')
is_default_pkg_id := opt.package_id == opt.default_package_id
if !is_default_pkg_id && os.is_file(opt.icon) && os.file_ext(opt.icon) == '.png' {
icon_path := os.join_path(package_path, 'res', 'mipmap')
paths.ensure(icon_path) or { panic(err) }
paths.ensure(icon_path) or { return error('${@FN}: ${err}') }
icon_file := os.join_path(icon_path, 'icon.png')
opt.verbose(1, 'Copying icon...')
os.rm(icon_file) or {}
os.cp(opt.icon, icon_file) or { panic(err) }
os.cp(opt.icon, icon_file) or { return error('${@FN}: ${err}') }
}
if opt.icon_mipmaps {
out_path := os.dir(icon_path) // should be "res" directory
template_icon_file := if opt.icon != '' {
opt.icon
} else {
ls := os.walk_ext(icon_path, '.png')
ls[ls.index(ls[0] or { '' })] or { '' }
}
if os.is_file(template_icon_file) {
opt.verbose(1, 'Generating mipmap icons...')
make_icon_mipmaps(template_icon_file, out_path)
}
}

assets_path := os.join_path(package_path, 'assets')
Expand Down Expand Up @@ -1304,6 +1320,63 @@ fn prepare_assets(opt PackageOptions) !string {
return assets_path
}

fn make_icon_mipmaps(icon_file string, out_path string) {
mut img := stbi.load(icon_file, desired_channels: 0) or {
vabutil.vab_error('${@FN}: error loading ${icon_file}: ${err}')
return
}
defer { img.free() }

mut threads := []thread{}
for size in mipmap_icon_sizes {
threads << spawn make_icon_mipmap(img, out_path, size, size)
}
threads.wait()
}

fn make_icon_mipmap(img stbi.Image, out_path string, w int, h int) {
res_str := match w {
192 {
'xxxhdpi'
}
144 {
'xxhdpi'
}
96 {
'xhdpi'
}
72 {
'hdpi'
}
48 {
'mdpi'
}
else {
vabutil.vab_error('${@FN}: unsupported width of ${w} passed')
return
}
}
rs_img := stbi.resize_uint8(img, w, h) or {
vabutil.vab_error('${@FN}: error resizing ${w} to ${out_path}: ${err}')
return
}
defer { rs_img.free() }
new_path := os.join_path(out_path, 'mipmap-${res_str}')

// eprintln(rs_img)
os.mkdir_all(new_path) or {
vabutil.vab_error('${@FN}: error creating output directory ${new_path}: ${err}')
return
}
out_file := os.join_path(new_path, 'icon.png')
os.rm(out_file) or {}
stbi.stbi_write_png(out_file, rs_img.width, rs_img.height, rs_img.nr_channels, rs_img.data,
(rs_img.width * rs_img.nr_channels)) or {
vabutil.vab_error('${@FN}: error writing output file ${out_file}: ${err}')
return
}
}

pub fn is_valid_package_id(id string) ! {
// https://developer.android.com/studio/build/application-id
// https://stackoverflow.com/a/39331217
Expand Down
2 changes: 2 additions & 0 deletions cli/options.v
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub mut:
c_flags []string @[long: 'cflag'; short: c; xdoc: 'Additional flags for the C compiler']
v_flags []string @[long: 'flag'; short: f; xdoc: 'Additional flags for the V compiler']
lib_name string @[ignore] // Generated field depending on names in input/flags
icon_mipmaps bool @[xdoc: 'Generate App mipmap(-xxxhdpi etc.) icons from either `--icon` or, if exists app skeleton']
assets_extra []string @[long: 'assets'; short: a; xdoc: 'Asset dir(s) to include in build']
libs_extra []string @[long: 'libs'; short: l; xdoc: 'Lib dir(s) to include in build']
version_code int @[xdoc: 'Build version code (android:versionCode)']
Expand Down Expand Up @@ -908,6 +909,7 @@ pub fn (opt &Options) as_android_package_options() android.PackageOptions {
format: format
activity_name: opt.activity_name
icon: opt.icon
icon_mipmaps: opt.icon_mipmaps
version_code: opt.version_code
v_flags: opt.v_flags
input: opt.input
Expand Down

0 comments on commit a99aa3f

Please sign in to comment.