googlefonts / noto-emoji

Noto Emoji fonts
SIL Open Font License 1.1
3.74k stars 451 forks source link

region flags waved svgs don't have a soft-light effect, unlike the CBDT and COLRv1 versions #398

Open anthrotype opened 2 years ago

anthrotype commented 2 years ago

The waved vector region-flags .svg files inside third_party/region-flags/waved-svg currently display slightly different from the same region-flags as encoded in both the bitmap and vector color fonts.

In particular, the SVG versions do not have the oblique soft-light blending effect that gives the flags a pseudo-3D effect. It's suble but visible when comparing them side by side. E.g. see the Scotland flag:

This screenshot is the SVG file:

Scotland flag SVG (no soft-light)

This one is the glyph from the COLRv1 font in Chrome (notice it gets darker in the lower-right corner, and lighter in the top-left):

Scotland flag COLRv1 (with soft-light)

The bitmap CBDT font has a similar soft-light effect as well (ignore the blur or different color tint):

Screen Shot 2022-07-21 at 11 59 51

The region-flags SVGs are the sources for both the bitmap and COLRv1 fonts; for the bitmap, the non waved SVGs in third_party/region-flags/svg directory are first converted to PNG, compressed (see Makefile), and then passed through the waveflag.c command to be warped and modified with the soft-light blend effect, see: https://github.com/googlefonts/noto-emoji/blob/81a3995aa3b5c5b86996780576f5c437d8bc101b/waveflag.c#L352

Whereas for the COLRv1 font, we created waved versions of the vector region-flags using the rsheeter/warp tool, and checked those in under third_party/region-flags/waved-svg directory (see #3). The soft-light effect is only added in a post-process step to the COLRv1 font with the colrv1_add_soft_light_to_flags.py script (it's translated as a PaintComposite with soft-light blend mode), see: https://github.com/googlefonts/noto-emoji/blob/81a3995aa3b5c5b86996780576f5c437d8bc101b/colrv1_postproc.py#L323

The reason we do in a post-processing stage instead of directly on the waved SVGs produced by the rsheeter/warp tool is because, initially we thought that SVG feBlend element didn't support the soft-light blend mode (https://www.w3.org/TR/SVG11/filters.html#feBlendElement).

However, it turns out that at least on latest Chrome and Safari (but not on FireFox), feBlend now supports all of the CSS blend modes, including soft-light. See this https://codepen.io/yoksel/pen/rNQJBK (forgot exactly how and where I found that link)

In fact I was able to modify the Scotland flag to add the feBlend with soft-light, here's the modified file and the diff vs the original:

emoji_u1f3f4_e0067_e0062_e0073_e0063_e0074_e007f.svg.zip

diff --git a/third_party/region-flags/waved-svg/emoji_u1f3f4_e0067_e0062_e0073_e0063_e0074_e007f.svg b/third_party/region-flags/waved-svg/emoji_u1f3f4_e0067_e0062_e0073_e0063_e0074_e007f.svg
index dd36422d..ae1d6049 100644
--- a/third_party/region-flags/waved-svg/emoji_u1f3f4_e0067_e0062_e0073_e0063_e0074_e007f.svg
+++ b/third_party/region-flags/waved-svg/emoji_u1f3f4_e0067_e0062_e0073_e0063_e0074_e007f.svg
@@ -1,6 +1,20 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
-  <defs/>
-  <path fill="#0065BD" d="M8,195.25 C178.83,110.03 349.03,140.83 521.26,167.28 C676.47,191.12 833.42,211.85 992,132.75 L992,804.75 C821.17,889.97 650.97,859.17 478.74,832.72 C323.53,808.88 166.58,788.15 8,867.25 L8,195.25"/>
-  <path fill="white" d="M8,195.25 C45.89,176.35 83.71,163.05 122.73,154.02 C247.24,210.47 371.63,314.08 500,421.6 C624.49,355.87 749.18,290.83 877.27,173.98 C915.14,165.22 952.97,152.22 992,132.75 L992,211.15 C867.43,358.38 743.02,444.06 614.73,516.4 C738.94,615.98 863.9,702.81 992,726.35 L992,804.75 C954.11,823.65 916.29,836.95 877.27,845.98 C752.76,789.53 628.37,685.92 500,578.4 C375.51,644.13 250.82,709.17 122.73,826.02 C84.86,834.78 47.03,847.78 8,867.25 L8,788.85 C132.57,641.62 256.98,555.94 385.27,483.6 C261.06,384.02 136.1,297.19 8,273.65 L8,195.25"/>
-  <path fill="#1A1A1A" opacity="0.2" d="M8,195.25 C178.83,110.03 349.03,140.83 521.26,167.28 C676.47,191.12 833.42,211.85 992,132.75 L992,804.75 C821.17,889.97 650.97,859.17 478.74,832.72 C323.53,808.88 166.58,788.15 8,867.25 L8,195.25 M39.25,214.64 L39.25,819.14 C345.81,690.88 650.43,915.18 960.75,785.36 L960.75,180.86 C654.19,309.12 349.57,84.82 39.25,214.64"/>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 1000">
+  <defs>
+    <linearGradient id="__lg" x1="0%" y1="0%" x2="100%" y2="100%">
+      <stop offset="0.0" stop-color="#FFFFFF" stop-opacity="0.5"/>
+      <stop offset="0.5" stop-color="#808080" stop-opacity="0.5"/>
+      <stop offset="1.0" stop-color="#000000" stop-opacity="0.5"/>
+    </linearGradient>
+    <rect id="__rect" x="8" y="132" width="984" height="736" fill="url(#__lg)"/>
+    <filter id="__softlight" x="0" y="0" filterUnits="userSpaceOnUse">
+      <feImage xlink:href="#__rect" result="rect"/>
+      <feComposite in="rect" in2="SourceGraphic" operator="in" result="clipped-rect"/>
+      <feBlend in="clipped-rect" in2="SourceGraphic" mode="soft-light"/>
+    </filter>
+  </defs>
+  <g filter="url(#__softlight)">
+    <path fill="#0065BD" d="M8,195.25 C178.83,110.03 349.03,140.83 521.26,167.28 C676.47,191.12 833.42,211.85 992,132.75 L992,804.75 C821.17,889.97 650.97,859.17 478.74,832.72 C323.53,808.88 166.58,788.15 8,867.25 L8,195.25"/>
+    <path fill="white" d="M8,195.25 C45.89,176.35 83.71,163.05 122.73,154.02 C247.24,210.47 371.63,314.08 500,421.6 C624.49,355.87 749.18,290.83 877.27,173.98 C915.14,165.22 952.97,152.22 992,132.75 L992,211.15 C867.43,358.38 743.02,444.06 614.73,516.4 C738.94,615.98 863.9,702.81 992,726.35 L992,804.75 C954.11,823.65 916.29,836.95 877.27,845.98 C752.76,789.53 628.37,685.92 500,578.4 C375.51,644.13 250.82,709.17 122.73,826.02 C84.86,834.78 47.03,847.78 8,867.25 L8,788.85 C132.57,641.62 256.98,555.94 385.27,483.6 C261.06,384.02 136.1,297.19 8,273.65 L8,195.25"/>
+    <path fill="#1A1A1A" opacity="0.2" d="M8,195.25 C178.83,110.03 349.03,140.83 521.26,167.28 C676.47,191.12 833.42,211.85 992,132.75 L992,804.75 C821.17,889.97 650.97,859.17 478.74,832.72 C323.53,808.88 166.58,788.15 8,867.25 L8,195.25 M39.25,214.64 L39.25,819.14 C345.81,690.88 650.43,915.18 960.75,785.36 L960.75,180.86 C654.19,309.12 349.57,84.82 39.25,214.64"/>
+  </g>
 </svg>

Looks like this in Chrome (basically the same in Safari), notice the darkening at the lower-right end compared to the top-left:

Screen Shot 2022-07-21 at 12 32 01

In FireFox (102) however, the unsupported filter is ignored and it looks flat, mono color:

Screen Shot 2022-07-21 at 12 33 56

These above are the standalone SVG rendered in the browsers. However, when the same file with feBlend is embedded in an OT-SVG font (with nanoemoji --color_font untouchedsvg), Safari completely discards the filters and displays the corresponding glyph similarly to the way FireFox does with the standalone SVG above. Possibly this has to do with the fact that filters, in general, are excluded from the svg-native spec and maybe Safari decided to stick to that for OT-SVG fonts.


I file this issue so that I don't lose the results of my experimentation and also as a reminder to revisit this later if/when SVG and/or OT-SVG support for CSS blend modes has improved across implementations.