Ship Material Symbols in the 20 optical-size cut

M3 draws icons at 20 dp from the optical size 20 cut, whose strokes stay as
heavy as the 24 dp design's instead of thinning with the glyph (styles.md
§ Icons, the optical size axis). The package only shipped the 24 cut, so every
20 px icon was a scaled-down 24 (core audit C16). bin/fetch-symbols now checks
out both cuts from the same commit of google/material-design-icons and writes
the new one to resources/svg/symbols/{outlined-20,filled-20}: 4,135 symbols
each, the same names and the same normalisation as the 24 cut.

Plan step 10; finding C16.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 04:00:16 +02:00
co-authored by Claude Fable 5.1
parent b1fc0c9cfa
commit c22d693334
8272 changed files with 8310 additions and 17 deletions
+38 -17
View File
@@ -2,12 +2,15 @@
#
# Refresh resources/svg/symbols from google/material-design-icons (Apache-2.0).
#
# Material Symbols Rounded at weight 400, grade 0 and optical size 24, outlined and
# filled, for every symbol Google publishes. Maintenance only: applications never run
# this, and bin/ is not part of the archive Composer installs.
# Material Symbols Rounded at weight 400 and grade 0, outlined and filled, in two cuts:
# optical size 24 (the standard size) and optical size 20. M3 draws an icon at 20 dp or
# smaller from the 20 cut, whose strokes stay as heavy as the 24 dp design's instead of
# thinning as the glyph is scaled down (docs/reference/m3/styles.md § Icons, the optical
# size axis). Maintenance only: applications never run this, and bin/ is not part of the
# archive Composer installs.
#
# The repository is ~5 GB, so it is cloned without blobs and checked out sparsely:
# git downloads only the two files per symbol that are kept. The @material-symbols
# git downloads only the four files per symbol that are kept. The @material-symbols
# npm packages were not used because their SVGs are drawn at optical size 48, whose
# strokes are thinner than the 24px design.
@@ -24,6 +27,7 @@ cd "$work/repo"
git sparse-checkout set --no-cone \
'/symbols/web/*/materialsymbolsrounded/*_24px.svg' \
'/symbols/web/*/materialsymbolsrounded/*_20px.svg' \
'!/symbols/web/*/materialsymbolsrounded/*_wght[0-9]*' \
'!/symbols/web/*/materialsymbolsrounded/*_grad200*' \
'!/symbols/web/*/materialsymbolsrounded/*_gradN25*'
@@ -31,14 +35,28 @@ git sparse-checkout set --no-cone \
git checkout --quiet "$(git symbolic-ref --short HEAD)"
out="$root/resources/svg/symbols"
rm -rf "$out/outlined" "$out/filled"
mkdir -p "$out/outlined" "$out/filled"
# The 24 cut keeps the folder names it has always had; the 20 cut is suffixed, so a
# name resolves to a folder without a lookup table (Support\SvgFile::symbol()).
folder() { # optical size, style
case "$1" in
24) echo "$out/$2" ;;
*) echo "$out/$2-$1" ;;
esac
}
for size in 24 20; do
for style in outlined filled; do
rm -rf "$(folder "$size" "$style")"
mkdir -p "$(folder "$size" "$style")"
done
done
# Google's files carry width="24" height="24" and no fill. Drop the size so CSS decides
# it, and paint in currentColor so an icon takes the colour of the text around it.
normalise() {
sed -E \
-e 's/ (width|height)="[0-9]+"//g' \
-e 's/ (width|height)="[0-9]+(px)?"//g' \
-e 's/<svg /<svg fill="currentColor" /' \
"$1"
}
@@ -47,19 +65,22 @@ missing=0
for dir in symbols/web/*/materialsymbolsrounded; do
name="$(basename "$(dirname "$dir")")"
outlined="$dir/${name}_24px.svg"
filled="$dir/${name}_fill1_24px.svg"
if [[ ! -f "$outlined" || ! -f "$filled" ]]; then
echo "skipped $name: no outlined and filled 24px pair" >&2
missing=$((missing + 1))
continue
fi
for size in 24 20; do
outlined="$dir/${name}_${size}px.svg"
filled="$dir/${name}_fill1_${size}px.svg"
normalise "$outlined" > "$out/outlined/$name.svg"
normalise "$filled" > "$out/filled/$name.svg"
if [[ ! -f "$outlined" || ! -f "$filled" ]]; then
echo "skipped $name: no outlined and filled ${size}px pair" >&2
missing=$((missing + 1))
continue
fi
normalise "$outlined" > "$(folder "$size" outlined)/$name.svg"
normalise "$filled" > "$(folder "$size" filled)/$name.svg"
done
done
git rev-parse HEAD > "$out/SOURCE"
echo "$(ls "$out/outlined" | wc -l | tr -d ' ') symbols from google/material-design-icons@$(cut -c1-12 "$out/SOURCE"), $missing skipped"
echo "$(ls "$out/outlined" | wc -l | tr -d ' ') symbols at optical size 24 and $(ls "$out/outlined-20" | wc -l | tr -d ' ') at 20 from google/material-design-icons@$(cut -c1-12 "$out/SOURCE"), $missing skipped"