summaryrefslogtreecommitdiff
path: root/core/fpdfapi/render/cpdf_textrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/render/cpdf_textrenderer.cpp')
-rw-r--r--core/fpdfapi/render/cpdf_textrenderer.cpp187
1 files changed, 187 insertions, 0 deletions
diff --git a/core/fpdfapi/render/cpdf_textrenderer.cpp b/core/fpdfapi/render/cpdf_textrenderer.cpp
new file mode 100644
index 0000000000..9cb8ce933e
--- /dev/null
+++ b/core/fpdfapi/render/cpdf_textrenderer.cpp
@@ -0,0 +1,187 @@
+// Copyright 2016 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.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fpdfapi/render/cpdf_textrenderer.h"
+
+#include <vector>
+
+#include "core/fpdfapi/font/cpdf_font.h"
+#include "core/fpdfapi/render/cpdf_charposlist.h"
+#include "core/fpdfapi/render/cpdf_renderoptions.h"
+#include "core/fxge/cfx_graphstatedata.h"
+#include "core/fxge/cfx_pathdata.h"
+#include "core/fxge/cfx_renderdevice.h"
+
+// static
+bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice,
+ int nChars,
+ uint32_t* pCharCodes,
+ FX_FLOAT* pCharPos,
+ CPDF_Font* pFont,
+ FX_FLOAT font_size,
+ const CFX_Matrix* pText2User,
+ const CFX_Matrix* pUser2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_ARGB fill_argb,
+ FX_ARGB stroke_argb,
+ CFX_PathData* pClippingPath,
+ int nFlag) {
+ CPDF_CharPosList CharPosList;
+ CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
+ if (CharPosList.m_nChars == 0)
+ return true;
+
+ bool bDraw = true;
+ int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
+ uint32_t startIndex = 0;
+ for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
+ int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
+ if (fontPosition == curFontPosition)
+ continue;
+ auto* font = fontPosition == -1
+ ? &pFont->m_Font
+ : pFont->m_FontFallbacks[fontPosition].get();
+ if (!pDevice->DrawTextPath(i - startIndex,
+ CharPosList.m_pCharPos + startIndex, font,
+ font_size, pText2User, pUser2Device, pGraphState,
+ fill_argb, stroke_argb, pClippingPath, nFlag)) {
+ bDraw = false;
+ }
+ fontPosition = curFontPosition;
+ startIndex = i;
+ }
+ auto* font = fontPosition == -1 ? &pFont->m_Font
+ : pFont->m_FontFallbacks[fontPosition].get();
+ if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex,
+ CharPosList.m_pCharPos + startIndex, font,
+ font_size, pText2User, pUser2Device, pGraphState,
+ fill_argb, stroke_argb, pClippingPath, nFlag)) {
+ bDraw = false;
+ }
+ return bDraw;
+}
+
+// static
+void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice,
+ FX_FLOAT origin_x,
+ FX_FLOAT origin_y,
+ CPDF_Font* pFont,
+ FX_FLOAT font_size,
+ const CFX_Matrix* pMatrix,
+ const CFX_ByteString& str,
+ FX_ARGB fill_argb,
+ FX_ARGB stroke_argb,
+ const CFX_GraphStateData* pGraphState,
+ const CPDF_RenderOptions* pOptions) {
+ if (pFont->IsType3Font())
+ return;
+
+ int nChars = pFont->CountChar(str.c_str(), str.GetLength());
+ if (nChars <= 0)
+ return;
+
+ int offset = 0;
+ uint32_t* pCharCodes;
+ FX_FLOAT* pCharPos;
+ std::vector<uint32_t> codes;
+ std::vector<FX_FLOAT> positions;
+ if (nChars == 1) {
+ pCharCodes = reinterpret_cast<uint32_t*>(
+ pFont->GetNextChar(str.c_str(), str.GetLength(), offset));
+ pCharPos = nullptr;
+ } else {
+ codes.resize(nChars);
+ positions.resize(nChars - 1);
+ FX_FLOAT cur_pos = 0;
+ for (int i = 0; i < nChars; i++) {
+ codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset);
+ if (i)
+ positions[i - 1] = cur_pos;
+ cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000;
+ }
+ pCharCodes = codes.data();
+ pCharPos = positions.data();
+ }
+ CFX_Matrix matrix;
+ if (pMatrix)
+ matrix = *pMatrix;
+
+ matrix.e = origin_x;
+ matrix.f = origin_y;
+
+ if (stroke_argb == 0) {
+ DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size,
+ &matrix, fill_argb, pOptions);
+ } else {
+ DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size,
+ &matrix, nullptr, pGraphState, fill_argb, stroke_argb, nullptr,
+ 0);
+ }
+}
+
+// static
+bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice,
+ int nChars,
+ uint32_t* pCharCodes,
+ FX_FLOAT* pCharPos,
+ CPDF_Font* pFont,
+ FX_FLOAT font_size,
+ const CFX_Matrix* pText2Device,
+ FX_ARGB fill_argb,
+ const CPDF_RenderOptions* pOptions) {
+ CPDF_CharPosList CharPosList;
+ CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size);
+ if (CharPosList.m_nChars == 0)
+ return true;
+ int FXGE_flags = 0;
+ if (pOptions) {
+ uint32_t dwFlags = pOptions->m_Flags;
+ if (dwFlags & RENDER_CLEARTYPE) {
+ FXGE_flags |= FXTEXT_CLEARTYPE;
+ if (dwFlags & RENDER_BGR_STRIPE)
+ FXGE_flags |= FXTEXT_BGR_STRIPE;
+ }
+ if (dwFlags & RENDER_NOTEXTSMOOTH)
+ FXGE_flags |= FXTEXT_NOSMOOTH;
+ if (dwFlags & RENDER_PRINTGRAPHICTEXT)
+ FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT;
+ if (dwFlags & RENDER_NO_NATIVETEXT)
+ FXGE_flags |= FXTEXT_NO_NATIVETEXT;
+ if (dwFlags & RENDER_PRINTIMAGETEXT)
+ FXGE_flags |= FXTEXT_PRINTIMAGETEXT;
+ } else {
+ FXGE_flags = FXTEXT_CLEARTYPE;
+ }
+ if (pFont->IsCIDFont())
+ FXGE_flags |= FXFONT_CIDFONT;
+ bool bDraw = true;
+ int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
+ uint32_t startIndex = 0;
+ for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
+ int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
+ if (fontPosition == curFontPosition)
+ continue;
+ auto* font = fontPosition == -1
+ ? &pFont->m_Font
+ : pFont->m_FontFallbacks[fontPosition].get();
+ if (!pDevice->DrawNormalText(
+ i - startIndex, CharPosList.m_pCharPos + startIndex, font,
+ font_size, pText2Device, fill_argb, FXGE_flags)) {
+ bDraw = false;
+ }
+ fontPosition = curFontPosition;
+ startIndex = i;
+ }
+ auto* font = fontPosition == -1 ? &pFont->m_Font
+ : pFont->m_FontFallbacks[fontPosition].get();
+ if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex,
+ CharPosList.m_pCharPos + startIndex, font,
+ font_size, pText2Device, fill_argb,
+ FXGE_flags)) {
+ bDraw = false;
+ }
+ return bDraw;
+}