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/page/cpdf_textstate.h"
8 
9 #include "core/fpdfapi/font/cpdf_font.h"
10 #include "core/fpdfapi/page/cpdf_docpagedata.h"
11 #include "core/fpdfapi/parser/cpdf_document.h"
12 
13 CPDF_TextState::CPDF_TextState() = default;
14 
15 CPDF_TextState::~CPDF_TextState() = default;
16 
Emplace()17 void CPDF_TextState::Emplace() {
18   m_Ref.Emplace();
19 }
20 
GetFont() const21 RetainPtr<CPDF_Font> CPDF_TextState::GetFont() const {
22   return m_Ref.GetObject()->m_pFont;
23 }
24 
SetFont(const RetainPtr<CPDF_Font> & pFont)25 void CPDF_TextState::SetFont(const RetainPtr<CPDF_Font>& pFont) {
26   m_Ref.GetPrivateCopy()->SetFont(pFont);
27 }
28 
GetFontSize() const29 float CPDF_TextState::GetFontSize() const {
30   return m_Ref.GetObject()->m_FontSize;
31 }
32 
SetFontSize(float size)33 void CPDF_TextState::SetFontSize(float size) {
34   m_Ref.GetPrivateCopy()->m_FontSize = size;
35 }
36 
GetMatrix() const37 const float* CPDF_TextState::GetMatrix() const {
38   return m_Ref.GetObject()->m_Matrix;
39 }
40 
GetMutableMatrix()41 float* CPDF_TextState::GetMutableMatrix() {
42   return m_Ref.GetPrivateCopy()->m_Matrix;
43 }
44 
GetCharSpace() const45 float CPDF_TextState::GetCharSpace() const {
46   return m_Ref.GetObject()->m_CharSpace;
47 }
48 
SetCharSpace(float sp)49 void CPDF_TextState::SetCharSpace(float sp) {
50   m_Ref.GetPrivateCopy()->m_CharSpace = sp;
51 }
52 
GetWordSpace() const53 float CPDF_TextState::GetWordSpace() const {
54   return m_Ref.GetObject()->m_WordSpace;
55 }
56 
SetWordSpace(float sp)57 void CPDF_TextState::SetWordSpace(float sp) {
58   m_Ref.GetPrivateCopy()->m_WordSpace = sp;
59 }
60 
GetFontSizeH() const61 float CPDF_TextState::GetFontSizeH() const {
62   return m_Ref.GetObject()->GetFontSizeH();
63 }
64 
GetTextMode() const65 TextRenderingMode CPDF_TextState::GetTextMode() const {
66   return m_Ref.GetObject()->m_TextMode;
67 }
68 
SetTextMode(TextRenderingMode mode)69 void CPDF_TextState::SetTextMode(TextRenderingMode mode) {
70   m_Ref.GetPrivateCopy()->m_TextMode = mode;
71 }
72 
GetCTM() const73 const float* CPDF_TextState::GetCTM() const {
74   return m_Ref.GetObject()->m_CTM;
75 }
76 
GetMutableCTM()77 float* CPDF_TextState::GetMutableCTM() {
78   return m_Ref.GetPrivateCopy()->m_CTM;
79 }
80 
TextData()81 CPDF_TextState::TextData::TextData()
82     : m_pFont(nullptr),
83       m_pDocument(nullptr),
84       m_FontSize(1.0f),
85       m_CharSpace(0),
86       m_WordSpace(0),
87       m_TextMode(TextRenderingMode::MODE_FILL) {
88   m_Matrix[0] = m_Matrix[3] = 1.0f;
89   m_Matrix[1] = m_Matrix[2] = 0;
90   m_CTM[0] = m_CTM[3] = 1.0f;
91   m_CTM[1] = m_CTM[2] = 0;
92 }
93 
TextData(const TextData & that)94 CPDF_TextState::TextData::TextData(const TextData& that)
95     : m_pFont(that.m_pFont),
96       m_pDocument(that.m_pDocument),
97       m_FontSize(that.m_FontSize),
98       m_CharSpace(that.m_CharSpace),
99       m_WordSpace(that.m_WordSpace),
100       m_TextMode(that.m_TextMode) {
101   for (int i = 0; i < 4; ++i)
102     m_Matrix[i] = that.m_Matrix[i];
103 
104   for (int i = 0; i < 4; ++i)
105     m_CTM[i] = that.m_CTM[i];
106 
107   if (m_pDocument && m_pFont) {
108     auto* pPageData = CPDF_DocPageData::FromDocument(m_pDocument.Get());
109     m_pFont = pPageData->GetFont(m_pFont->GetFontDict());
110   }
111 }
112 
113 CPDF_TextState::TextData::~TextData() = default;
114 
Clone() const115 RetainPtr<CPDF_TextState::TextData> CPDF_TextState::TextData::Clone() const {
116   return pdfium::MakeRetain<CPDF_TextState::TextData>(*this);
117 }
118 
SetFont(const RetainPtr<CPDF_Font> & pFont)119 void CPDF_TextState::TextData::SetFont(const RetainPtr<CPDF_Font>& pFont) {
120   m_pDocument = pFont ? pFont->GetDocument() : nullptr;
121   m_pFont = pFont;
122 }
123 
GetFontSizeH() const124 float CPDF_TextState::TextData::GetFontSizeH() const {
125   return fabs(FXSYS_sqrt2(m_Matrix[0], m_Matrix[2]) * m_FontSize);
126 }
127 
SetTextRenderingModeFromInt(int iMode,TextRenderingMode * mode)128 bool SetTextRenderingModeFromInt(int iMode, TextRenderingMode* mode) {
129   if (iMode < 0 || iMode > 7)
130     return false;
131   *mode = static_cast<TextRenderingMode>(iMode);
132   return true;
133 }
134 
TextRenderingModeIsClipMode(const TextRenderingMode & mode)135 bool TextRenderingModeIsClipMode(const TextRenderingMode& mode) {
136   switch (mode) {
137     case TextRenderingMode::MODE_FILL_CLIP:
138     case TextRenderingMode::MODE_STROKE_CLIP:
139     case TextRenderingMode::MODE_FILL_STROKE_CLIP:
140     case TextRenderingMode::MODE_CLIP:
141       return true;
142     default:
143       return false;
144   }
145 }
146 
TextRenderingModeIsStrokeMode(const TextRenderingMode & mode)147 bool TextRenderingModeIsStrokeMode(const TextRenderingMode& mode) {
148   switch (mode) {
149     case TextRenderingMode::MODE_STROKE:
150     case TextRenderingMode::MODE_FILL_STROKE:
151     case TextRenderingMode::MODE_STROKE_CLIP:
152     case TextRenderingMode::MODE_FILL_STROKE_CLIP:
153       return true;
154     default:
155       return false;
156   }
157 }
158