From 8f5f897b50918fe83da894d9e7a34bbe314244de Mon Sep 17 00:00:00 2001 From: thestig Date: Fri, 20 May 2016 17:28:24 -0700 Subject: Add an enum to represent text rendering modes. Review-Url: https://codereview.chromium.org/1999553002 --- core/fpdfapi/fpdf_page/cpdf_textobject.cpp | 3 +- core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp | 33 ++++++++- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 23 +++--- .../fpdfapi/fpdf_page/include/cpdf_textstatedata.h | 18 ++++- core/fpdfapi/fpdf_render/fpdf_render_text.cpp | 85 ++++++++++++---------- fpdfsdk/fxedit/fxet_pageobjs.cpp | 2 +- 6 files changed, 106 insertions(+), 58 deletions(-) diff --git a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp index a3fbbad8b0..72658c67ba 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textobject.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textobject.cpp @@ -313,8 +313,7 @@ void CPDF_TextObject::CalcPositionData(FX_FLOAT* pTextAdvanceX, m_Bottom = min_y; m_Top = max_y; matrix.TransformRect(m_Left, m_Right, m_Top, m_Bottom); - int textmode = m_TextState.GetObject()->m_TextMode; - if (textmode == 1 || textmode == 2 || textmode == 5 || textmode == 6) { + if (TextRenderingModeIsStrokeMode(m_TextState.GetObject()->m_TextMode)) { FX_FLOAT half_width = m_GraphState.GetObject()->m_LineWidth / 2; m_Left -= half_width; m_Right += half_width; diff --git a/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp b/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp index 5cd6061542..e60af0076e 100644 --- a/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_textstatedata.cpp @@ -10,13 +10,44 @@ #include "core/fpdfapi/fpdf_page/pageint.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" +bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode) { + if (iMode < 0 || iMode > 7) + return false; + *mode = static_cast(iMode); + return true; +} + +bool TextRenderingModeIsClipMode(const TextRenderingMode& mode) { + switch (mode) { + case TextRenderingMode::MODE_FILL_CLIP: + case TextRenderingMode::MODE_STROKE_CLIP: + case TextRenderingMode::MODE_FILL_STROKE_CLIP: + case TextRenderingMode::MODE_CLIP: + return true; + default: + return false; + } +} + +bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode) { + switch (mode) { + case TextRenderingMode::MODE_STROKE: + case TextRenderingMode::MODE_FILL_STROKE: + case TextRenderingMode::MODE_STROKE_CLIP: + case TextRenderingMode::MODE_FILL_STROKE_CLIP: + return true; + default: + return false; + } +} + CPDF_TextStateData::CPDF_TextStateData() : m_pFont(nullptr), m_pDocument(nullptr), m_FontSize(1.0f), m_CharSpace(0), m_WordSpace(0), - m_TextMode(0) { + m_TextMode(TextRenderingMode::MODE_FILL) { m_Matrix[0] = m_Matrix[3] = 1.0f; m_Matrix[1] = m_Matrix[2] = 0; m_CTM[0] = m_CTM[3] = 1.0f; diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 0374915af4..4a7b6ad403 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -816,8 +816,10 @@ void CPDF_StreamContentParser::Handle_EndText() { if (m_ClipTextList.empty()) return; - if (m_pCurStates->m_TextState.GetObject()->m_TextMode >= 4) + if (TextRenderingModeIsClipMode( + m_pCurStates->m_TextState.GetObject()->m_TextMode)) { m_pCurStates->m_ClipPath.AppendTexts(&m_ClipTextList); + } m_ClipTextList.clear(); } @@ -1251,17 +1253,14 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, if (nsegs == 0) { return; } - int textmode; - if (pFont->IsType3Font()) { - textmode = 0; - } else { - textmode = m_pCurStates->m_TextState.GetObject()->m_TextMode; - } + const TextRenderingMode text_mode = + pFont->IsType3Font() ? TextRenderingMode::MODE_FILL + : m_pCurStates->m_TextState.GetObject()->m_TextMode; { std::unique_ptr pText(new CPDF_TextObject); m_pLastTextObject = pText.get(); SetGraphicStates(m_pLastTextObject, TRUE, TRUE, TRUE); - if (textmode && textmode != 3 && textmode != 4 && textmode != 7) { + if (TextRenderingModeIsStrokeMode(text_mode)) { FX_FLOAT* pCTM = pText->m_TextState.GetModify()->m_CTM; pCTM[0] = m_pCurStates->m_CTM.a; pCTM[1] = m_pCurStates->m_CTM.c; @@ -1278,7 +1277,7 @@ void CPDF_StreamContentParser::AddTextObject(CFX_ByteString* pStrs, m_pCurStates->m_TextHorzScale, m_Level); m_pCurStates->m_TextX += x_advance; m_pCurStates->m_TextY += y_advance; - if (textmode > 3) { + if (TextRenderingModeIsClipMode(text_mode)) { m_ClipTextList.push_back( std::unique_ptr(pText->Clone())); } @@ -1380,10 +1379,8 @@ void CPDF_StreamContentParser::OnChangeTextMatrix() { void CPDF_StreamContentParser::Handle_SetTextRenderMode() { int mode = GetInteger(0); - if (mode < 0 || mode > 7) { - return; - } - m_pCurStates->m_TextState.GetModify()->m_TextMode = mode; + SetTextRenderingModeFromInt( + mode, &m_pCurStates->m_TextState.GetModify()->m_TextMode); } void CPDF_StreamContentParser::Handle_SetTextRise() { diff --git a/core/fpdfapi/fpdf_page/include/cpdf_textstatedata.h b/core/fpdfapi/fpdf_page/include/cpdf_textstatedata.h index feed1a043f..4e33d5f170 100644 --- a/core/fpdfapi/fpdf_page/include/cpdf_textstatedata.h +++ b/core/fpdfapi/fpdf_page/include/cpdf_textstatedata.h @@ -12,6 +12,22 @@ class CPDF_Font; class CPDF_Document; +// See PDF Reference 1.7, page 402, table 5.3. +enum class TextRenderingMode { + MODE_FILL = 0, + MODE_STROKE = 1, + MODE_FILL_STROKE = 2, + MODE_INVISIBLE = 3, + MODE_FILL_CLIP = 4, + MODE_STROKE_CLIP = 5, + MODE_FILL_STROKE_CLIP = 6, + MODE_CLIP = 7, +}; + +bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode); +bool TextRenderingModeIsClipMode(const TextRenderingMode& mode); +bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode); + class CPDF_TextStateData { public: CPDF_TextStateData(); @@ -23,8 +39,8 @@ class CPDF_TextStateData { FX_FLOAT m_FontSize; FX_FLOAT m_CharSpace; FX_FLOAT m_WordSpace; + TextRenderingMode m_TextMode; FX_FLOAT m_Matrix[4]; - int m_TextMode; FX_FLOAT m_CTM[4]; }; diff --git a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp index f2704b7d60..ce73208896 100644 --- a/core/fpdfapi/fpdf_render/fpdf_render_text.cpp +++ b/core/fpdfapi/fpdf_render/fpdf_render_text.cpp @@ -6,6 +6,8 @@ #include "core/fpdfapi/fpdf_render/render_int.h" +#include + #include "core/fpdfapi/fpdf_font/cpdf_cidfont.h" #include "core/fpdfapi/fpdf_font/cpdf_type3char.h" #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" @@ -211,72 +213,76 @@ CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_Matrix* pObj2Device, CFX_PathData* pClippingPath) { - if (textobj->m_nChars == 0) { + if (textobj->m_nChars == 0) return TRUE; - } - int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; - if (text_render_mode == 3) { + + const TextRenderingMode& text_render_mode = + textobj->m_TextState.GetObject()->m_TextMode; + if (text_render_mode == TextRenderingMode::MODE_INVISIBLE) return TRUE; - } + CPDF_Font* pFont = textobj->m_TextState.GetFont(); - if (pFont->IsType3Font()) { + if (pFont->IsType3Font()) return ProcessType3Text(textobj, pObj2Device); - } - FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; + + bool bFill = false; + bool bStroke = false; + bool bClip = false; if (pClippingPath) { - bClip = TRUE; + bClip = true; } else { switch (text_render_mode) { - case 0: - case 4: - bFill = TRUE; + case TextRenderingMode::MODE_FILL: + case TextRenderingMode::MODE_FILL_CLIP: + bFill = true; break; - case 1: - case 5: - if (!pFont->GetFace() && - !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { - bFill = TRUE; + case TextRenderingMode::MODE_STROKE: + case TextRenderingMode::MODE_STROKE_CLIP: + if (pFont->GetFace() || + (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { + bStroke = true; } else { - bStroke = TRUE; + bFill = true; } break; - case 2: - case 6: - if (!pFont->GetFace() && - !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { - bFill = TRUE; - } else { - bFill = bStroke = TRUE; + case TextRenderingMode::MODE_FILL_STROKE: + case TextRenderingMode::MODE_FILL_STROKE_CLIP: + bFill = true; + if (pFont->GetFace() || + (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { + bStroke = true; } break; - case 3: - case 7: + case TextRenderingMode::MODE_INVISIBLE: + // Already handled above, but the compiler is not smart enough to + // realize it. Fall through. + ASSERT(false); + case TextRenderingMode::MODE_CLIP: return TRUE; - default: - bFill = TRUE; } } - FX_ARGB stroke_argb = 0, fill_argb = 0; - FX_BOOL bPattern = FALSE; + FX_ARGB stroke_argb = 0; + FX_ARGB fill_argb = 0; + bool bPattern = false; if (bStroke) { if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { - bPattern = TRUE; + bPattern = true; } else { stroke_argb = GetStrokeArgb(textobj); } } if (bFill) { if (textobj->m_ColorState.GetFillColor()->IsPattern()) { - bPattern = TRUE; + bPattern = true; } else { fill_argb = GetFillArgb(textobj); } } CFX_Matrix text_matrix; textobj->GetTextMatrix(&text_matrix); - if (IsAvailableMatrix(text_matrix) == FALSE) { + if (!IsAvailableMatrix(text_matrix)) return TRUE; - } + FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); if (bPattern) { DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, @@ -319,6 +325,7 @@ FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, &text_matrix, fill_argb, &m_Options); } + CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) { if (!pFont->m_pDocument) { return NULL; @@ -336,17 +343,15 @@ static void ReleaseCachedType3(CPDF_Type3Font* pFont) { class CPDF_RefType3Cache { public: - CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) { - m_dwCount = 0; - m_pType3Font = pType3Font; - } + explicit CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) + : m_dwCount(0), m_pType3Font(pType3Font) {} ~CPDF_RefType3Cache() { while (m_dwCount--) { ReleaseCachedType3(m_pType3Font); } } uint32_t m_dwCount; - CPDF_Type3Font* m_pType3Font; + CPDF_Type3Font* const m_pType3Font; }; FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, diff --git a/fpdfsdk/fxedit/fxet_pageobjs.cpp b/fpdfsdk/fxedit/fxet_pageobjs.cpp index e8d9e2a371..be386095e2 100644 --- a/fpdfsdk/fxedit/fxet_pageobjs.cpp +++ b/fpdfsdk/fxedit/fxet_pageobjs.cpp @@ -422,7 +422,7 @@ static CPDF_TextObject* AddTextObjToPageObjects( pTextStateData->m_FontSize = fFontSize; pTextStateData->m_CharSpace = fCharSpace; pTextStateData->m_WordSpace = 0; - pTextStateData->m_TextMode = 0; + pTextStateData->m_TextMode = TextRenderingMode::MODE_FILL; pTextStateData->m_Matrix[0] = nHorzScale / 100.0f; pTextStateData->m_Matrix[1] = 0; pTextStateData->m_Matrix[2] = 0; -- cgit v1.2.3