Decouple anti-alias setting from FT_Render_Mode This CL decouples the anti-alias setting from the previous freetype callers. This is done by introducing a new enum, AARenderMode, and a function GetFTRenderMode(), which is used to abstract the antialiasing setting. This change is part of the ongoing effort to encapsulate FreeType usage, which makes future adjustments to anti-aliasing logic easier and cleaner. Change-Id: I6ef3d17ca6af94972e48691311df088f5cb6f64d Bug: 452087737 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/138530 Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index c3103d5..1242da1 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -1089,7 +1089,7 @@ return true; } - FX_RECT rect = GetGlyphsBBox(glyphs, 0); + FX_RECT rect = GetGlyphsBBox(glyphs, FontAntiAliasingMode::kNormal); auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>(); if (!bitmap->Create(rect.Width(), rect.Height(), FXDIB_Format::k8bppMask)) { return true;
diff --git a/core/fxge/apple/fx_apple_impl.cpp b/core/fxge/apple/fx_apple_impl.cpp index ef176e3..0cb5226 100644 --- a/core/fxge/apple/fx_apple_impl.cpp +++ b/core/fxge/apple/fx_apple_impl.cpp
@@ -22,6 +22,7 @@ #include "core/fxge/cfx_renderdevice.h" #include "core/fxge/cfx_substfont.h" #include "core/fxge/dib/cfx_dibitmap.h" +#include "core/fxge/fx_font.h" #include "core/fxge/text_char_pos.h" namespace { @@ -181,7 +182,7 @@ uint32_t glyph_index, const CFX_Matrix& matrix, int dest_width, - int anti_alias) { + FontAntiAliasingMode anti_alias) { return nullptr; }
diff --git a/core/fxge/cfx_face.cpp b/core/fxge/cfx_face.cpp index 3fe1029..42e87e5 100644 --- a/core/fxge/cfx_face.cpp +++ b/core/fxge/cfx_face.cpp
@@ -530,12 +530,13 @@ return pdfium::checked_cast<int>(GetRec()->num_glyphs); } -std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph(const CFX_Font* font, - uint32_t glyph_index, - bool bFontStyle, - const CFX_Matrix& matrix, - int dest_width, - int anti_alias) { +std::unique_ptr<CFX_GlyphBitmap> CFX_Face::RenderGlyph( + const CFX_Font* font, + uint32_t glyph_index, + bool bFontStyle, + const CFX_Matrix& matrix, + int dest_width, + FontAntiAliasingMode anti_alias) { FT_Matrix ft_matrix; ft_matrix.xx = matrix.a / 64 * 65536; ft_matrix.xy = matrix.c / 64 * 65536; @@ -621,7 +622,7 @@ int dib_width = bitmap.width; auto pGlyphBitmap = std::make_unique<CFX_GlyphBitmap>(glyph->bitmap_left, glyph->bitmap_top); - const FXDIB_Format format = anti_alias == FT_RENDER_MODE_MONO + const FXDIB_Format format = anti_alias == FontAntiAliasingMode::kMono ? FXDIB_Format::k1bppMask : FXDIB_Format::k8bppMask; if (!pGlyphBitmap->GetBitmap()->Create(dib_width, bitmap.rows, format)) { @@ -632,9 +633,9 @@ uint8_t* pDestBuf = pGlyphBitmap->GetBitmap()->GetWritableBuffer().data(); const uint8_t* pSrcBuf = bitmap.buffer; UNSAFE_TODO({ - if (anti_alias != FT_RENDER_MODE_MONO && + if (anti_alias != FontAntiAliasingMode::kMono && bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - unsigned int bytes = anti_alias == FT_RENDER_MODE_LCD ? 3 : 1; + unsigned int bytes = anti_alias == FontAntiAliasingMode::kLcd ? 3 : 1; for (unsigned int i = 0; i < bitmap.rows; i++) { for (unsigned int n = 0; n < bitmap.width; n++) { uint8_t data =
diff --git a/core/fxge/cfx_face.h b/core/fxge/cfx_face.h index 0753aff..048cf14 100644 --- a/core/fxge/cfx_face.h +++ b/core/fxge/cfx_face.h
@@ -20,6 +20,7 @@ #include "core/fxcrt/retain_ptr.h" #include "core/fxcrt/span.h" #include "core/fxge/freetype/fx_freetype.h" +#include "core/fxge/fx_font.h" namespace fxge { enum class FontEncoding : uint32_t; @@ -115,7 +116,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias); + FontAntiAliasingMode anti_alias); std::unique_ptr<CFX_Path> LoadGlyphPath(uint32_t glyph_index, int dest_width, bool is_vertical,
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp index 915e2e1..f760ec4 100644 --- a/core/fxge/cfx_font.cpp +++ b/core/fxge/cfx_font.cpp
@@ -386,7 +386,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, CFX_TextRenderOptions* text_options) const { return GetOrCreateGlyphCache()->LoadGlyphBitmap(this, glyph_index, bFontStyle, matrix, dest_width,
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h index ff4bee1..919ee7c 100644 --- a/core/fxge/cfx_font.h +++ b/core/fxge/cfx_font.h
@@ -22,10 +22,7 @@ #include "core/fxcrt/span.h" #include "core/fxcrt/unowned_ptr_exclusion.h" #include "core/fxge/cfx_face.h" - -#if defined(PDF_USE_SKIA) #include "core/fxge/fx_font.h" -#endif class CFX_GlyphBitmap; class CFX_GlyphCache; @@ -91,7 +88,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, CFX_TextRenderOptions* text_options) const; const CFX_Path* LoadGlyphPath(uint32_t glyph_index, int dest_width) const; int GetGlyphWidth(uint32_t glyph_index) const;
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp index 7954089..0dafc22 100644 --- a/core/fxge/cfx_glyphcache.cpp +++ b/core/fxge/cfx_glyphcache.cpp
@@ -19,6 +19,7 @@ #include "core/fxge/cfx_glyphbitmap.h" #include "core/fxge/cfx_path.h" #include "core/fxge/cfx_substfont.h" +#include "core/fxge/fx_font.h" #if defined(PDF_USE_SKIA) #include "third_party/skia/include/core/SkFontMgr.h" // nogncheck @@ -47,7 +48,7 @@ UniqueKeyGen(const CFX_Font* font, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, bool bNative); pdfium::span<const uint8_t> span() const; @@ -75,7 +76,7 @@ UniqueKeyGen::UniqueKeyGen(const CFX_Font* font, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, bool bNative) { int nMatrixA = static_cast<int>(matrix.a * 10000); int nMatrixB = static_cast<int>(matrix.b * 10000); @@ -86,11 +87,11 @@ if (bNative) { if (font->GetSubstFont()) { Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, - anti_alias, font->GetSubstFont()->weight_, + static_cast<int>(anti_alias), font->GetSubstFont()->weight_, font->GetSubstFont()->italic_angle_, font->IsVertical(), 3}); } else { - Initialize( - {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias, 3}); + Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, + static_cast<int>(anti_alias), 3}); } return; } @@ -98,12 +99,12 @@ CHECK(!bNative); if (font->GetSubstFont()) { - Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias, - font->GetSubstFont()->weight_, + Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, + static_cast<int>(anti_alias), font->GetSubstFont()->weight_, font->GetSubstFont()->italic_angle_, font->IsVertical()}); } else { - Initialize( - {nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, anti_alias}); + Initialize({nMatrixA, nMatrixB, nMatrixC, nMatrixD, dest_width, + static_cast<int>(anti_alias)}); } } @@ -120,7 +121,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias) { + FontAntiAliasingMode anti_alias) { if (!face_) { return nullptr; } @@ -157,7 +158,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, CFX_TextRenderOptions* text_options) { if (glyph_index == kInvalidGlyphIndex) { return nullptr; @@ -306,7 +307,7 @@ uint32_t glyph_index, bool bFontStyle, int dest_width, - int anti_alias) { + FontAntiAliasingMode anti_alias) { SizeGlyphCache* pSizeCache; auto it = size_map_.find(FaceGlyphsKey); if (it == size_map_.end()) {
diff --git a/core/fxge/cfx_glyphcache.h b/core/fxge/cfx_glyphcache.h index 03c971f..d319379 100644 --- a/core/fxge/cfx_glyphcache.h +++ b/core/fxge/cfx_glyphcache.h
@@ -15,9 +15,9 @@ #include "core/fxcrt/observed_ptr.h" #include "core/fxcrt/retain_ptr.h" #include "core/fxge/cfx_face.h" +#include "core/fxge/fx_font.h" #if defined(PDF_USE_SKIA) -#include "core/fxge/fx_font.h" #include "third_party/skia/include/core/SkRefCnt.h" // nogncheck #endif @@ -36,7 +36,7 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias, + FontAntiAliasingMode anti_alias, CFX_TextRenderOptions* text_options); const CFX_Path* LoadGlyphPath(const CFX_Font* font, uint32_t glyph_index, @@ -69,20 +69,20 @@ bool bFontStyle, const CFX_Matrix& matrix, int dest_width, - int anti_alias); + FontAntiAliasingMode anti_alias); std::unique_ptr<CFX_GlyphBitmap> RenderGlyph_Nativetext( const CFX_Font* font, uint32_t glyph_index, const CFX_Matrix& matrix, int dest_width, - int anti_alias); + FontAntiAliasingMode anti_alias); CFX_GlyphBitmap* LookUpGlyphBitmap(const CFX_Font* font, const CFX_Matrix& matrix, const ByteString& FaceGlyphsKey, uint32_t glyph_index, bool bFontStyle, int dest_width, - int anti_alias); + FontAntiAliasingMode anti_alias); RetainPtr<CFX_Face> const face_; std::map<ByteString, SizeGlyphCache> size_map_; std::map<PathMapKey, std::unique_ptr<CFX_Path>> path_map_;
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp index d39c95d..7c530ba 100644 --- a/core/fxge/cfx_renderdevice.cpp +++ b/core/fxge/cfx_renderdevice.cpp
@@ -505,6 +505,12 @@ return CFX_DIBBase::kPlatformRGBFormat; } +bool IsModeNonLCD(FontAntiAliasingMode mode) { + return mode == FontAntiAliasingMode::kNormal || + mode == FontAntiAliasingMode::kLight || + mode == FontAntiAliasingMode::kMono; +} + } // namespace CFX_RenderDevice::CFX_RenderDevice() = default; @@ -1086,7 +1092,7 @@ uint32_t fill_color, const CFX_TextRenderOptions& options) { // `anti_alias` and `normalize` don't affect Skia rendering. - int anti_alias = FT_RENDER_MODE_MONO; + FontAntiAliasingMode anti_alias = FontAntiAliasingMode::kMono; bool normalize = false; const bool is_text_smooth = options.IsSmooth(); // |text_options| has the potential to affect all derived classes of @@ -1100,7 +1106,7 @@ // 6225973, 6243070, 6393145, 6421054, 6282327, and 6624828; the latest // one expires 10/7/19. This makes LCD anti-aliasing very ugly, so we // instead fall back on NORMAL anti-aliasing. - anti_alias = FT_RENDER_MODE_NORMAL; + anti_alias = FontAntiAliasingMode::kNormal; if (CFX_DefaultRenderDevice::UseSkiaRenderer()) { // Since |anti_alias| doesn't affect Skia rendering, and Skia only // follows strictly to the options provided by |text_options|, we need @@ -1112,16 +1118,16 @@ // Whether Skia uses LCD optimization should strictly follow the // rendering options provided by |text_options|. No change needs to be // done for |text_options| here. - anti_alias = FT_RENDER_MODE_LCD; + anti_alias = FontAntiAliasingMode::kLcd; normalize = true; } else if (bpp_ < 16) { // This case doesn't apply to Skia since Skia always have |bpp_| = 32. - anti_alias = FT_RENDER_MODE_NORMAL; + anti_alias = FontAntiAliasingMode::kNormal; } else { // Whether Skia uses LCD optimization should strictly follow the // rendering options provided by |text_options|. No change needs to be // done for |text_options| here. - anti_alias = FT_RENDER_MODE_LCD; + anti_alias = FontAntiAliasingMode::kLcd; normalize = !font->HasFaceRec() || options.aliasing_type != CFX_TextRenderOptions::kLcd; } @@ -1173,7 +1179,7 @@ std::vector<TextGlyphPos> glyphs(pCharPos.size()); for (auto [charpos, glyph] : fxcrt::Zip(pCharPos, pdfium::span(glyphs))) { glyph.device_origin_ = text2Device.Transform(charpos.origin_); - glyph.origin_.x = anti_alias < FT_RENDER_MODE_LCD + glyph.origin_.x = IsModeNonLCD(anti_alias) ? FXSYS_roundf(glyph.device_origin_.x) : static_cast<int>(floor(glyph.device_origin_.x)); glyph.origin_.y = FXSYS_roundf(glyph.device_origin_.y); @@ -1183,7 +1189,7 @@ charpos.glyph_index_, charpos.font_style_, matrix, charpos.font_char_width_, anti_alias, &text_options); } - if (anti_alias < FT_RENDER_MODE_LCD && glyphs.size() > 1) { + if (IsModeNonLCD(anti_alias) && glyphs.size() > 1) { AdjustGlyphSpace(&glyphs); } @@ -1197,7 +1203,7 @@ int pixel_height = bmp_rect.Height(); int pixel_left = bmp_rect.left; int pixel_top = bmp_rect.top; - if (anti_alias == FT_RENDER_MODE_MONO) { + if (anti_alias == FontAntiAliasingMode::kMono) { auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>(); if (!bitmap->Create(pixel_width, pixel_height, FXDIB_Format::k1bppMask)) { return false; @@ -1242,7 +1248,7 @@ } int dest_width = pixel_width; FX_BGRA_STRUCT<uint8_t> bgra; - if (anti_alias == FT_RENDER_MODE_LCD) { + if (anti_alias == FontAntiAliasingMode::kLcd) { bgra = ArgbToBGRAStruct(fill_color); } @@ -1259,7 +1265,7 @@ const RetainPtr<CFX_DIBitmap>& pGlyph = glyph.glyph_->GetBitmap(); int ncols = pGlyph->GetWidth(); int nrows = pGlyph->GetHeight(); - if (anti_alias == FT_RENDER_MODE_NORMAL) { + if (anti_alias == FontAntiAliasingMode::kNormal) { if (!bitmap->CompositeMask(point.value().x, point.value().y, ncols, nrows, pGlyph, fill_color, 0, 0, BlendMode::kNormal, nullptr, false)) {
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp index e5d15a4..1877d90 100644 --- a/core/fxge/fx_font.cpp +++ b/core/fxge/fx_font.cpp
@@ -35,7 +35,8 @@ } // namespace -FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, int anti_alias) { +FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, + FontAntiAliasingMode anti_alias) { FX_RECT rect; bool bStarted = false; for (const TextGlyphPos& glyph : glyphs) { @@ -49,7 +50,7 @@ } int char_width = glyph.glyph_->GetBitmap()->GetWidth(); - if (anti_alias == FT_RENDER_MODE_LCD) { + if (anti_alias == FontAntiAliasingMode::kLcd) { char_width /= 3; }
diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h index 4891c26..dcf11d1 100644 --- a/core/fxge/fx_font.h +++ b/core/fxge/fx_font.h
@@ -49,6 +49,16 @@ } // namespace pdfium +enum class FontAntiAliasingMode : int { + kNormal, + kLight, + kMono, + kLcd, + kLcdV, + kSdf, + kMax +}; + /* Other font flags */ #define FXFONT_USEEXTERNATTR 0x80000 @@ -65,7 +75,8 @@ class TextGlyphPos; -FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, int anti_alias); +FX_RECT GetGlyphsBBox(const std::vector<TextGlyphPos>& glyphs, + FontAntiAliasingMode anti_alias); ByteString GetNameFromTT(pdfium::span<const uint8_t> name_table, uint32_t name); size_t GetTTCIndex(pdfium::span<const uint8_t> font_data, size_t font_offset);