feat(cli): generate icons for iOS (#5667)
@@ -30,6 +30,7 @@ struct IcnsEntry {
|
||||
ostype: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PngEntry {
|
||||
name: String,
|
||||
size: u32,
|
||||
@@ -244,6 +245,83 @@ fn png(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
fn ios_entries(out_dir: &Path) -> Result<Vec<PngEntry>> {
|
||||
struct IosEntry {
|
||||
size: f32,
|
||||
multipliers: Vec<u8>,
|
||||
has_extra: bool,
|
||||
}
|
||||
|
||||
let mut entries = Vec::new();
|
||||
|
||||
let targets = vec![
|
||||
IosEntry {
|
||||
size: 20.,
|
||||
multipliers: vec![1, 2, 3],
|
||||
has_extra: true,
|
||||
},
|
||||
IosEntry {
|
||||
size: 29.,
|
||||
multipliers: vec![1, 2, 3],
|
||||
has_extra: true,
|
||||
},
|
||||
IosEntry {
|
||||
size: 40.,
|
||||
multipliers: vec![1, 2, 3],
|
||||
has_extra: true,
|
||||
},
|
||||
IosEntry {
|
||||
size: 60.,
|
||||
multipliers: vec![2, 3],
|
||||
has_extra: false,
|
||||
},
|
||||
IosEntry {
|
||||
size: 76.,
|
||||
multipliers: vec![1, 2],
|
||||
has_extra: false,
|
||||
},
|
||||
IosEntry {
|
||||
size: 83.5,
|
||||
multipliers: vec![2],
|
||||
has_extra: false,
|
||||
},
|
||||
IosEntry {
|
||||
size: 512.,
|
||||
multipliers: vec![2],
|
||||
has_extra: false,
|
||||
},
|
||||
];
|
||||
|
||||
for target in targets {
|
||||
let size_str = if target.size == 512. {
|
||||
"512".to_string()
|
||||
} else {
|
||||
format!("{size}x{size}", size = target.size)
|
||||
};
|
||||
if target.has_extra {
|
||||
let name = format!("AppIcon-{size_str}@2x-1.png");
|
||||
entries.push(PngEntry {
|
||||
out_path: out_dir.join(&name),
|
||||
name,
|
||||
size: (target.size * 2.) as u32,
|
||||
});
|
||||
}
|
||||
for multiplier in target.multipliers {
|
||||
let name = format!(
|
||||
"AppIcon-{size_str}@{multiplier}x.png",
|
||||
multiplier = multiplier
|
||||
);
|
||||
entries.push(PngEntry {
|
||||
out_path: out_dir.join(&name),
|
||||
name,
|
||||
size: (target.size * multiplier as f32) as u32,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
let mut entries = desktop_entries(out_dir);
|
||||
let _ = crate::mobile::android::with_config(
|
||||
Some(Default::default()),
|
||||
@@ -264,6 +342,19 @@ fn png(source: &DynamicImage, out_dir: &Path) -> Result<()> {
|
||||
},
|
||||
);
|
||||
|
||||
let ios_out = out_dir
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("gen/apple/Assets.xcassets/AppIcon.appiconset");
|
||||
let out = if ios_out.exists() {
|
||||
ios_out
|
||||
} else {
|
||||
let out = out_dir.join("ios");
|
||||
create_dir_all(&out).context("Can't create iOS output directory")?;
|
||||
out
|
||||
};
|
||||
entries.extend(ios_entries(&out)?);
|
||||
|
||||
for entry in entries {
|
||||
log::info!(action = "PNG"; "Creating {}", entry.name);
|
||||
resize_and_save_png(source, entry.size, &entry.out_path)?;
|
||||
|
||||
|
After Width: | Height: | Size: 975 B |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,116 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29x29@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "AppIcon-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-20x20@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-40x40@2x-1.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "AppIcon-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "AppIcon-512@2x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ targets:
|
||||
platform: iOS
|
||||
sources:
|
||||
- path: Sources
|
||||
- path: Assets.xcassets
|
||||
- path: {{app.asset-dir}}
|
||||
buildPhase: resources
|
||||
type: folder
|
||||
|
||||