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/fpdfdoc/cpdf_defaultappearance.h"
8
9 #include <algorithm>
10
11 #include "core/fpdfapi/parser/cpdf_simple_parser.h"
12 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
13 #include "core/fxge/cfx_color.h"
14
HasFont()15 bool CPDF_DefaultAppearance::HasFont() {
16 if (m_csDA.IsEmpty())
17 return false;
18
19 CPDF_SimpleParser syntax(m_csDA.AsStringView());
20 return syntax.FindTagParamFromStart("Tf", 2);
21 }
22
GetFontString()23 ByteString CPDF_DefaultAppearance::GetFontString() {
24 ByteString csFont;
25 if (m_csDA.IsEmpty())
26 return csFont;
27
28 CPDF_SimpleParser syntax(m_csDA.AsStringView());
29 if (syntax.FindTagParamFromStart("Tf", 2)) {
30 csFont += syntax.GetWord();
31 csFont += " ";
32 csFont += syntax.GetWord();
33 csFont += " ";
34 csFont += syntax.GetWord();
35 }
36 return csFont;
37 }
38
GetFont(float * fFontSize)39 ByteString CPDF_DefaultAppearance::GetFont(float* fFontSize) {
40 *fFontSize = 0.0f;
41 if (m_csDA.IsEmpty())
42 return ByteString();
43
44 ByteString csFontNameTag;
45 CPDF_SimpleParser syntax(m_csDA.AsStringView());
46 if (syntax.FindTagParamFromStart("Tf", 2)) {
47 csFontNameTag = ByteString(syntax.GetWord());
48 csFontNameTag.Delete(0, 1);
49 *fFontSize = FX_atof(syntax.GetWord());
50 }
51 return PDF_NameDecode(csFontNameTag);
52 }
53
HasColor(PaintOperation nOperation)54 bool CPDF_DefaultAppearance::HasColor(PaintOperation nOperation) {
55 if (m_csDA.IsEmpty())
56 return false;
57
58 CPDF_SimpleParser syntax(m_csDA.AsStringView());
59 if (syntax.FindTagParamFromStart(
60 (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) {
61 return true;
62 }
63 if (syntax.FindTagParamFromStart(
64 (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) {
65 return true;
66 }
67 return syntax.FindTagParamFromStart(
68 (nOperation == PaintOperation::STROKE ? "K" : "k"), 4);
69 }
70
GetColorString(PaintOperation nOperation)71 ByteString CPDF_DefaultAppearance::GetColorString(PaintOperation nOperation) {
72 ByteString csColor;
73 if (m_csDA.IsEmpty())
74 return csColor;
75
76 CPDF_SimpleParser syntax(m_csDA.AsStringView());
77 if (syntax.FindTagParamFromStart(
78 (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) {
79 csColor += syntax.GetWord();
80 csColor += " ";
81 csColor += syntax.GetWord();
82 return csColor;
83 }
84 if (syntax.FindTagParamFromStart(
85 (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) {
86 csColor += syntax.GetWord();
87 csColor += " ";
88 csColor += syntax.GetWord();
89 csColor += " ";
90 csColor += syntax.GetWord();
91 csColor += " ";
92 csColor += syntax.GetWord();
93 return csColor;
94 }
95 if (syntax.FindTagParamFromStart(
96 (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) {
97 csColor += syntax.GetWord();
98 csColor += " ";
99 csColor += syntax.GetWord();
100 csColor += " ";
101 csColor += syntax.GetWord();
102 csColor += " ";
103 csColor += syntax.GetWord();
104 csColor += " ";
105 csColor += syntax.GetWord();
106 }
107 return csColor;
108 }
109
GetColor(int & iColorType,float fc[4],PaintOperation nOperation)110 void CPDF_DefaultAppearance::GetColor(int& iColorType,
111 float fc[4],
112 PaintOperation nOperation) {
113 iColorType = CFX_Color::kTransparent;
114 for (int c = 0; c < 4; c++)
115 fc[c] = 0;
116
117 if (m_csDA.IsEmpty())
118 return;
119
120 CPDF_SimpleParser syntax(m_csDA.AsStringView());
121 if (syntax.FindTagParamFromStart(
122 (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) {
123 iColorType = CFX_Color::kGray;
124 fc[0] = FX_atof(syntax.GetWord());
125 return;
126 }
127 if (syntax.FindTagParamFromStart(
128 (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) {
129 iColorType = CFX_Color::kRGB;
130 fc[0] = FX_atof(syntax.GetWord());
131 fc[1] = FX_atof(syntax.GetWord());
132 fc[2] = FX_atof(syntax.GetWord());
133 return;
134 }
135 if (syntax.FindTagParamFromStart(
136 (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) {
137 iColorType = CFX_Color::kCMYK;
138 fc[0] = FX_atof(syntax.GetWord());
139 fc[1] = FX_atof(syntax.GetWord());
140 fc[2] = FX_atof(syntax.GetWord());
141 fc[3] = FX_atof(syntax.GetWord());
142 }
143 }
144
GetColor(FX_ARGB & color,int & iColorType,PaintOperation nOperation)145 void CPDF_DefaultAppearance::GetColor(FX_ARGB& color,
146 int& iColorType,
147 PaintOperation nOperation) {
148 color = 0;
149 iColorType = CFX_Color::kTransparent;
150 if (m_csDA.IsEmpty())
151 return;
152
153 CPDF_SimpleParser syntax(m_csDA.AsStringView());
154 if (syntax.FindTagParamFromStart(
155 (nOperation == PaintOperation::STROKE ? "G" : "g"), 1)) {
156 iColorType = CFX_Color::kGray;
157 float g = FX_atof(syntax.GetWord()) * 255 + 0.5f;
158 color = ArgbEncode(255, (int)g, (int)g, (int)g);
159 return;
160 }
161 if (syntax.FindTagParamFromStart(
162 (nOperation == PaintOperation::STROKE ? "RG" : "rg"), 3)) {
163 iColorType = CFX_Color::kRGB;
164 float r = FX_atof(syntax.GetWord()) * 255 + 0.5f;
165 float g = FX_atof(syntax.GetWord()) * 255 + 0.5f;
166 float b = FX_atof(syntax.GetWord()) * 255 + 0.5f;
167 color = ArgbEncode(255, (int)r, (int)g, (int)b);
168 return;
169 }
170 if (syntax.FindTagParamFromStart(
171 (nOperation == PaintOperation::STROKE ? "K" : "k"), 4)) {
172 iColorType = CFX_Color::kCMYK;
173 float c = FX_atof(syntax.GetWord());
174 float m = FX_atof(syntax.GetWord());
175 float y = FX_atof(syntax.GetWord());
176 float k = FX_atof(syntax.GetWord());
177 float r = 1.0f - std::min(1.0f, c + k);
178 float g = 1.0f - std::min(1.0f, m + k);
179 float b = 1.0f - std::min(1.0f, y + k);
180 color = ArgbEncode(255, (int)(r * 255 + 0.5f), (int)(g * 255 + 0.5f),
181 (int)(b * 255 + 0.5f));
182 }
183 }
184
HasTextMatrix()185 bool CPDF_DefaultAppearance::HasTextMatrix() {
186 if (m_csDA.IsEmpty())
187 return false;
188
189 CPDF_SimpleParser syntax(m_csDA.AsStringView());
190 return syntax.FindTagParamFromStart("Tm", 6);
191 }
192
GetTextMatrixString()193 ByteString CPDF_DefaultAppearance::GetTextMatrixString() {
194 ByteString csTM;
195 if (m_csDA.IsEmpty())
196 return csTM;
197
198 CPDF_SimpleParser syntax(m_csDA.AsStringView());
199 if (syntax.FindTagParamFromStart("Tm", 6)) {
200 for (int i = 0; i < 6; i++) {
201 csTM += syntax.GetWord();
202 csTM += " ";
203 }
204 csTM += syntax.GetWord();
205 }
206 return csTM;
207 }
208
GetTextMatrix()209 CFX_Matrix CPDF_DefaultAppearance::GetTextMatrix() {
210 if (m_csDA.IsEmpty())
211 return CFX_Matrix();
212
213 CPDF_SimpleParser syntax(m_csDA.AsStringView());
214 if (!syntax.FindTagParamFromStart("Tm", 6))
215 return CFX_Matrix();
216
217 float f[6];
218 for (int i = 0; i < 6; i++)
219 f[i] = FX_atof(syntax.GetWord());
220 return CFX_Matrix(f);
221 }
222