findfont not matching close weights

Greetings. It seems that a "not" operator got dropped in rev. 6143 to
font_manager.py. I've attached a patch.

The missing "not" tripped up findfont when trying to match font weights: the
code

    fm = matplotlib.font_manager.FontManager()
    fm.findfont('New Century Schoolbook', fontext='afm')

was yielding '...\\matplotlib\\mpl-data\\fonts\\ttf\\Vera.ttf' instead of
the expected '...\\matplotlib\\mpl-data\\fonts\\afm\\pncr8a.afm', because
fm.afmdict['New Century Schoolbook']['normal']['normal'] had only the
weights 500 and 700, not the 400 called for by the implicit normal weight in
the findfont call.

findfont.patch (491 Bytes)

This is a longstanding known issue -- the font finding algorithm is way too precise, and should instead do a nearest-neighbor search similar to fontconfig. It's a non-trivial bit of code that no one has yet found time for.

If you're running matplotlib 0.98.x and are on a non-Windows platform, you can try the experimental fontconfig support by changing the "USE_FONTCONFIG" variable to "True" in font_manager.py. (You'll need to install fontconfig on OS-X -- most recent Linux distributions should already have it.)

Cheers,
Mike

Stan West wrote:

···

Greetings. It seems that a "not" operator got dropped in rev. 6143 to
font_manager.py. I've attached a patch.

The missing "not" tripped up findfont when trying to match font weights: the
code

    fm = matplotlib.font_manager.FontManager()
    fm.findfont('New Century Schoolbook', fontext='afm')

was yielding '...\\matplotlib\\mpl-data\\fonts\\ttf\\Vera.ttf' instead of
the expected '...\\matplotlib\\mpl-data\\fonts\\afm\\pncr8a.afm', because
fm.afmdict['New Century Schoolbook']['normal']['normal'] had only the
weights 500 and 700, not the 400 called for by the implicit normal weight in
the findfont call.
  ------------------------------------------------------------------------

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
------------------------------------------------------------------------

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options
  
--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Thank you, Mike, for your reply. My understanding of the intent of the code
is that if the weight is not found in the font dict, setWeights is called to
supplement the dict with the missing weights, and the weight is sought again
in the supplemented dict. That would seem to effect the desired approximate
matching, albeit by precisely matching to an enlarged font dict. However,
Rev. 6143 replaced

    if not font.has_key(weight):
        setWeights(font)

with

    if weight in font:
        setWeights(font)

dropping the "not" and thereby supplementing the dict when the sought weight
is already present. Restoring the "not" would restore the approximate
matching, no?

Thanks also for the fontconfig suggestion; I would be happy to try it,
except that my platform is Windows.

Stan

···

-----Original Message-----
From: Michael Droettboom [mailto:mdroe@…31…]
Sent: Wednesday, October 22, 2008 10:11
To: Stan West
Cc: matplotlib-devel@lists.sourceforge.net
Subject: Re: [matplotlib-devel] findfont not matching close weights

This is a longstanding known issue -- the font finding
algorithm is way too precise, and should instead do a
nearest-neighbor search similar to fontconfig. It's a
non-trivial bit of code that no one has yet found time for.

If you're running matplotlib 0.98.x and are on a non-Windows
platform, you can try the experimental fontconfig support by
changing the "USE_FONTCONFIG" variable to "True" in
font_manager.py. (You'll need to install fontconfig on OS-X
-- most recent Linux distributions should already have it.)

Cheers,
Mike

Stan West wrote:
> Greetings. It seems that a "not" operator got dropped in
rev. 6143 to
> font_manager.py. I've attached a patch.
>
> The missing "not" tripped up findfont when trying to match font
> weights: the code
>
> fm = matplotlib.font_manager.FontManager()
> fm.findfont('New Century Schoolbook', fontext='afm')
>
> was yielding
'...\\matplotlib\\mpl-data\\fonts\\ttf\\Vera.ttf' instead
> of the expected
'...\\matplotlib\\mpl-data\\fonts\\afm\\pncr8a.afm',
> because fm.afmdict['New Century
Schoolbook']['normal']['normal'] had
> only the weights 500 and 700, not the 400 called for by the
implicit
> normal weight in the findfont call.
>
>
----------------------------------------------------------------------
> --
>
>
----------------------------------------------------------------------
> --- This SF.Net email is sponsored by the Moblin Your Move
Developer's
> challenge Build the coolest Linux based applications with
Moblin SDK &
> win great prizes Grand prize is a trip for two to an Open
Source event
> anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
>
----------------------------------------------------------------------
> --
>
> _______________________________________________
> Matplotlib-devel mailing list
> Matplotlib-devel@lists.sourceforge.net
> matplotlib-devel List Signup and Options
>

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA

Stan West wrote:

Thank you, Mike, for your reply. My understanding of the intent of the code
is that if the weight is not found in the font dict, setWeights is called to
supplement the dict with the missing weights, and the weight is sought again
in the supplemented dict. That would seem to effect the desired approximate
matching, albeit by precisely matching to an enlarged font dict. However,
Rev. 6143 replaced

    if not font.has_key(weight):
        setWeights(font)

with

    if weight in font:
        setWeights(font)

dropping the "not" and thereby supplementing the dict when the sought weight
is already present. Restoring the "not" would restore the approximate
matching, no?
  

You're right That looks like a typo. This is now fixed in SVN r6294.

Thanks also for the fontconfig suggestion; I would be happy to try it,
except that my platform is Windows.
  

That's, unfortunately, why we can't just switch to using it. fontconfig solves this problem in a much more robust way, and more importantly is maintained by others who know the pitfalls of fonts really well. It is ported to Windows, but it is generally not there, so we would have to require or ship it.

Cheers,
Mike

···

Stan

-----Original Message-----
From: Michael Droettboom [mailto:mdroe@…31…] Sent: Wednesday, October 22, 2008 10:11
To: Stan West
Cc: matplotlib-devel@lists.sourceforge.net
Subject: Re: [matplotlib-devel] findfont not matching close weights

This is a longstanding known issue -- the font finding algorithm is way too precise, and should instead do a nearest-neighbor search similar to fontconfig. It's a non-trivial bit of code that no one has yet found time for.

If you're running matplotlib 0.98.x and are on a non-Windows platform, you can try the experimental fontconfig support by changing the "USE_FONTCONFIG" variable to "True" in font_manager.py. (You'll need to install fontconfig on OS-X -- most recent Linux distributions should already have it.)

Cheers,
Mike

Stan West wrote:
    

Greetings. It seems that a "not" operator got dropped in
      

rev. 6143 to
    

font_manager.py. I've attached a patch.

The missing "not" tripped up findfont when trying to match font weights: the code

    fm = matplotlib.font_manager.FontManager()
    fm.findfont('New Century Schoolbook', fontext='afm')

was yielding
      

'...\\matplotlib\\mpl-data\\fonts\\ttf\\Vera.ttf' instead
    

of the expected
      

'...\\matplotlib\\mpl-data\\fonts\\afm\\pncr8a.afm',
    

because fm.afmdict['New Century
      

Schoolbook']['normal']['normal'] had
    

only the weights 500 and 700, not the 400 called for by the
      

implicit
    

normal weight in the findfont call.
  

----------------------------------------------------------------------
    

--

----------------------------------------------------------------------
    

--- This SF.Net email is sponsored by the Moblin Your Move
      

Developer's
    

challenge Build the coolest Linux based applications with
      

Moblin SDK &
    

win great prizes Grand prize is a trip for two to an Open
      

Source event
    

anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/

----------------------------------------------------------------------
    

--

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
matplotlib-devel List Signup and Options
  

--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA
    
--
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA