Create struct CFX_TextRenderOptions to represent text rendering options.
This CL creates a new structure CFX_TextRenderOptions, to represent the
following option flags which are used for text rendering:
FXFONT_CIDFONT
FXTEXT_CLEARTYPE
FXTEXT_BGR_STRIPE
FXTEXT_NO_NATIVETEXT
FXTEXT_NOSMOOTH
This will help remove integer flag |text_flags| in DrawNormalText(),
reduce related bitwise operations, and make it easier to change
rendering options in the future.
Bug: pdfium:1531
Change-Id: I21cc9c57fcf745a01c0b9f519f01cbd9a674941c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70051
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Hui Yingst <nigi@chromium.org>
diff --git a/core/fpdfapi/render/cpdf_textrenderer.cpp b/core/fpdfapi/render/cpdf_textrenderer.cpp
index 2398c7c..24c0e5b 100644
--- a/core/fpdfapi/render/cpdf_textrenderer.cpp
+++ b/core/fpdfapi/render/cpdf_textrenderer.cpp
@@ -24,21 +24,23 @@
return position == -1 ? pFont->GetFont() : pFont->GetFontFallback(position);
}
-int GetTextRenderOptionsHelper(const CPDF_Font* pFont,
- const CPDF_RenderOptions& options) {
- int text_options = 0;
+CFX_TextRenderOptions GetTextRenderOptionsHelper(
+ const CPDF_Font* pFont,
+ const CPDF_RenderOptions& options) {
+ CFX_TextRenderOptions text_options;
+
if (pFont->IsCIDFont())
- text_options |= FXFONT_CIDFONT;
+ text_options.font_is_cid = true;
if (options.GetOptions().bNoTextSmooth) {
- text_options |= FXTEXT_NOSMOOTH;
+ text_options.aliasing_type = CFX_TextRenderOptions::kAliasing;
} else if (options.GetOptions().bClearType) {
- text_options |= FXTEXT_CLEARTYPE;
- if (options.GetOptions().bBGRStripe)
- text_options |= FXTEXT_BGR_STRIPE;
+ text_options.aliasing_type = options.GetOptions().bBGRStripe
+ ? CFX_TextRenderOptions::kBgrStripe
+ : CFX_TextRenderOptions::kLcd;
}
if (options.GetOptions().bNoNativeText)
- text_options |= FXTEXT_NO_NATIVETEXT;
+ text_options.native_text = false;
return text_options;
}
@@ -140,7 +142,8 @@
if (pos.empty())
return true;
- int fxge_flags = GetTextRenderOptionsHelper(pFont, options);
+ CFX_TextRenderOptions text_options =
+ GetTextRenderOptionsHelper(pFont, options);
bool bDraw = true;
int32_t fontPosition = pos[0].m_FallbackFontPosition;
size_t startIndex = 0;
@@ -152,7 +155,7 @@
CFX_Font* font = GetFont(pFont, fontPosition);
if (!pDevice->DrawNormalText(i - startIndex, &pos[startIndex], font,
font_size, mtText2Device, fill_argb,
- fxge_flags)) {
+ text_options)) {
bDraw = false;
}
fontPosition = curFontPosition;
@@ -161,7 +164,7 @@
CFX_Font* font = GetFont(pFont, fontPosition);
if (!pDevice->DrawNormalText(pos.size() - startIndex, &pos[startIndex], font,
font_size, mtText2Device, fill_argb,
- fxge_flags)) {
+ text_options)) {
bDraw = false;
}
return bDraw;
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index 98ec1b5..3d1d0a1 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -53,6 +53,8 @@
"cfx_renderdevice.h",
"cfx_substfont.cpp",
"cfx_substfont.h",
+ "cfx_textrenderoptions.cpp",
+ "cfx_textrenderoptions.h",
"cfx_unicodeencoding.cpp",
"cfx_unicodeencoding.h",
"dib/cfx_bitmapcomposer.cpp",
diff --git a/core/fxge/cfx_font.cpp b/core/fxge/cfx_font.cpp
index 12c1d32..0782c51 100644
--- a/core/fxge/cfx_font.cpp
+++ b/core/fxge/cfx_font.cpp
@@ -709,15 +709,16 @@
return pPath.release();
}
-const CFX_GlyphBitmap* CFX_Font::LoadGlyphBitmap(uint32_t glyph_index,
- bool bFontStyle,
- const CFX_Matrix& matrix,
- uint32_t dest_width,
- int anti_alias,
- int* pTextFlags) const {
+const CFX_GlyphBitmap* CFX_Font::LoadGlyphBitmap(
+ uint32_t glyph_index,
+ bool bFontStyle,
+ const CFX_Matrix& matrix,
+ uint32_t dest_width,
+ int anti_alias,
+ CFX_TextRenderOptions* text_options) const {
return GetOrCreateGlyphCache()->LoadGlyphBitmap(this, glyph_index, bFontStyle,
matrix, dest_width,
- anti_alias, pTextFlags);
+ anti_alias, text_options);
}
const CFX_PathData* CFX_Font::LoadGlyphPath(uint32_t glyph_index,
diff --git a/core/fxge/cfx_font.h b/core/fxge/cfx_font.h
index 45ea79b..e3822b4 100644
--- a/core/fxge/cfx_font.h
+++ b/core/fxge/cfx_font.h
@@ -15,6 +15,7 @@
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxge/cfx_face.h"
+#include "core/fxge/cfx_textrenderoptions.h"
#include "core/fxge/fx_freetype.h"
#include "third_party/base/span.h"
@@ -68,12 +69,13 @@
#endif // !defined(OS_WIN)
#endif // defined(PDF_ENABLE_XFA)
- const CFX_GlyphBitmap* LoadGlyphBitmap(uint32_t glyph_index,
- bool bFontStyle,
- const CFX_Matrix& matrix,
- uint32_t dest_width,
- int anti_alias,
- int* pTextFlags) const;
+ const CFX_GlyphBitmap* LoadGlyphBitmap(
+ uint32_t glyph_index,
+ bool bFontStyle,
+ const CFX_Matrix& matrix,
+ uint32_t dest_width,
+ int anti_alias,
+ CFX_TextRenderOptions* text_options) const;
const CFX_PathData* LoadGlyphPath(uint32_t glyph_index,
uint32_t dest_width) const;
diff --git a/core/fxge/cfx_glyphcache.cpp b/core/fxge/cfx_glyphcache.cpp
index b48697b..57bb0d6 100644
--- a/core/fxge/cfx_glyphcache.cpp
+++ b/core/fxge/cfx_glyphcache.cpp
@@ -246,19 +246,20 @@
return pGlyphPath;
}
-const CFX_GlyphBitmap* CFX_GlyphCache::LoadGlyphBitmap(const CFX_Font* pFont,
- uint32_t glyph_index,
- bool bFontStyle,
- const CFX_Matrix& matrix,
- uint32_t dest_width,
- int anti_alias,
- int* pTextFlags) {
+const CFX_GlyphBitmap* CFX_GlyphCache::LoadGlyphBitmap(
+ const CFX_Font* pFont,
+ uint32_t glyph_index,
+ bool bFontStyle,
+ const CFX_Matrix& matrix,
+ uint32_t dest_width,
+ int anti_alias,
+ CFX_TextRenderOptions* text_options) {
if (glyph_index == kInvalidGlyphIndex)
return nullptr;
UniqueKeyGen keygen;
#if defined(OS_MACOSX)
- const bool bNative = !(*pTextFlags & FXTEXT_NO_NATIVETEXT);
+ const bool bNative = text_options->native_text;
#else
const bool bNative = false;
#endif
@@ -267,7 +268,7 @@
#if defined(OS_MACOSX) && !defined _SKIA_SUPPORT_ && \
!defined _SKIA_SUPPORT_PATHS_
- const bool bDoLookUp = !!(*pTextFlags & FXTEXT_NO_NATIVETEXT);
+ const bool bDoLookUp = !text_options->native_text;
#else
const bool bDoLookUp = true;
#endif
@@ -308,7 +309,7 @@
}
GenKey(&keygen, pFont, matrix, dest_width, anti_alias, /*bNative=*/false);
ByteString FaceGlyphsKey2(keygen.key_, keygen.key_len_);
- *pTextFlags |= FXTEXT_NO_NATIVETEXT;
+ text_options->native_text = false;
return LookUpGlyphBitmap(pFont, matrix, FaceGlyphsKey2, glyph_index,
bFontStyle, dest_width, anti_alias);
#endif
diff --git a/core/fxge/cfx_glyphcache.h b/core/fxge/cfx_glyphcache.h
index caf9172..d8305c7 100644
--- a/core/fxge/cfx_glyphcache.h
+++ b/core/fxge/cfx_glyphcache.h
@@ -25,6 +25,7 @@
class CFX_GlyphBitmap;
class CFX_Matrix;
class CFX_PathData;
+struct CFX_TextRenderOptions;
class CFX_GlyphCache : public Retainable, public Observable {
public:
@@ -37,7 +38,7 @@
const CFX_Matrix& matrix,
uint32_t dest_width,
int anti_alias,
- int* pTextFlags);
+ CFX_TextRenderOptions* text_options);
const CFX_PathData* LoadGlyphPath(const CFX_Font* pFont,
uint32_t glyph_index,
uint32_t dest_width);
diff --git a/core/fxge/cfx_renderdevice.cpp b/core/fxge/cfx_renderdevice.cpp
index 7899d0a..49ff7ca 100644
--- a/core/fxge/cfx_renderdevice.cpp
+++ b/core/fxge/cfx_renderdevice.cpp
@@ -353,9 +353,10 @@
}
}
-bool ShouldDrawDeviceText(const CFX_Font* pFont, uint32_t text_flags) {
+bool ShouldDrawDeviceText(const CFX_Font* pFont,
+ const CFX_TextRenderOptions& options) {
#if defined(OS_MACOSX)
- if (text_flags & FXFONT_CIDFONT)
+ if (options.font_is_cid)
return false;
const ByteString bsPsName = pFont->GetPsName();
@@ -860,38 +861,37 @@
float font_size,
const CFX_Matrix& mtText2Device,
uint32_t fill_color,
- uint32_t text_flags) {
- int nativetext_flags = text_flags;
+ const CFX_TextRenderOptions& options) {
if (GetDeviceType() != DeviceType::kDisplay) {
- if (ShouldDrawDeviceText(pFont, text_flags) &&
+ if (ShouldDrawDeviceText(pFont, options) &&
m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, mtText2Device,
font_size, fill_color)) {
return true;
}
if (FXARGB_A(fill_color) < 255)
return false;
- } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) {
- if (ShouldDrawDeviceText(pFont, text_flags) &&
+ } else if (options.native_text) {
+ if (ShouldDrawDeviceText(pFont, options) &&
m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, mtText2Device,
font_size, fill_color)) {
return true;
}
}
+ bool is_text_smooth = options.IsSmooth();
CFX_Matrix char2device = mtText2Device;
CFX_Matrix text2Device = mtText2Device;
char2device.Scale(font_size, -font_size);
if (fabs(char2device.a) + fabs(char2device.b) > 50 * 1.0f ||
GetDeviceType() == DeviceType::kPrinter) {
if (pFont->GetFaceRec()) {
- int nPathFlags =
- (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH;
+ int nPathFlags = is_text_smooth ? 0 : FXFILL_NOPATHSMOOTH;
return DrawTextPath(nChars, pCharPos, pFont, font_size, mtText2Device,
nullptr, nullptr, fill_color, 0, nullptr, nPathFlags);
}
}
int anti_alias = FT_RENDER_MODE_MONO;
bool bNormal = false;
- if ((text_flags & FXTEXT_NOSMOOTH) == 0) {
+ if (is_text_smooth) {
if (GetDeviceType() == DeviceType::kDisplay && m_bpp > 1) {
if (!CFX_GEModule::Get()->GetFontMgr()->FTLibrarySupportsHinting()) {
// Some Freetype implementations (like the one packaged with Fedora) do
@@ -907,16 +907,13 @@
anti_alias = FT_RENDER_MODE_NORMAL;
} else {
anti_alias = FT_RENDER_MODE_LCD;
-
- bool bClearType = false;
- if (pFont->GetFaceRec())
- bClearType = !!(text_flags & FXTEXT_CLEARTYPE);
- bNormal = !bClearType;
+ bNormal = !pFont->GetFaceRec() || !options.IsLcd();
}
}
}
std::vector<TextGlyphPos> glyphs(nChars);
CFX_Matrix deviceCtm = char2device;
+ CFX_TextRenderOptions native_text_options(options);
for (size_t i = 0; i < glyphs.size(); ++i) {
TextGlyphPos& glyph = glyphs[i];
@@ -936,11 +933,11 @@
new_matrix.Concat(deviceCtm);
glyph.m_pGlyph = pFont->LoadGlyphBitmap(
charpos.m_GlyphIndex, charpos.m_bFontStyle, new_matrix,
- charpos.m_FontCharWidth, anti_alias, &nativetext_flags);
+ charpos.m_FontCharWidth, anti_alias, &native_text_options);
} else {
glyph.m_pGlyph = pFont->LoadGlyphBitmap(
charpos.m_GlyphIndex, charpos.m_bFontStyle, deviceCtm,
- charpos.m_FontCharWidth, anti_alias, &nativetext_flags);
+ charpos.m_FontCharWidth, anti_alias, &native_text_options);
}
}
if (anti_alias < FT_RENDER_MODE_LCD && glyphs.size() > 1)
@@ -1019,7 +1016,6 @@
}
continue;
}
- bool bBGRStripe = !!(text_flags & FXTEXT_BGR_STRIPE);
ncols /= 3;
int x_subpixel = static_cast<int>(glyph.m_fDeviceOrigin.x * 3) % 3;
int start_col = std::max(point->x, 0);
@@ -1032,8 +1028,10 @@
if (start_col >= end_col)
continue;
- DrawNormalTextHelper(bitmap, pGlyph, nrows, point->x, point->y, start_col,
- end_col, bNormal, bBGRStripe, x_subpixel, a, r, g, b);
+ DrawNormalTextHelper(
+ bitmap, pGlyph, nrows, point->x, point->y, start_col, end_col, bNormal,
+ options.aliasing_type == CFX_TextRenderOptions::kBgrStripe, x_subpixel,
+ a, r, g, b);
}
if (bitmap->IsAlphaMask())
SetBitMask(bitmap, bmp_rect.left, bmp_rect.top, fill_color);
diff --git a/core/fxge/cfx_renderdevice.h b/core/fxge/cfx_renderdevice.h
index e4b6437..84c2e03 100644
--- a/core/fxge/cfx_renderdevice.h
+++ b/core/fxge/cfx_renderdevice.h
@@ -26,6 +26,7 @@
class PauseIndicatorIface;
class TextCharPos;
struct CFX_Color;
+struct CFX_TextRenderOptions;
enum class BorderStyle { SOLID, DASH, BEVELED, INSET, UNDERLINE };
@@ -162,7 +163,7 @@
float font_size,
const CFX_Matrix& mtText2Device,
uint32_t fill_color,
- uint32_t text_flags);
+ const CFX_TextRenderOptions& options);
bool DrawTextPath(int nChars,
const TextCharPos* pCharPos,
CFX_Font* pFont,
diff --git a/core/fxge/cfx_textrenderoptions.cpp b/core/fxge/cfx_textrenderoptions.cpp
new file mode 100644
index 0000000..6d63aeb
--- /dev/null
+++ b/core/fxge/cfx_textrenderoptions.cpp
@@ -0,0 +1,21 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/fxge/cfx_textrenderoptions.h"
+
+#include "third_party/base/no_destructor.h"
+
+// static
+const CFX_TextRenderOptions& CFX_TextRenderOptions::LcdOptions() {
+ static pdfium::base::NoDestructor<CFX_TextRenderOptions> instance(kLcd);
+ return *instance;
+}
+
+CFX_TextRenderOptions::CFX_TextRenderOptions() = default;
+
+CFX_TextRenderOptions::CFX_TextRenderOptions(AliasingType type)
+ : aliasing_type(type) {}
+
+CFX_TextRenderOptions::CFX_TextRenderOptions(
+ const CFX_TextRenderOptions& other) = default;
diff --git a/core/fxge/cfx_textrenderoptions.h b/core/fxge/cfx_textrenderoptions.h
new file mode 100644
index 0000000..eecc487
--- /dev/null
+++ b/core/fxge/cfx_textrenderoptions.h
@@ -0,0 +1,48 @@
+// Copyright 2020 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CORE_FXGE_CFX_TEXTRENDEROPTIONS_H_
+#define CORE_FXGE_CFX_TEXTRENDEROPTIONS_H_
+
+struct CFX_TextRenderOptions {
+ // AliasingType defines the options for drawing pixels on the edges of the
+ // text. The values are defined in an incrementing order due to the latter
+ // aliasing type's dependency on the previous one.
+ enum AliasingType {
+ // No transparent pixels on glyph edges.
+ kAliasing,
+
+ // May have transparent pixels on glyph edges.
+ kAntiAliasing,
+
+ // LCD optimization, can be enabled when anti-aliasing is allowed.
+ kLcd,
+
+ // BGR stripe optimization, can be enabled when LCD optimazation is enabled.
+ kBgrStripe,
+ };
+
+ static const CFX_TextRenderOptions& LcdOptions();
+
+ CFX_TextRenderOptions();
+ explicit CFX_TextRenderOptions(AliasingType type);
+ CFX_TextRenderOptions(const CFX_TextRenderOptions& other);
+
+ // Indicates whether LCD optimazation is enabled.
+ bool IsLcd() const { return aliasing_type >= kLcd; }
+
+ // Indicates whether anti aliasing is enabled.
+ bool IsSmooth() const { return aliasing_type >= kAntiAliasing; }
+
+ // Aliasing option for fonts.
+ AliasingType aliasing_type = kAntiAliasing;
+
+ // Font is CID font.
+ bool font_is_cid = false;
+
+ // Using the native text output available on some platforms.
+ bool native_text = true;
+};
+
+#endif // CORE_FXGE_CFX_TEXTRENDEROPTIONS_H_
diff --git a/core/fxge/fx_font.h b/core/fxge/fx_font.h
index b748d55..0c2229a 100644
--- a/core/fxge/fx_font.h
+++ b/core/fxge/fx_font.h
@@ -39,7 +39,6 @@
/* Other font flags */
#define FXFONT_USEEXTERNATTR 0x80000
-#define FXFONT_CIDFONT 0x100000
#define GET_TT_SHORT(w) (uint16_t)(((w)[0] << 8) | (w)[1])
#define GET_TT_LONG(w) \
diff --git a/core/fxge/render_defines.h b/core/fxge/render_defines.h
index 152c7f1..3321505 100644
--- a/core/fxge/render_defines.h
+++ b/core/fxge/render_defines.h
@@ -39,9 +39,4 @@
#define FX_ZEROAREA_FILL 256
#define FXFILL_NOPATHSMOOTH 512
-#define FXTEXT_CLEARTYPE 0x01
-#define FXTEXT_BGR_STRIPE 0x02
-#define FXTEXT_NO_NATIVETEXT 0x08
-#define FXTEXT_NOSMOOTH 0x20
-
#endif // CORE_FXGE_RENDER_DEFINES_H_
diff --git a/fxbarcode/oned/BC_OneDimWriter.cpp b/fxbarcode/oned/BC_OneDimWriter.cpp
index 8634ecd..605fd8f 100644
--- a/fxbarcode/oned/BC_OneDimWriter.cpp
+++ b/fxbarcode/oned/BC_OneDimWriter.cpp
@@ -37,8 +37,8 @@
#include "fxbarcode/BC_Writer.h"
// static
-uint32_t CBC_OneDimWriter::GetTextRenderOptions() {
- return FXTEXT_CLEARTYPE;
+const CFX_TextRenderOptions& CBC_OneDimWriter::GetTextRenderOptions() {
+ return CFX_TextRenderOptions::LcdOptions();
}
// static
diff --git a/fxbarcode/oned/BC_OneDimWriter.h b/fxbarcode/oned/BC_OneDimWriter.h
index da9b086..98e8878 100644
--- a/fxbarcode/oned/BC_OneDimWriter.h
+++ b/fxbarcode/oned/BC_OneDimWriter.h
@@ -11,6 +11,7 @@
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/unowned_ptr.h"
+#include "core/fxge/cfx_textrenderoptions.h"
#include "fxbarcode/BC_Library.h"
#include "fxbarcode/BC_Writer.h"
#include "fxbarcode/utils.h"
@@ -22,7 +23,7 @@
class CBC_OneDimWriter : public CBC_Writer {
public:
- static uint32_t GetTextRenderOptions();
+ static const CFX_TextRenderOptions& GetTextRenderOptions();
static bool HasValidContentSize(WideStringView contents);
CBC_OneDimWriter();
diff --git a/xfa/fde/cfde_textout.cpp b/xfa/fde/cfde_textout.cpp
index 35d66c9..c54973d 100644
--- a/xfa/fde/cfde_textout.cpp
+++ b/xfa/fde/cfde_textout.cpp
@@ -69,6 +69,7 @@
RetainPtr<CFGAS_GEFont> pCurFont;
TextCharPos* pCurCP = nullptr;
int32_t iCurCount = 0;
+ const CFX_TextRenderOptions& options = CFX_TextRenderOptions::LcdOptions();
for (auto& pos : pCharPos) {
RetainPtr<CFGAS_GEFont> pSTFont =
pFont->GetSubstFont(static_cast<int32_t>(pos.m_GlyphIndex));
@@ -88,7 +89,7 @@
#endif
device->DrawNormalText(iCurCount, pCurCP, font, -fFontSize, matrix,
- color, FXTEXT_CLEARTYPE);
+ color, options);
}
pCurFont = pSTFont;
pCurCP = &pos;
@@ -111,7 +112,7 @@
#endif
bRet = device->DrawNormalText(iCurCount, pCurCP, font, -fFontSize, matrix,
- color, FXTEXT_CLEARTYPE);
+ color, options);
}
#if defined _SKIA_SUPPORT_ || defined _SKIA_SUPPORT_PATHS_
device->Flush(false);