Skip to content

Commit d59a684

Browse files
gnpricechrisbobbe
authored andcommitted
logo: Generate launcher icons, as Zulip logo plus "BETA"
This script is adapted lightly from the one with the same name in zulip-mobile. The SVGs that describe the design are also lightly adapted from what we have in zulip-mobile for debug builds. (Which say "DEBUG" rather than "BETA".) Fixes: #390
1 parent 7649477 commit d59a684

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+343
-90
lines changed
-544 Bytes
Binary file not shown.
Binary file not shown.
-442 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Lines changed: 60 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,92 @@
11
{
2-
"images" : [
2+
"images": [
33
{
4-
"size" : "20x20",
5-
"idiom" : "iphone",
6-
"filename" : "Icon-App-20x20@2x.png",
7-
"scale" : "2x"
4+
"size": "60x60",
5+
"idiom": "iphone",
6+
"filename": "Icon-60x60@3x.png",
7+
"scale": "3x"
88
},
99
{
10-
"size" : "20x20",
11-
"idiom" : "iphone",
12-
"filename" : "Icon-App-20x20@3x.png",
13-
"scale" : "3x"
10+
"size": "60x60",
11+
"idiom": "iphone",
12+
"filename": "Icon-60x60@2x.png",
13+
"scale": "2x"
1414
},
1515
{
16-
"size" : "29x29",
17-
"idiom" : "iphone",
18-
"filename" : "Icon-App-29x29@1x.png",
19-
"scale" : "1x"
16+
"size": "83.5x83.5",
17+
"idiom": "ipad",
18+
"filename": "Icon-83.5x83.5@2x.png",
19+
"scale": "2x"
2020
},
2121
{
22-
"size" : "29x29",
23-
"idiom" : "iphone",
24-
"filename" : "Icon-App-29x29@2x.png",
25-
"scale" : "2x"
22+
"size": "76x76",
23+
"idiom": "ipad",
24+
"filename": "Icon-76x76@2x.png",
25+
"scale": "2x"
2626
},
2727
{
28-
"size" : "29x29",
29-
"idiom" : "iphone",
30-
"filename" : "Icon-App-29x29@3x.png",
31-
"scale" : "3x"
28+
"size": "1024x1024",
29+
"idiom": "ios-marketing",
30+
"filename": "Icon-1024x1024@1x.png",
31+
"scale": "1x"
3232
},
3333
{
34-
"size" : "40x40",
35-
"idiom" : "iphone",
36-
"filename" : "Icon-App-40x40@2x.png",
37-
"scale" : "2x"
34+
"size": "40x40",
35+
"idiom": "iphone",
36+
"filename": "Icon-40x40@3x.png",
37+
"scale": "3x"
3838
},
3939
{
40-
"size" : "40x40",
41-
"idiom" : "iphone",
42-
"filename" : "Icon-App-40x40@3x.png",
43-
"scale" : "3x"
40+
"size": "40x40",
41+
"idiom": "iphone",
42+
"filename": "Icon-40x40@2x.png",
43+
"scale": "2x"
4444
},
4545
{
46-
"size" : "60x60",
47-
"idiom" : "iphone",
48-
"filename" : "Icon-App-60x60@2x.png",
49-
"scale" : "2x"
46+
"size": "40x40",
47+
"idiom": "ipad",
48+
"filename": "Icon-40x40@2x.png",
49+
"scale": "2x"
5050
},
5151
{
52-
"size" : "60x60",
53-
"idiom" : "iphone",
54-
"filename" : "Icon-App-60x60@3x.png",
55-
"scale" : "3x"
52+
"size": "29x29",
53+
"idiom": "iphone",
54+
"filename": "Icon-29x29@3x.png",
55+
"scale": "3x"
5656
},
5757
{
58-
"size" : "20x20",
59-
"idiom" : "ipad",
60-
"filename" : "Icon-App-20x20@1x.png",
61-
"scale" : "1x"
58+
"size": "29x29",
59+
"idiom": "iphone",
60+
"filename": "Icon-29x29@2x.png",
61+
"scale": "2x"
6262
},
6363
{
64-
"size" : "20x20",
65-
"idiom" : "ipad",
66-
"filename" : "Icon-App-20x20@2x.png",
67-
"scale" : "2x"
64+
"size": "29x29",
65+
"idiom": "ipad",
66+
"filename": "Icon-29x29@2x.png",
67+
"scale": "2x"
6868
},
6969
{
70-
"size" : "29x29",
71-
"idiom" : "ipad",
72-
"filename" : "Icon-App-29x29@1x.png",
73-
"scale" : "1x"
70+
"size": "20x20",
71+
"idiom": "iphone",
72+
"filename": "Icon-20x20@3x.png",
73+
"scale": "3x"
7474
},
7575
{
76-
"size" : "29x29",
77-
"idiom" : "ipad",
78-
"filename" : "Icon-App-29x29@2x.png",
79-
"scale" : "2x"
76+
"size": "20x20",
77+
"idiom": "iphone",
78+
"filename": "Icon-20x20@2x.png",
79+
"scale": "2x"
8080
},
8181
{
82-
"size" : "40x40",
83-
"idiom" : "ipad",
84-
"filename" : "[email protected]",
85-
"scale" : "1x"
86-
},
87-
{
88-
"size" : "40x40",
89-
"idiom" : "ipad",
90-
"filename" : "[email protected]",
91-
"scale" : "2x"
92-
},
93-
{
94-
"size" : "76x76",
95-
"idiom" : "ipad",
96-
"filename" : "[email protected]",
97-
"scale" : "1x"
98-
},
99-
{
100-
"size" : "76x76",
101-
"idiom" : "ipad",
102-
"filename" : "[email protected]",
103-
"scale" : "2x"
104-
},
105-
{
106-
"size" : "83.5x83.5",
107-
"idiom" : "ipad",
108-
"filename" : "[email protected]",
109-
"scale" : "2x"
110-
},
111-
{
112-
"size" : "1024x1024",
113-
"idiom" : "ios-marketing",
114-
"filename" : "[email protected]",
115-
"scale" : "1x"
82+
"size": "20x20",
83+
"idiom": "ipad",
84+
"filename": "[email protected]",
85+
"scale": "2x"
11686
}
11787
],
118-
"info" : {
119-
"version" : 1,
120-
"author" : "xcode"
88+
"info": {
89+
"version": 1,
90+
"author": "xcode"
12191
}
12292
}
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

tools/generate-logos

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env bash
2+
set -eu
3+
4+
# Generate the many different versions of our logo we need across the app.
5+
#
6+
# This script is not run as part of the build, in order to avoid introducing
7+
# its somewhat specialized dependencies as requirements for normal
8+
# development. Instead, we keep its outputs checked into the repo.
9+
10+
# Because this script isn't meant to be run routinely, we let it be a bit
11+
# rough-and-ready in its interface. But it should error early if it's
12+
# missing anything it needs.
13+
#
14+
# Much of the knowledge it encodes -- what contexts call for which
15+
# graphical variation of the logo, in what sizes and what format --
16+
# was compiled at https://github.com/zulip/zulip-mobile/issues/4200
17+
# before being turned into this executable form (first for zulip-mobile).
18+
19+
# TIP: Everything in this script has the handy property that its
20+
# outputs are reproducible. That means that if you run it and
21+
# `git status` shows that it's changed any of the files in the
22+
# tree... then either the source images, or something in the
23+
# script itself, has changed since the run reflected in your
24+
# current tree.
25+
26+
this_dir=${BASH_SOURCE[0]%/*}
27+
# shellcheck source=tools/lib/ensure-coreutils.sh
28+
. "${this_dir}"/lib/ensure-coreutils.sh
29+
root_dir=$(readlink -f "${this_dir}"/..)
30+
31+
tmpdir=$(mktemp -d)
32+
33+
die() {
34+
echo >&2 "$1"
35+
exit 1
36+
}
37+
38+
inkscape --version >/dev/null 2>&1 \
39+
|| die "Need inkscape -- try 'apt install inkscape'."
40+
41+
cwebp -version >/dev/null 2>&1 \
42+
|| die "Need cwebp -- try 'apt install webp'."
43+
44+
jq --version >/dev/null 2>&1 \
45+
|| die "Need jq -- try 'apt install jq'."
46+
47+
48+
# This should point to a zulip.git worktree.
49+
zulip_root="${root_dir%/*}"/zulip
50+
51+
# White Z in gradient-colored circle.
52+
src_icon_circle="${zulip_root}"/static/images/logo/zulip-icon-circle.svg
53+
54+
# White Z in gradient-colored circle with BETA banner.
55+
# Contains a link to the equivalent of ${src_icon_circle}.
56+
src_icon_circle_beta="${root_dir}"/tools/zulip-icon-circle-beta.svg
57+
58+
# White Z in gradient-colored square, full-bleed.
59+
# src_icon_square="${zulip_root}"/static/images/logo/zulip-icon-square.svg
60+
61+
# White Z in gradient-colored square, full-bleed, with BETA banner.
62+
# Contains a link to the equivalent of ${src_icon_square}.
63+
src_icon_square_beta="${root_dir}"/tools/zulip-icon-square-beta.svg
64+
65+
66+
[ -r "${src_icon_circle}" ] \
67+
|| die "Expected Zulip worktree at: ${zulip_root}"
68+
69+
70+
make_one_ios_app_icon() {
71+
# SET BY CALLER: contents iconset
72+
local size_pt="$1" scale="$2" idiom="$3"
73+
local size_px="${4-$(( size_pt * scale ))}"
74+
75+
local output_basename=Icon-"${size_pt}x${size_pt}@${scale}x".png
76+
local output="${iconset}"/"${output_basename}"
77+
if [ ! -f "${output}" ]; then
78+
inkscape "${src_icon_square_beta}" -w "${size_px}" --export-png="${output}"
79+
fi
80+
81+
printf >>"${contents}" \
82+
' { "size": "%s", "idiom": "%s", "filename": "%s", "scale": "%s" }\n' \
83+
"${size_pt}x${size_pt}" "${idiom}" "${output_basename}" "${scale}x"
84+
}
85+
86+
make_ios_app_icon() {
87+
local iconset=ios/Runner/Assets.xcassets/AppIcon.appiconset
88+
rm -rf "${iconset}"
89+
mkdir -p "${iconset}"
90+
91+
local contents="${tmpdir}"/Contents.json.in
92+
rm -f "${contents}"
93+
94+
# Handy command for a compact view of what's in the contents:
95+
# $ jq '.images[] | "\(.size) \(.scale) \(.idiom)"' -r \
96+
# <"${iconset}"/Contents.json
97+
98+
# From "App Icon Sizes" at:
99+
# https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/
100+
make_one_ios_app_icon 60 3 iphone
101+
make_one_ios_app_icon 60 2 iphone
102+
make_one_ios_app_icon 83.5 2 ipad 167
103+
make_one_ios_app_icon 76 2 ipad
104+
make_one_ios_app_icon 1024 1 ios-marketing
105+
106+
# From "Spotlight, Settings, and Notification Icons"
107+
# in the same iOS doc
108+
make_one_ios_app_icon 40 3 iphone
109+
make_one_ios_app_icon 40 2 iphone
110+
make_one_ios_app_icon 40 2 ipad
111+
make_one_ios_app_icon 29 3 iphone
112+
make_one_ios_app_icon 29 2 iphone
113+
make_one_ios_app_icon 29 2 ipad
114+
make_one_ios_app_icon 20 3 iphone
115+
make_one_ios_app_icon 20 2 iphone
116+
make_one_ios_app_icon 20 2 ipad
117+
118+
jq <"${contents}" \
119+
-s '{ "images": ., "info": { "version": 1, "author": "xcode" } }' \
120+
>"${iconset}"/Contents.json
121+
}
122+
123+
make_ios() {
124+
make_ios_app_icon
125+
}
126+
127+
128+
make_webp() {
129+
local input="$1" size="$2" output="$3"
130+
inkscape "${input}" -w "${size}" --export-png="${tmpdir}"/tmp.png
131+
# `cwebp -z 9` means lossless, and max/slowest compression
132+
cwebp -z 9 "${tmpdir}"/tmp.png -o "${output}"
133+
}
134+
135+
make_one_android_icon() {
136+
# SET BY CALLER: src sourceset restype name
137+
local size_px="$1" density="$2"
138+
local output=android/app/src/"${sourceset}"/res/"${restype}"-"${density}"/"${name}".webp
139+
mkdir -p "${output%/*}"
140+
make_webp "${src}" "${size_px}" "${output}"
141+
}
142+
143+
make_android_icon() {
144+
local src="$1" size_dp="$2" sourceset="$3" restype="$4" name="$5"
145+
146+
rm -f android/app/src/"${sourceset}"/res/*/"${name}".*
147+
148+
# Scale factors from:
149+
# https://developer.android.com/training/multiscreen/screendensities#TaskProvideAltBmp
150+
make_one_android_icon "${size_dp}" mdpi
151+
make_one_android_icon $(( size_dp * 3 / 2 )) hdpi
152+
make_one_android_icon $(( size_dp * 2 )) xhdpi
153+
make_one_android_icon $(( size_dp * 3 )) xxhdpi
154+
make_one_android_icon $(( size_dp * 4 )) xxxhdpi
155+
}
156+
157+
make_android() {
158+
# Launcher icon goes in a mipmap:
159+
# https://developer.android.com/training/multiscreen/screendensities#mipmap
160+
make_android_icon "${src_icon_circle_beta}" 48 main mipmap ic_launcher
161+
}
162+
163+
make_ios
164+
165+
make_android
166+
167+
cat <<'EOF'
168+
169+
Done!
170+
171+
If `git status` shows any changes in this script's outputs, be sure to
172+
commit those alongside your changes to the script itself.
173+
EOF

0 commit comments

Comments
 (0)