Browse Source

FreeType: Added RasterizerFlags::Monochrome flag to disable font anti-aliasing. (#2545) Combine with RasterizerFlags::MonoHinting for best results.

HolyBlackCat 6 years ago
parent
commit
87c5356d97
4 changed files with 48 additions and 11 deletions
  1. 2 0
      docs/CHANGELOG.txt
  2. 1 0
      misc/freetype/README.md
  3. 43 10
      misc/freetype/imgui_freetype.cpp
  4. 2 1
      misc/freetype/imgui_freetype.h

+ 2 - 0
docs/CHANGELOG.txt

@@ -41,6 +41,8 @@ Other Changes:
 - Separator: Revert 1.70 "Declare its thickness (1.0f) to the layout" change. It's not incorrect
   but it breaks existing some layout patterns. Will return back to it when we expose Separator flags.
 - Scrollbar: Very minor bounding box adjustment to cope with various border size.
+- ImFontAtlas: FreeType: Added RasterizerFlags::Monochrome flag to disable font anti-aliasing. (#2545)
+  Combine with RasterizerFlags::MonoHinting for best results.
 - Examples/Backends: Don't filter characters under 0x10000 before calling io.AddInputCharacter(),
   the filtering is done in io.AddInputCharacter() itself. This is in prevision for fuller Unicode
   support. (#2538, #2541)

+ 1 - 0
misc/freetype/README.md

@@ -120,6 +120,7 @@ struct FreeTypeTest
             WantRebuild |= ImGui::CheckboxFlags("MonoHinting",   &FontsFlags, ImGuiFreeType::MonoHinting);
             WantRebuild |= ImGui::CheckboxFlags("Bold",          &FontsFlags, ImGuiFreeType::Bold);
             WantRebuild |= ImGui::CheckboxFlags("Oblique",       &FontsFlags, ImGuiFreeType::Oblique);
+            WantRebuild |= ImGui::CheckboxFlags("Monochrome",    &FontsFlags, ImGuiFreeType::Monochrome);
         }
         ImGui::End();
     }

+ 43 - 10
misc/freetype/imgui_freetype.cpp

@@ -12,6 +12,7 @@
 // - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
 // - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
 // - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
+// - v0.62: (2019/02/09) added RasterizerFlags::Monochrome flag to disable font anti-aliasing (combine with ::MonoHinting for best results!)
 
 // Gamma Correct Blending:
 //  FreeType assumes blending in linear space rather than gamma space.
@@ -109,6 +110,7 @@ namespace
         FT_Face         Face;
         unsigned int    UserFlags;          // = ImFontConfig::RasterizerFlags
         FT_Int32        LoadFlags;
+        FT_Render_Mode  RenderMode;
     };
 
     // From SDL_ttf: Handy routines for converting from fixed point
@@ -142,6 +144,11 @@ namespace
         else
             LoadFlags |= FT_LOAD_TARGET_NORMAL;
 
+        if (UserFlags & ImGuiFreeType::Monochrome)
+            RenderMode = FT_RENDER_MODE_MONO;
+        else
+            RenderMode = FT_RENDER_MODE_NORMAL;
+
         return true;
     }
 
@@ -208,7 +215,7 @@ namespace
     const FT_Bitmap* FreeTypeFont::RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info)
     {
         FT_GlyphSlot slot = Face->glyph;
-        FT_Error error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
+        FT_Error error = FT_Render_Glyph(slot, RenderMode);
         if (error != 0)
             return NULL;
 
@@ -230,16 +237,42 @@ namespace
         const uint8_t* src = ft_bitmap->buffer;
         const uint32_t src_pitch = ft_bitmap->pitch;
 
-        if (multiply_table == NULL)
-        {
-            for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
-                memcpy(dst, src, w);
-        }
-        else
+        switch (ft_bitmap->pixel_mode)
         {
-            for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
-                for (uint32_t x = 0; x < w; x++)
-                    dst[x] = multiply_table[src[x]];
+        case FT_PIXEL_MODE_GRAY: // Grayscale image, 1 byte per pixel.
+            {
+                if (multiply_table == NULL)
+                {
+                    for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
+                        memcpy(dst, src, w);
+                }
+                else
+                {
+                    for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
+                        for (uint32_t x = 0; x < w; x++)
+                            dst[x] = multiply_table[src[x]];
+                }
+                break;
+            }
+        case FT_PIXEL_MODE_MONO: // Monochrome image, 1 bit per pixel. The bits in each byte are ordered from MSB to LSB.
+            {
+                uint8_t color0 = multiply_table ? multiply_table[0] : 0;
+                uint8_t color1 = multiply_table ? multiply_table[255] : 255;
+                for (uint32_t y = 0; y < h; y++, src += src_pitch, dst += dst_pitch)
+                {
+                    uint8_t bits = 0;
+                    const uint8_t* bits_ptr = src;
+                    for (uint32_t x = 0; x < w; x++, bits <<= 1)
+                    {
+                        if ((x & 7) == 0)
+                            bits = *bits_ptr++;
+                        dst[x] = (bits & 0x80) ? color1 : color0;
+                    }
+                }
+                break;
+            }
+        default:
+            IM_ASSERT(0 && "FreeTypeFont::BlitGlyph(): Unknown bitmap pixel mode!");
         }
     }
 }

+ 2 - 1
misc/freetype/imgui_freetype.h

@@ -24,7 +24,8 @@ namespace ImGuiFreeType
         LightHinting    = 1 << 3,   // A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.
         MonoHinting     = 1 << 4,   // Strong hinting algorithm that should only be used for monochrome output.
         Bold            = 1 << 5,   // Styling: Should we artificially embolden the font?
-        Oblique         = 1 << 6    // Styling: Should we slant the font, emulating italic style?
+        Oblique         = 1 << 6,   // Styling: Should we slant the font, emulating italic style?
+        Monochrome      = 1 << 7    // Disable anti-aliasing. Combine this with MonoHinting for best results!
     };
 
     IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);