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 namespace {
     19 
     20 CFX_Font* GetFont(CPDF_Font* pFont, int32_t position) {
     21   return position == -1 ? pFont->GetFont() : pFont->GetFontFallback(position);
     22 }
     23 
     24 }  // namespace
     25 
     26 // static
     27 bool CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice,
     28                                      const std::vector<uint32_t>& charCodes,
     29                                      const std::vector<float>& charPos,
     30                                      CPDF_Font* pFont,
     31                                      float font_size,
     32                                      const CFX_Matrix* pText2User,
     33                                      const CFX_Matrix* pUser2Device,
     34                                      const CFX_GraphStateData* pGraphState,
     35                                      FX_ARGB fill_argb,
     36                                      FX_ARGB stroke_argb,
     37                                      CFX_PathData* pClippingPath,
     38                                      int nFlag) {
     39   CPDF_CharPosList CharPosList;
     40   CharPosList.Load(charCodes, charPos, pFont, font_size);
     41   if (CharPosList.m_nChars == 0)
     42     return true;
     43 
     44   bool bDraw = true;
     45   int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
     46   uint32_t startIndex = 0;
     47   for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
     48     int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
     49     if (fontPosition == curFontPosition)
     50       continue;
     51 
     52     CFX_Font* font = GetFont(pFont, fontPosition);
     53     if (!pDevice->DrawTextPath(i - startIndex,
     54                                CharPosList.m_pCharPos + startIndex, font,
     55                                font_size, pText2User, pUser2Device, pGraphState,
     56                                fill_argb, stroke_argb, pClippingPath, nFlag)) {
     57       bDraw = false;
     58     }
     59     fontPosition = curFontPosition;
     60     startIndex = i;
     61   }
     62   CFX_Font* font = GetFont(pFont, fontPosition);
     63   if (!pDevice->DrawTextPath(CharPosList.m_nChars - startIndex,
     64                              CharPosList.m_pCharPos + startIndex, font,
     65                              font_size, pText2User, pUser2Device, pGraphState,
     66                              fill_argb, stroke_argb, pClippingPath, nFlag)) {
     67     bDraw = false;
     68   }
     69   return bDraw;
     70 }
     71 
     72 // static
     73 void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice,
     74                                        float origin_x,
     75                                        float origin_y,
     76                                        CPDF_Font* pFont,
     77                                        float font_size,
     78                                        const CFX_Matrix* pMatrix,
     79                                        const ByteString& str,
     80                                        FX_ARGB fill_argb,
     81                                        const CFX_GraphStateData* pGraphState,
     82                                        const CPDF_RenderOptions* pOptions) {
     83   if (pFont->IsType3Font())
     84     return;
     85 
     86   int nChars = pFont->CountChar(str.c_str(), str.GetLength());
     87   if (nChars <= 0)
     88     return;
     89 
     90   int offset = 0;
     91   std::vector<uint32_t> codes;
     92   std::vector<float> positions;
     93   codes.resize(nChars);
     94   positions.resize(nChars - 1);
     95   float cur_pos = 0;
     96   for (int i = 0; i < nChars; i++) {
     97     codes[i] = pFont->GetNextChar(str.c_str(), str.GetLength(), offset);
     98     if (i)
     99       positions[i - 1] = cur_pos;
    100     cur_pos += pFont->GetCharWidthF(codes[i]) * font_size / 1000;
    101   }
    102   CFX_Matrix matrix;
    103   if (pMatrix)
    104     matrix = *pMatrix;
    105 
    106   matrix.e = origin_x;
    107   matrix.f = origin_y;
    108 
    109   DrawNormalText(pDevice, codes, positions, pFont, font_size, &matrix,
    110                  fill_argb, pOptions);
    111 }
    112 
    113 // static
    114 bool CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice,
    115                                        const std::vector<uint32_t>& charCodes,
    116                                        const std::vector<float>& charPos,
    117                                        CPDF_Font* pFont,
    118                                        float font_size,
    119                                        const CFX_Matrix* pText2Device,
    120                                        FX_ARGB fill_argb,
    121                                        const CPDF_RenderOptions* pOptions) {
    122   CPDF_CharPosList CharPosList;
    123   CharPosList.Load(charCodes, charPos, pFont, font_size);
    124   if (CharPosList.m_nChars == 0)
    125     return true;
    126   int FXGE_flags = 0;
    127   if (pOptions) {
    128     if (pOptions->HasFlag(RENDER_CLEARTYPE)) {
    129       FXGE_flags |= FXTEXT_CLEARTYPE;
    130       if (pOptions->HasFlag(RENDER_BGR_STRIPE))
    131         FXGE_flags |= FXTEXT_BGR_STRIPE;
    132     }
    133     if (pOptions->HasFlag(RENDER_NOTEXTSMOOTH))
    134       FXGE_flags |= FXTEXT_NOSMOOTH;
    135     if (pOptions->HasFlag(RENDER_PRINTGRAPHICTEXT))
    136       FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT;
    137     if (pOptions->HasFlag(RENDER_NO_NATIVETEXT))
    138       FXGE_flags |= FXTEXT_NO_NATIVETEXT;
    139     if (pOptions->HasFlag(RENDER_PRINTIMAGETEXT))
    140       FXGE_flags |= FXTEXT_PRINTIMAGETEXT;
    141   } else {
    142     FXGE_flags = FXTEXT_CLEARTYPE;
    143   }
    144   if (pFont->IsCIDFont())
    145     FXGE_flags |= FXFONT_CIDFONT;
    146   bool bDraw = true;
    147   int32_t fontPosition = CharPosList.m_pCharPos[0].m_FallbackFontPosition;
    148   uint32_t startIndex = 0;
    149   for (uint32_t i = 0; i < CharPosList.m_nChars; i++) {
    150     int32_t curFontPosition = CharPosList.m_pCharPos[i].m_FallbackFontPosition;
    151     if (fontPosition == curFontPosition)
    152       continue;
    153 
    154     CFX_Font* font = GetFont(pFont, fontPosition);
    155     if (!pDevice->DrawNormalText(
    156             i - startIndex, CharPosList.m_pCharPos + startIndex, font,
    157             font_size, pText2Device, fill_argb, FXGE_flags)) {
    158       bDraw = false;
    159     }
    160     fontPosition = curFontPosition;
    161     startIndex = i;
    162   }
    163   CFX_Font* font = GetFont(pFont, fontPosition);
    164   if (!pDevice->DrawNormalText(CharPosList.m_nChars - startIndex,
    165                                CharPosList.m_pCharPos + startIndex, font,
    166                                font_size, pText2Device, fill_argb,
    167                                FXGE_flags)) {
    168     bDraw = false;
    169   }
    170   return bDraw;
    171 }
    172