Home | History | Annotate | Download | only in render
      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
     19 bool 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
     67 void 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
    108 bool 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