Alexei Podtelezhnikov pushed to branch master at FreeType / FreeType
Commits:
-
ec46a50d
by Alexei Podtelezhnikov (Алексей Подтележников) at 2024-04-22T21:21:12-04:00
2 changed files:
Changes:
... | ... | @@ -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 | {
|
... | ... | @@ -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:
|