freetype-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [ft-devel] [Patch] Autofit and stem snapping


From: Turner, David
Subject: RE: [ft-devel] [Patch] Autofit and stem snapping
Date: Tue, 20 Sep 2005 14:55:24 +0200

Salut Frédéric,

I've reviewed Owen's patch, which led me to peek inside the
sources of libXft and Cairo to understand the difference. I
now believe that the problem is in Cairo and that the patch
is incorrect.

I believe that this comes from a misunderstanding of the
FreeType API from the Cairo developers. I'll try to explain it
myself:

  the FreeType API defines several FT_LOAD_TARGET_XXX constants
  that determine which hinting algorithm to use when loading
  outlines from a font file:

    FT_LOAD_TARGET_NORMAL  => hint for normal anti-aliased rendering
    FT_LOAD_TARGET_LIGHT   => same as above, but hint less !
    FT_LOAD_TARGET_MONO    => hint for monochrome rendering
    FT_LOAD_TARGET_LCD     => hint for horizontal LCD rendering
    FT_LOAD_TARGET_LCD_V   => hint for vertical LCD rendering

  Notice that:

    - you should only use *one* of these values in your load flags;
      you cannot OR them, because they're not simple bit flags !

    - this means you cannot combine them, i.e. there is no
      "light lcd" mode. Light hinting is intended for normal
      anti-aliased rendering only.

  However, FreeType makes a distinction between the hinting algorithm
  being used, and the pixel mode of the target bitmaps. For example,
  it is possible to use the "light" hinting algorithm and have the
  results rendered in horizontal LCD pixel mode, with something like:

     FT_Load_Glyph( face, glyph_index, load_flags | FT_LOAD_TARGET_LIGHT );
     FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD );

  both libXft and Cairo load outlines and render them to bitmaps themselves
  (i.e. they basically re-implement FT_Render_Glyph, with the addition
   of color filtering for RGB modes. The reasons why they do it this way
   escape me at the moment).

  However, they certainly do not select the hinting algorithm the same
  way. If we take a look at xftfreetype.c in libXft-2.1.7, we see this
  (very simplified) code:

-------------------------------------------------------
    if ( antialias )
    {
      if ( NONE < hinting && hinting < FULL )
      {
        load_flags |= FT_LOAD_TARGET_LIGHT;
      }
      else switch ( rgba_mode )
      {
        case RGBA_RGB: case RGBA_BGR:
           load_flags |= FT_LOAD_TARGET_LCD;
           break;

        case RGBA_VRGB: case RGBA_VBGR
           load_flags |= FT_LOAD_TARGET_LCD_V;
           break;
      }
    }
    else
      load_flags |= FT_LOAD_TARGET_MONO;
--------------------------------------------------------

  which is correct, because it only selects one FT_LOAD_TARGET_XXX
  value depending on settings. (FT_LOAD_TARGET_NORMAL is always 0)


  Now, the corresponding code in Cairo is _very_ different. There
  are actually two distinct ways to compute load flags. They're
  located in cairo-ft-font.c. In "_get_pattern_load_flags":

--------------------------------------------------------
   if ( antialias )
   {
     switch ( hintstyle )
     {
       case SLIGHT: case MEDIUM:
         target_flags = FT_LOAD_TARGET_LIGHT;
         break;
       default:
         target_flags = FT_LOAD_TARGET_NORMAL;
     }
   }
   else
     target_flags = FT_LOAD_TARGET_MONO;

   switch ( rgba_mode )
   {
     case RGB: case BGR:
       target_flags = FT_LOAD_TARGET_LCD;
       break;

     case VRGB: case VBGR:
       target_flags = FT_LOAD_TARGET_LCD_V;
       break;
   }

   load_flags |= target_flags;
--------------------------------------------------------


  And in "_get_options_load_flags":

----------------------------------------------------
     switch ( options->antialias )
     {
       case NONE:
          load_flags |= FT_LOAD_TARGET_MONO;
          break;

       case RGB: case BGR:
          load_flags |= FT_LOAD_TARGET_LCD;
          break;

       case VRGB: case VBGR:
          load_flags |= FT_LOAD_TARGET_LCD_V;
          break;

       case DEFAULT:
          load_flags |= FT_LOAD_NO_BITMAP;
     }

     switch ( options->hinting )
     {
       case NONE:
          load_flags |= FT_LOAD_NO_HINTING;
          break;

       case SLIGHT: case MEDIUM:
          load_flags |= FT_LOAD_TARGET_LIGHT;
          break;

       case FULL:
          load_flags |= FT_LOAD_TARGET_NORMAL;
     }
----------------------------------------------------

  There are several problems here:

   - first, the two functions don't agree on a common
     way to compute the hinting algorithm !

   - in "_get_pattern_options", setting a RGB decimated
     mode disables light hinting.

   - in "_get_options_load_flags", setting the hinting
     mode the SLIGHT or MEDIUM overwrites the value
     previously computed, instead of replacing it.
     

  The fix is to modify these functions to duplicate
  libXft's behaviour. 

  There is no "magic spell" in libXft, and I wonder
  why Owen's patch works at all.

  Please forward this to the Cairo mailing list.


Hope this helps,

- David Turner
- The FreeType Project  (www.freetype.org)





  using one of this values changes the way outlines are distorted
  when they're loaded. Notice that they match their FT_RENDER_MODE_XXX
  values intentionally.

  Notice also that you should only use *one* of these values in your
  load flags; you cannot OR them, because they're not simple bit flags.




> -----Message d'origine-----
> De : address@hidden
> [mailto:address@hidden 
> la part de
> Frederic Crozat
> Envoyé : mardi 20 septembre 2005 10:41
> À : address@hidden
> Objet : Re: [ft-devel] [Patch] Autofit and stem snapping
> 
> 
> Le mercredi 31 août 2005 à 13:58 +0200, Frederic Crozat a écrit :
> > Le mardi 30 août 2005 à 15:14 -0400, Owen Taylor a écrit :
> > > It was  reported with cairo that snapping of stems to 
> integer widths 
> > > for LCD rendering was no longer working:
> > > 
> > >  https://bugs.freedesktop.org/show_bug.cgi?id=4302
> > > 
> > > Upon investigation this turned out to be a 2.1.9 / 2.1.10 change
> > > in FreeType.
> > > 
> > > It looks like the problem is in  
> af_latin_compute_stem_width(). As I
> > > read it variable vertical was supposed to be whether the 
> stem being
> > > hinted is vertical, but was instead set to whether 
> vertical hinting 
> > > was enabled for the font.
> > > 
> > > Here's a patch that works for me.
> > 
> > This patch seems to trigger a misrendering of "ö" character with
> > Bitstream Vera Sans 10 => only one dot is rendered, instead of two..
> 
> Any hope of getting Owen patch reviewed ?
> 
> -- 
> Frederic Crozat <address@hidden>
> Mandriva
> 
> 
> 
> _______________________________________________
> Freetype-devel mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/freetype-devel
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]