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 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 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 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 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 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 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 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 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 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 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