freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype][master] Improve SDF documentation.


From: Alexei Podtelezhnikov (@apodtele)
Subject: [Git][freetype/freetype][master] Improve SDF documentation.
Date: Tue, 23 Apr 2024 01:22:20 +0000

Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType

Commits:

  • ec46a50d
    by Alexei Podtelezhnikov (Алексей Подтележников) at 2024-04-22T21:21:12-04:00
    Improve SDF documentation.
    

2 changed files:

Changes:

  • include/freetype/freetype.h
    ... ... @@ -3771,87 +3771,18 @@ FT_BEGIN_HEADER
    3771 3771
        *     pixels and use the @FT_PIXEL_MODE_LCD_V mode.
    
    3772 3772
        *
    
    3773 3773
        *   FT_RENDER_MODE_SDF ::
    
    3774
    -   *     This mode corresponds to 8-bit, single-channel signed distance field
    
    3775
    -   *     (SDF) bitmaps.  Each pixel in the SDF grid is the value from the
    
    3776
    -   *     pixel's position to the nearest glyph's outline.  The distances are
    
    3777
    -   *     calculated from the center of the pixel and are positive if they are
    
    3778
    -   *     filled by the outline (i.e., inside the outline) and negative
    
    3779
    -   *     otherwise.  Check the note below on how to convert the output values
    
    3780
    -   *     to usable data.
    
    3774
    +   *     The positive (unsigned) 8-bit bitmap values can be converted to the
    
    3775
    +   *     single-channel signed distance field (SDF) by subtracting 128, with
    
    3776
    +   *     the positive and negative results corresponding to the inside and
    
    3777
    +   *     the outside of a glyph contour, respectively.  The distance units are
    
    3778
    +   *     arbitrarily determined by an adjustable @spread property.
    
    3781 3779
        *
    
    3782 3780
        * @note:
    
    3783
    -   *   The selected render mode only affects vector glyphs of a font.
    
    3781
    +   *   The selected render mode only affects scalable vector glyphs of a font.
    
    3784 3782
        *   Embedded bitmaps often have a different pixel mode like
    
    3785 3783
        *   @FT_PIXEL_MODE_MONO.  You can use @FT_Bitmap_Convert to transform them
    
    3786 3784
        *   into 8-bit pixmaps.
    
    3787 3785
        *
    
    3788
    -   *   For @FT_RENDER_MODE_SDF the output bitmap buffer contains normalized
    
    3789
    -   *   distances that are packed into unsigned 8-bit values.  To get pixel
    
    3790
    -   *   values in floating point representation use the following pseudo-C
    
    3791
    -   *   code for the conversion.
    
    3792
    -   *
    
    3793
    -   *   ```
    
    3794
    -   *   // Load glyph and render using FT_RENDER_MODE_SDF,
    
    3795
    -   *   // then use the output buffer as follows.
    
    3796
    -   *
    
    3797
    -   *   ...
    
    3798
    -   *   FT_Byte  buffer = glyph->bitmap->buffer;
    
    3799
    -   *
    
    3800
    -   *
    
    3801
    -   *   for pixel in buffer
    
    3802
    -   *   {
    
    3803
    -   *     // `sd` is the signed distance and `spread` is the current spread;
    
    3804
    -   *     // the default spread is 2 and can be changed.
    
    3805
    -   *
    
    3806
    -   *     float  sd = (float)pixel - 128.0f;
    
    3807
    -   *
    
    3808
    -   *
    
    3809
    -   *     // Convert to pixel values.
    
    3810
    -   *     sd = ( sd / 128.0f ) * spread;
    
    3811
    -   *
    
    3812
    -   *     // Store `sd` in a buffer or use as required.
    
    3813
    -   *   }
    
    3814
    -   *
    
    3815
    -   *   ```
    
    3816
    -   *
    
    3817
    -   *   FreeType has two rasterizers for generating SDF, namely:
    
    3818
    -   *
    
    3819
    -   *   1. `sdf` for generating SDF directly from glyph's outline, and
    
    3820
    -   *
    
    3821
    -   *   2. `bsdf` for generating SDF from rasterized bitmaps.
    
    3822
    -   *
    
    3823
    -   *   Depending on the glyph type (i.e., outline or bitmap), one of the two
    
    3824
    -   *   rasterizers is chosen at runtime and used for generating SDFs.  To
    
    3825
    -   *   force the use of `bsdf` you should render the glyph with any of the
    
    3826
    -   *   FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and
    
    3827
    -   *   then re-render with `FT_RENDER_MODE_SDF`.
    
    3828
    -   *
    
    3829
    -   *   There are some issues with stability and possible failures of the SDF
    
    3830
    -   *   renderers (specifically `sdf`).
    
    3831
    -   *
    
    3832
    -   *   1. The `sdf` rasterizer is sensitive to really small features (e.g.,
    
    3833
    -   *      sharp turns that are less than 1~pixel) and imperfections in the
    
    3834
    -   *      glyph's outline, causing artifacts in the final output.
    
    3835
    -   *
    
    3836
    -   *   2. The `sdf` rasterizer has limited support for handling intersecting
    
    3837
    -   *      contours and *cannot* handle self-intersecting contours whatsoever.
    
    3838
    -   *      Self-intersection happens when a single connected contour
    
    3839
    -   *      intersects itself at some point; having these in your font
    
    3840
    -   *      definitely poses a problem to the rasterizer and cause artifacts,
    
    3841
    -   *      too.
    
    3842
    -   *
    
    3843
    -   *   3. Generating SDF for really small glyphs may result in undesirable
    
    3844
    -   *      output; the pixel grid (which stores distance information) becomes
    
    3845
    -   *      too coarse.
    
    3846
    -   *
    
    3847
    -   *   4. Since the output buffer is normalized, precision at smaller spreads
    
    3848
    -   *      is greater than precision at larger spread values because the
    
    3849
    -   *      output range of [0..255] gets mapped to a smaller SDF range.  A
    
    3850
    -   *      spread of~2 should be sufficient in most cases.
    
    3851
    -   *
    
    3852
    -   *   Points (1) and (2) can be avoided by using the `bsdf` rasterizer,
    
    3853
    -   *   which is more stable than the `sdf` rasterizer in general.
    
    3854
    -   *
    
    3855 3786
        */
    
    3856 3787
       typedef enum  FT_Render_Mode_
    
    3857 3788
       {
    

  • include/freetype/ftdriver.h
    ... ... @@ -817,6 +817,79 @@ FT_BEGIN_HEADER
    817 817
        *   2.5
    
    818 818
        */
    
    819 819
     
    
    820
    +
    
    821
    +  /**************************************************************************
    
    822
    +   *
    
    823
    +   * @property:
    
    824
    +   *   spread
    
    825
    +   *
    
    826
    +   * @description:
    
    827
    +   *   This property of the 'sdf' and 'bsdf' renderers defines how the signed
    
    828
    +   *   distance field (SDF) is represented in the output bitmap.  The output
    
    829
    +   *   values are calculated as follows, '128 * ( SDF / spread + 1 )', with
    
    830
    +   *   the result truncated to the 8-bit range [0..255].  Therefore, 'spread'
    
    831
    +   *   is also the maximum euclidean distance from the edge after which the
    
    832
    +   *   values are truncated.  The spread is specified in pixels with the
    
    833
    +   *   default value of 8.
    
    834
    +   *
    
    835
    +   * @example:
    
    836
    +   *   The following example code demonstrates how to set the SDF spread
    
    837
    +   *   (omitting the error handling).
    
    838
    +   *
    
    839
    +   *   ```
    
    840
    +   *     FT_Library  library;
    
    841
    +   *     FT_UInt     spread = 2;
    
    842
    +   *
    
    843
    +   *
    
    844
    +   *     FT_Init_FreeType( &library );
    
    845
    +   *
    
    846
    +   *     FT_Property_Set( library, "sdf", "spread", &spread );
    
    847
    +   *   ```
    
    848
    +   *
    
    849
    +   * @note
    
    850
    +   *   FreeType has two rasterizers for generating SDF, namely:
    
    851
    +   *
    
    852
    +   *   1. `sdf` for generating SDF directly from glyph's outline, and
    
    853
    +   *
    
    854
    +   *   2. `bsdf` for generating SDF from rasterized bitmaps.
    
    855
    +   *
    
    856
    +   *   Depending on the glyph type (i.e., outline or bitmap), one of the two
    
    857
    +   *   rasterizers is chosen at runtime and used for generating SDFs.  To
    
    858
    +   *   force the use of `bsdf` you should render the glyph with any of the
    
    859
    +   *   FreeType's other rendering modes (e.g., `FT_RENDER_MODE_NORMAL`) and
    
    860
    +   *   then re-render with `FT_RENDER_MODE_SDF`.
    
    861
    +   *
    
    862
    +   *   There are some issues with stability and possible failures of the SDF
    
    863
    +   *   renderers (specifically `sdf`).
    
    864
    +   *
    
    865
    +   *   1. The `sdf` rasterizer is sensitive to really small features (e.g.,
    
    866
    +   *      sharp turns that are less than 1~pixel) and imperfections in the
    
    867
    +   *      glyph's outline, causing artifacts in the final output.
    
    868
    +   *
    
    869
    +   *   2. The `sdf` rasterizer has limited support for handling intersecting
    
    870
    +   *      contours and *cannot* handle self-intersecting contours whatsoever.
    
    871
    +   *      Self-intersection happens when a single connected contour
    
    872
    +   *      intersects itself at some point; having these in your font
    
    873
    +   *      definitely poses a problem to the rasterizer and cause artifacts,
    
    874
    +   *      too.
    
    875
    +   *
    
    876
    +   *   3. Generating SDF for really small glyphs may result in undesirable
    
    877
    +   *      output; the pixel grid (which stores distance information) becomes
    
    878
    +   *      too coarse.
    
    879
    +   *
    
    880
    +   *   4. Since the output buffer is normalized, precision at smaller spreads
    
    881
    +   *      is greater than precision at larger spread values because the
    
    882
    +   *      output range of [0..255] gets mapped to a smaller SDF range.  A
    
    883
    +   *      spread of~2 should be sufficient in most cases.
    
    884
    +   *
    
    885
    +   *   Points (1) and (2) can be avoided by using the `bsdf` rasterizer,
    
    886
    +   *   which is more stable than the `sdf` rasterizer in general.
    
    887
    +   *
    
    888
    +   * @since:
    
    889
    +   *   2.11
    
    890
    +   */
    
    891
    +
    
    892
    +
    
    820 893
       /**************************************************************************
    
    821 894
        *
    
    822 895
        * @property:
    


  • reply via email to

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