fonttools / fontbakery

🧁 A font quality assurance tool for everyone
https://fontbakery.readthedocs.io
Apache License 2.0
553 stars 103 forks source link

Check quality of overlaps in VFs #2695

Open m4rc1e opened 5 years ago

m4rc1e commented 5 years ago

A user recently reported that Comfortaa has a slight rendering issue at large sizes, https://github.com/google/fonts/issues/2196

This is definitely due to dodgy overlaps.

Imo an overlap should be pretty minimal. Not this.

image

But this.

Screenshot 2019-11-15 at 10 59 26

One way to check could be to do the following:

  1. Calculate the surface area of the glyph (use fonttools area pen)
  2. Remove overlaps from glyph
  3. Calculate the surface area of the glyph again after step 2
  4. Diff both surface areas and WARN user if values are greater than a certain percentage.
m4rc1e commented 4 years ago

Bad overlaps can also impact instantiated static fonts.

Several users have reported overlap issues in older versions of Safari (<10). Since we don't serve variable fonts to these ancient browsers, users are actually getting static fonts that have been instantiated from the variable font.

If the overlaps are badly constructed, they're often visible.

Screenshot 2020-04-14 at 15 04 24 Screenshot 2020-04-14 at 15 04 54

If the overlaps are constructed well, they're not visible.

Screenshot 2020-04-14 at 15 05 33 Screenshot 2020-04-14 at 15 06 07

I've raised this issue internally and the conclusion was there is nothing we can do. Apparently, we are correctly setting bit 6 (OVERLAP_SIMPLE) for the glyf table.

Issues reported:

cc @davelab6

laerm0 commented 4 years ago

This would probably need human eyes for a final run on what the check finds…but that's probably not worth it.

tenuki commented 3 years ago

Hi M4rc13 !?

A user recently reported that Comfortaa has a slight rendering issue at large sizes, google/fonts#2196

I've found it by myself too.. it is annoying :-(

This is definitely due to dodgy overlaps.

Imo an overlap should be pretty minimal. Not this.

What do you mean with 'pretty minimal'? Do you have an idea?

I've converted Comfortaa's a's shape to path in inkscape. Then cloned the shape, and in one of the clones changed the fill-rule to evenodd. After that, I've exported both shapes using object-fit export to png files. pathfull.png containing default fill rule and pathwrong.png using evenodd fill rule.

With that, I used this code to measure:

from PIL import Image
from collections import Counter

def measure(filename):
    im = Image.open(filename)
    rgb_im = im
    print(rgb_im.size)

    s = Counter()
    for x in range(rgb_im.size[0]):
        for y in range(rgb_im.size[1]):
            r,g,b,a = rgb_im.getpixel((x,y))
            if a<=256/4:
                idx = 0
            elif a>=3*(256/4):
                idx = 255 
            else: idx=None
            if not idx is None:
                s[idx]+=1

    print(s)
    print(">10:", sum(1 for x in s if s[x]>10))
    print("ratio:", s[0]/s[255])
    return s

def show(name, data):
    def p(setdata, value):
        return value * 100.0 / (setdata[0]+setdata[255])
    print(name, " black:  %d  (%02.02f)   white:  %d  (%02.02f)" % ( data[0],p(data,data[0]), data[255], p(data,data[255])))

full = measure('pathfull.png')
wrong = measure('pathwrong.png')

show('full',full)
show('wrong', wrong)

Take in consideration that image was exported in there is anti-aliasing to not all points were black or white. And that the "color" (I mean how gray is it) is actually set into the alpha channel. As it was kind of disperse, I accounted them this way: black: those from 100% black to 75% black white: those from 0% black to 25% black discarded the remaining points.

The output is:

C:\Users\aweil\repos\md2pdf>python imgcmp.py pathfull.png
(127, 137)
Counter({0: 10441, 255: 6634})
>10: 2
ratio: 1.5738619234247815
(127, 137)
Counter({0: 10781, 255: 6256})
>10: 2
ratio: 1.7233056265984654

full  black:  10441  (61.15)   white:  6634  (38.85)
wrong  black:  10781  (63.28)   white:  6256  (36.72)

As you can see, the black points in the "wrong" set is 2.13% . Was that the number you were proposing to calculate?

Just in case, these are the files:

pathfull pathwrong

Oops thanks github for allowing me not to upload an .svg file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="210mm"
   height="297mm"
   viewBox="0 0 210 297"
   version="1.1"
   id="svg8"
   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
   sodipodi:docname="font-test.svg">
  <defs
     id="defs2">
    <rect
       x="24.190477"
       y="21.922617"
       width="65.0119"
       height="65.0119"
       id="rect837" />
  </defs>
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="3.4063955"
     inkscape:cx="195.79109"
     inkscape:cy="205.71427"
     inkscape:document-units="mm"
     inkscape:current-layer="layer1"
     inkscape:document-rotation="0"
     showgrid="false"
     inkscape:window-width="1920"
     inkscape:window-height="1027"
     inkscape:window-x="-8"
     inkscape:window-y="-8"
     inkscape:window-maximized="1"
     showguides="true"
     inkscape:guide-bbox="true">
    <sodipodi:guide
       position="77.827866,259.87254"
       orientation="0,-1"
       id="guide904" />
  </sodipodi:namedview>
  <metadata
     id="metadata5">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title />
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <rect
       style="opacity:0.98;fill:none;stroke-width:2.164;stroke:#000000;stroke-opacity:1"
       id="rect10"
       width="65.011902"
       height="65.011902"
       x="24.190477"
       y="21.922617"
       ry="3.1949496" />
    <g
       aria-label=" a"
       transform="matrix(5.4032409,0,0,5.7829711,-105.58851,-116.7866)"
       id="text835"
       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:Comfortaa;-inkscape-font-specification:'Comfortaa, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect837);fill:#000000;fill-opacity:1;stroke:none">
      <path
         d="m 26.955293,31.124574 q -0.625787,0 -1.121541,-0.292575 -0.495753,-0.300703 -0.788329,-0.812711 -0.284449,-0.512008 -0.284449,-1.15405 0,-0.650169 0.292575,-1.162177 0.300703,-0.512009 0.812712,-0.804584 0.512008,-0.300703 1.15405,-0.300703 0.642041,0 1.145922,0.300703 0.512008,0.292575 0.804584,0.804584 0.300703,0.512008 0.30883,1.162177 l -0.25194,0.19505 q 0,0.585152 -0.276322,1.056524 -0.268194,0.463246 -0.739567,0.739568 -0.463246,0.268194 -1.056525,0.268194 z m 0.06502,-0.568898 q 0.471372,0 0.837092,-0.219432 0.373847,-0.219432 0.585152,-0.601406 0.219432,-0.390101 0.219432,-0.8696 0,-0.487627 -0.219432,-0.869601 -0.211305,-0.381974 -0.585152,-0.601406 -0.36572,-0.227559 -0.837092,-0.227559 -0.463245,0 -0.837093,0.227559 -0.373847,0.219432 -0.593279,0.601406 -0.219432,0.381974 -0.219432,0.869601 0,0.479499 0.219432,0.8696 0.219432,0.381974 0.593279,0.601406 0.373848,0.219432 0.837093,0.219432 z m 1.942379,0.528263 q -0.138161,0 -0.227559,-0.08127 -0.0894,-0.0894 -0.0894,-0.227559 v -1.389737 l 0.154415,-0.642041 0.4795,0.121907 v 1.909871 q 0,0.138161 -0.0894,0.227559 -0.0894,0.08127 -0.22756,0.08127 z"
         style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5833px;font-family:Comfortaa;-inkscape-font-specification:'Comfortaa, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.767918"
         id="path886"
         inkscape:export-xdpi="132.53999"
         inkscape:export-ydpi="132.53999" />
    </g>
    <path
       d="m 71.495776,63.3433 q -3.381277,0 -6.059956,-1.691953 -2.678673,-1.738957 -4.259531,-4.699884 -1.536947,-2.960928 -1.536947,-6.673838 0,-3.759909 1.580854,-6.720837 1.62477,-2.960933 4.391278,-4.652886 2.766503,-1.738956 6.23561,-1.738956 3.469102,0 6.191693,1.738956 2.766502,1.691953 4.347361,4.652886 1.624771,2.960928 1.668683,6.720837 l -1.361293,1.127969 q 0,3.383917 -1.493034,6.109847 -1.449117,2.678939 -3.996059,4.276901 -2.503029,1.550958 -5.708659,1.550958 z m 0.351319,-3.289921 q 2.546936,0 4.52301,-1.268969 2.019985,-1.268969 3.161717,-3.477913 1.185644,-2.255943 1.185644,-5.028872 0,-2.819933 -1.185644,-5.028878 -1.141732,-2.208945 -3.161717,-3.477914 -1.976074,-1.315967 -4.52301,-1.315967 -2.503024,0 -4.523015,1.315967 -2.019985,1.268969 -3.205629,3.477914 -1.185644,2.208945 -1.185644,5.028878 0,2.772929 1.185644,5.028872 1.185644,2.208944 3.205629,3.477913 2.019991,1.268969 4.523015,1.268969 z m 10.495142,3.05493 q -0.746517,0 -1.229556,-0.469982 -0.48305,-0.516998 -0.48305,-1.315967 v -8.036809 l 0.834341,-3.712905 2.590854,0.704985 V 61.32236 q 0,0.798981 -0.483049,1.315967 -0.48305,0.469982 -1.229562,0.469982 z"
       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.5833px;line-height:1.25;font-family:Comfortaa;-inkscape-font-specification:'Comfortaa, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect837);fill:#000000;fill-opacity:1;stroke:none;stroke-width:4.29257;fill-rule:evenodd"
       id="path886-5"
       inkscape:export-xdpi="132.53999"
       inkscape:export-ydpi="132.53999" />
  </g>
</svg>
tenuki commented 3 years ago

Several users have reported overlap issues in older versions of Safari (<10). Since we don't serve variable fonts to these ancient browsers, users are actually getting static fonts that have been instantiated from the variable font.

It my case I'm able to see wrongly rendered a (and others) in mozilla's firefox as well as on the webkit engine current version (!!).