1// Copyright 2016 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "core/fpdfapi/render/cpdf_textrenderer.h" 8 9#include <algorithm> 10 11#include "core/fpdfapi/font/cpdf_font.h" 12#include "core/fpdfapi/render/cpdf_charposlist.h" 13#include "core/fpdfapi/render/cpdf_renderoptions.h" 14#include "core/fxge/cfx_graphstatedata.h" 15#include "core/fxge/cfx_pathdata.h" 16#include "core/fxge/cfx_renderdevice.h" 17 18// static 19bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, 20 const std::vector<uint32_t>& charCodes, 21 const std::vector<FX_FLOAT>& charPos, 22 CPDF_Font* pFont, 23 FX_FLOAT font_size, 24 const CFX_Matrix* pText2User, 25 const CFX_Matrix* pUser2Device, 26 const CFX_GraphStateData* pGraphState, 27 FX_ARGB fill_argb, 28 FX_ARGB stroke_argb, 29 CFX_PathData* pClippingPath, 30 int nFlag) { 31 CPDF_CharPosList CharPosList; 32 CharPosList.Load(charCodes, charPos, pFont, font_size); 33 if (CharPosList.m_nChars == 0) 34 return true; 35 36 bool bDraw = true; 37 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; 38 uint32_t startIndex = 0; 39 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { 40 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; 41 if (fontPosition == curFontPosition) 42 continue; 43 auto* font = fontPosition == -1 44 ? &pFont->m_Font 45 : pFont->m_FontFallbacks[fontPosition].get(); 46 if (!pDevice->DrawTextPath(i - startIndex, 47 CharPosList.m_pCharPos + startIndex, font, 48 font_size, pText2User, pUser2Device, pGraphState, 49 fill_argb, stroke_argb, pClippingPath, nFlag)) { 50 bDraw = false; 51 } 52 fontPosition = curFontPosition; 53 startIndex = i; 54 } 55 auto* font = fontPosition == -1 ? &pFont->m_Font 56 : pFont->m_FontFallbacks[fontPosition].get(); 57 if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex, 58 CharPosList.m_pCharPos + startIndex, font, 59 font_size, pText2User, pUser2Device, pGraphState, 60 fill_argb, stroke_argb, pClippingPath, nFlag)) { 61 bDraw = false; 62 } 63 return bDraw; 64} 65 66// static 67void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, 68 FX_FLOAT origin_x, 69 FX_FLOAT origin_y, 70 CPDF_Font* pFont, 71 FX_FLOAT font_size, 72 const CFX_Matrix* pMatrix, 73 const CFX_ByteString& str, 74 FX_ARGB fill_argb, 75 const CFX_GraphStateData* pGraphState, 76 const CPDF_RenderOptions* pOptions) { 77 if (pFont->IsType3Font()) 78 return; 79 80 int nChars = pFont->CountChar(str.c_str(), str.GetLength()); 81 if (nChars <= 0) 82 return; 83 84 int offset = 0; 85 std::vector<uint32_t> codes; 86 std::vector<FX_FLOAT> positions; 87 codes.resize(nChars); 88 positions.resize(nChars - 1); 89 FX_FLOAT cur_pos = 0; 90 for (int i = 0; i < nChars; i++) { 91 codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset); 92 if (i) 93 positions[i - 1] = cur_pos; 94 cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000; 95 } 96 CFX_Matrix matrix; 97 if (pMatrix) 98 matrix = *pMatrix; 99 100 matrix.e = origin_x; 101 matrix.f = origin_y; 102 103 DrawNormalText(pDevice, codes, positions, pFont, font_size, &matrix, 104 fill_argb, pOptions); 105} 106 107// static 108bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, 109 const std::vector<uint32_t>& charCodes, 110 const std::vector<FX_FLOAT>& charPos, 111 CPDF_Font* pFont, 112 FX_FLOAT font_size, 113 const CFX_Matrix* pText2Device, 114 FX_ARGB fill_argb, 115 const CPDF_RenderOptions* pOptions) { 116 CPDF_CharPosList CharPosList; 117 CharPosList.Load(charCodes, charPos, pFont, font_size); 118 if (CharPosList.m_nChars == 0) 119 return true; 120 int FXGE_flags = 0; 121 if (pOptions) { 122 uint32_t dwFlags = pOptions->m_Flags; 123 if (dwFlags & RENDER_CLEARTYPE) { 124 FXGE_flags |= FXTEXT_CLEARTYPE; 125 if (dwFlags & RENDER_BGR_STRIPE) 126 FXGE_flags |= FXTEXT_BGR_STRIPE; 127 } 128 if (dwFlags & RENDER_NOTEXTSMOOTH) 129 FXGE_flags |= FXTEXT_NOSMOOTH; 130 if (dwFlags & RENDER_PRINTGRAPHICTEXT) 131 FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; 132 if (dwFlags & RENDER_NO_NATIVETEXT) 133 FXGE_flags |= FXTEXT_NO_NATIVETEXT; 134 if (dwFlags & RENDER_PRINTIMAGETEXT) 135 FXGE_flags |= FXTEXT_PRINTIMAGETEXT; 136 } else { 137 FXGE_flags = FXTEXT_CLEARTYPE; 138 } 139 if (pFont->IsCIDFont()) 140 FXGE_flags |= FXFONT_CIDFONT; 141 bool bDraw = true; 142 int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition; 143 uint32_t startIndex = 0; 144 for (uint32_t i = 0; i < CharPosList.m_nChars; i++) { 145 int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition; 146 if (fontPosition == curFontPosition) 147 continue; 148 auto* font = fontPosition == -1 149 ? &pFont->m_Font 150 : pFont->m_FontFallbacks[fontPosition].get(); 151 if (!pDevice->DrawNormalText( 152 i - startIndex, CharPosList.m_pCharPos + startIndex, font, 153 font_size, pText2Device, fill_argb, FXGE_flags)) { 154 bDraw = false; 155 } 156 fontPosition = curFontPosition; 157 startIndex = i; 158 } 159 auto* font = fontPosition == -1 ? &pFont->m_Font 160 : pFont->m_FontFallbacks[fontPosition].get(); 161 if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex, 162 CharPosList.m_pCharPos + startIndex, font, 163 font_size, pText2Device, fill_argb, 164 FXGE_flags)) { 165 bDraw = false; 166 } 167 return bDraw; 168} 169