OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_page/pageint.h" | 7 #include "core/fpdfapi/fpdf_page/pageint.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "core/fpdfapi/fpdf_edit/include/cpdf_creator.h" | 11 #include "core/fpdfapi/fpdf_edit/include/cpdf_creator.h" |
12 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" | 12 #include "core/fpdfapi/fpdf_font/cpdf_type3font.h" |
13 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" | 13 #include "core/fpdfapi/fpdf_font/include/cpdf_font.h" |
14 #include "core/fpdfapi/fpdf_page/cpdf_allstates.h" | 14 #include "core/fpdfapi/fpdf_page/cpdf_allstates.h" |
| 15 #include "core/fpdfapi/fpdf_page/cpdf_meshstream.h" |
15 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" | 16 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" |
16 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" | 17 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h" |
17 #include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h" | 18 #include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h" |
18 #include "core/fpdfapi/fpdf_page/include/cpdf_image.h" | 19 #include "core/fpdfapi/fpdf_page/include/cpdf_image.h" |
19 #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h" | 20 #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h" |
20 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" | 21 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h" |
21 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" | 22 #include "core/fpdfapi/fpdf_page/include/cpdf_pathobject.h" |
22 #include "core/fpdfapi/fpdf_page/include/cpdf_shadingobject.h" | 23 #include "core/fpdfapi/fpdf_page/include/cpdf_shadingobject.h" |
23 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" | 24 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" |
24 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 25 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
25 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 26 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
26 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 27 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
27 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" | 28 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
28 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" | 29 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" |
29 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" | 30 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" |
30 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 31 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
31 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 32 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
32 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" | 33 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
| 37 const int kSingleCoordinatePair = 1; |
| 38 const int kTensorCoordinatePairs = 16; |
| 39 const int kCoonsCoordinatePairs = 12; |
| 40 const int kSingleColorPerPatch = 1; |
| 41 const int kQuadColorsPerPatch = 4; |
| 42 |
36 const char kPathOperatorSubpath = 'm'; | 43 const char kPathOperatorSubpath = 'm'; |
37 const char kPathOperatorLine = 'l'; | 44 const char kPathOperatorLine = 'l'; |
38 const char kPathOperatorCubicBezier1 = 'c'; | 45 const char kPathOperatorCubicBezier1 = 'c'; |
39 const char kPathOperatorCubicBezier2 = 'v'; | 46 const char kPathOperatorCubicBezier2 = 'v'; |
40 const char kPathOperatorCubicBezier3 = 'y'; | 47 const char kPathOperatorCubicBezier3 = 'y'; |
41 const char kPathOperatorClosePath = 'h'; | 48 const char kPathOperatorClosePath = 'h'; |
42 const char kPathOperatorRectangle[] = "re"; | 49 const char kPathOperatorRectangle[] = "re"; |
43 | 50 |
44 struct PDF_AbbrPair { | 51 struct PDF_AbbrPair { |
45 const FX_CHAR* abbr; | 52 const FX_CHAR* abbr; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, | 90 CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, |
84 size_t count, | 91 size_t count, |
85 const CFX_ByteStringC& abbr) { | 92 const CFX_ByteStringC& abbr) { |
86 auto it = std::find_if( | 93 auto it = std::find_if( |
87 table, table + count, | 94 table, table + count, |
88 [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); | 95 [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); |
89 return it != table + count ? CFX_ByteStringC(it->full_name) | 96 return it != table + count ? CFX_ByteStringC(it->full_name) |
90 : CFX_ByteStringC(); | 97 : CFX_ByteStringC(); |
91 } | 98 } |
92 | 99 |
| 100 CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, |
| 101 ShadingType type, |
| 102 const CFX_Matrix& matrix, |
| 103 CPDF_Function** pFuncs, |
| 104 int nFuncs, |
| 105 CPDF_ColorSpace* pCS) { |
| 106 if (!pStream || !pFuncs || !pCS) |
| 107 return CFX_FloatRect(0, 0, 0, 0); |
| 108 |
| 109 CPDF_MeshStream stream; |
| 110 if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) |
| 111 return CFX_FloatRect(0, 0, 0, 0); |
| 112 |
| 113 CFX_FloatRect rect; |
| 114 bool bStarted = false; |
| 115 bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || |
| 116 type == kLatticeFormGouraudTriangleMeshShading; |
| 117 |
| 118 int point_count = kSingleCoordinatePair; |
| 119 if (type == kTensorProductPatchMeshShading) |
| 120 point_count = kTensorCoordinatePairs; |
| 121 else if (type == kCoonsPatchMeshShading) |
| 122 point_count = kCoonsCoordinatePairs; |
| 123 |
| 124 int color_count = kSingleColorPerPatch; |
| 125 if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) |
| 126 color_count = kQuadColorsPerPatch; |
| 127 |
| 128 while (!stream.m_BitStream.IsEOF()) { |
| 129 uint32_t flag = 0; |
| 130 if (type != kLatticeFormGouraudTriangleMeshShading) |
| 131 flag = stream.GetFlag(); |
| 132 |
| 133 if (!bGouraud && flag) { |
| 134 point_count -= 4; |
| 135 color_count -= 2; |
| 136 } |
| 137 |
| 138 for (int i = 0; i < point_count; i++) { |
| 139 FX_FLOAT x; |
| 140 FX_FLOAT y; |
| 141 stream.GetCoords(x, y); |
| 142 if (bStarted) { |
| 143 rect.UpdateRect(x, y); |
| 144 } else { |
| 145 rect.InitRect(x, y); |
| 146 bStarted = true; |
| 147 } |
| 148 } |
| 149 stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * |
| 150 color_count); |
| 151 if (bGouraud) |
| 152 stream.m_BitStream.ByteAlign(); |
| 153 } |
| 154 rect.Transform(&matrix); |
| 155 return rect; |
| 156 } |
| 157 |
93 } // namespace | 158 } // namespace |
94 | 159 |
95 CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { | 160 CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { |
96 return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), | 161 return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), |
97 abbr); | 162 abbr); |
98 } | 163 } |
99 | 164 |
100 CFX_ByteStringC PDF_FindValueAbbreviationForTesting( | 165 CFX_ByteStringC PDF_FindValueAbbreviationForTesting( |
101 const CFX_ByteStringC& abbr) { | 166 const CFX_ByteStringC& abbr) { |
102 return PDF_FindFullName(PDF_InlineValueAbbr, | 167 return PDF_FindFullName(PDF_InlineValueAbbr, |
(...skipping 14 matching lines...) Expand all Loading... |
117 return true; | 182 return true; |
118 } | 183 } |
119 } | 184 } |
120 return false; | 185 return false; |
121 } | 186 } |
122 | 187 |
123 CPDF_StreamContentParser::CPDF_StreamContentParser( | 188 CPDF_StreamContentParser::CPDF_StreamContentParser( |
124 CPDF_Document* pDocument, | 189 CPDF_Document* pDocument, |
125 CPDF_Dictionary* pPageResources, | 190 CPDF_Dictionary* pPageResources, |
126 CPDF_Dictionary* pParentResources, | 191 CPDF_Dictionary* pParentResources, |
127 CFX_Matrix* pmtContentToUser, | 192 const CFX_Matrix* pmtContentToUser, |
128 CPDF_PageObjectHolder* pObjHolder, | 193 CPDF_PageObjectHolder* pObjHolder, |
129 CPDF_Dictionary* pResources, | 194 CPDF_Dictionary* pResources, |
130 CFX_FloatRect* pBBox, | 195 CFX_FloatRect* pBBox, |
131 CPDF_AllStates* pStates, | 196 CPDF_AllStates* pStates, |
132 int level) | 197 int level) |
133 : m_pDocument(pDocument), | 198 : m_pDocument(pDocument), |
134 m_pPageResources(pPageResources), | 199 m_pPageResources(pPageResources), |
135 m_pParentResources(pParentResources), | 200 m_pParentResources(pParentResources), |
136 m_pResources(pResources), | 201 m_pResources(pResources), |
137 m_pObjectHolder(pObjHolder), | 202 m_pObjectHolder(pObjHolder), |
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 if (pLastParam->IsName()) | 1043 if (pLastParam->IsName()) |
979 nvalues--; | 1044 nvalues--; |
980 FX_FLOAT* values = NULL; | 1045 FX_FLOAT* values = NULL; |
981 if (nvalues) { | 1046 if (nvalues) { |
982 values = FX_Alloc(FX_FLOAT, nvalues); | 1047 values = FX_Alloc(FX_FLOAT, nvalues); |
983 for (uint32_t i = 0; i < nvalues; i++) { | 1048 for (uint32_t i = 0; i < nvalues; i++) { |
984 values[i] = GetNumber(nargs - i - 1); | 1049 values[i] = GetNumber(nargs - i - 1); |
985 } | 1050 } |
986 } | 1051 } |
987 if (nvalues != nargs) { | 1052 if (nvalues != nargs) { |
988 CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); | 1053 CPDF_Pattern* pPattern = FindPattern(GetString(0), false); |
989 if (pPattern) { | 1054 if (pPattern) { |
990 m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); | 1055 m_pCurStates->m_ColorState.SetFillPattern(pPattern, values, nvalues); |
991 } | 1056 } |
992 } else { | 1057 } else { |
993 m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues); | 1058 m_pCurStates->m_ColorState.SetFillColor(NULL, values, nvalues); |
994 } | 1059 } |
995 FX_Free(values); | 1060 FX_Free(values); |
996 } | 1061 } |
997 | 1062 |
998 void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { | 1063 void CPDF_StreamContentParser::Handle_SetColorPS_Stroke() { |
999 CPDF_Object* pLastParam = GetObject(0); | 1064 CPDF_Object* pLastParam = GetObject(0); |
1000 if (!pLastParam) { | 1065 if (!pLastParam) { |
1001 return; | 1066 return; |
1002 } | 1067 } |
1003 int nargs = m_ParamCount; | 1068 int nargs = m_ParamCount; |
1004 int nvalues = nargs; | 1069 int nvalues = nargs; |
1005 if (pLastParam->IsName()) | 1070 if (pLastParam->IsName()) |
1006 nvalues--; | 1071 nvalues--; |
1007 | 1072 |
1008 FX_FLOAT* values = NULL; | 1073 FX_FLOAT* values = NULL; |
1009 if (nvalues) { | 1074 if (nvalues) { |
1010 values = FX_Alloc(FX_FLOAT, nvalues); | 1075 values = FX_Alloc(FX_FLOAT, nvalues); |
1011 for (int i = 0; i < nvalues; i++) { | 1076 for (int i = 0; i < nvalues; i++) { |
1012 values[i] = GetNumber(nargs - i - 1); | 1077 values[i] = GetNumber(nargs - i - 1); |
1013 } | 1078 } |
1014 } | 1079 } |
1015 if (nvalues != nargs) { | 1080 if (nvalues != nargs) { |
1016 CPDF_Pattern* pPattern = FindPattern(GetString(0), FALSE); | 1081 CPDF_Pattern* pPattern = FindPattern(GetString(0), false); |
1017 if (pPattern) { | 1082 if (pPattern) { |
1018 m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); | 1083 m_pCurStates->m_ColorState.SetStrokePattern(pPattern, values, nvalues); |
1019 } | 1084 } |
1020 } else { | 1085 } else { |
1021 m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues); | 1086 m_pCurStates->m_ColorState.SetStrokeColor(NULL, values, nvalues); |
1022 } | 1087 } |
1023 FX_Free(values); | 1088 FX_Free(values); |
1024 } | 1089 } |
1025 | 1090 |
1026 CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, | |
1027 ShadingType type, | |
1028 const CFX_Matrix* pMatrix, | |
1029 CPDF_Function** pFuncs, | |
1030 int nFuncs, | |
1031 CPDF_ColorSpace* pCS); | |
1032 | |
1033 void CPDF_StreamContentParser::Handle_ShadeFill() { | 1091 void CPDF_StreamContentParser::Handle_ShadeFill() { |
1034 CPDF_Pattern* pPattern = FindPattern(GetString(0), TRUE); | 1092 CPDF_Pattern* pPattern = FindPattern(GetString(0), true); |
1035 if (!pPattern) | 1093 if (!pPattern) |
1036 return; | 1094 return; |
1037 | 1095 |
1038 CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); | 1096 CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); |
1039 if (!pShading) | 1097 if (!pShading) |
1040 return; | 1098 return; |
1041 | 1099 |
1042 if (!pShading->m_bShadingObj || !pShading->Load()) | 1100 if (!pShading->m_bShadingObj || !pShading->Load()) |
1043 return; | 1101 return; |
1044 | 1102 |
1045 std::unique_ptr<CPDF_ShadingObject> pObj(new CPDF_ShadingObject); | 1103 std::unique_ptr<CPDF_ShadingObject> pObj(new CPDF_ShadingObject); |
1046 pObj->m_pShading = pShading; | 1104 pObj->m_pShading = pShading; |
1047 SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); | 1105 SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); |
1048 pObj->m_Matrix = m_pCurStates->m_CTM; | 1106 pObj->m_Matrix = m_pCurStates->m_CTM; |
1049 pObj->m_Matrix.Concat(m_mtContentToUser); | 1107 pObj->m_Matrix.Concat(m_mtContentToUser); |
1050 CFX_FloatRect bbox = | 1108 CFX_FloatRect bbox = |
1051 pObj->m_ClipPath.IsNull() ? m_BBox : pObj->m_ClipPath.GetClipBox(); | 1109 pObj->m_ClipPath.IsNull() ? m_BBox : pObj->m_ClipPath.GetClipBox(); |
1052 if (pShading->IsMeshShading()) { | 1110 if (pShading->IsMeshShading()) { |
1053 bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), | 1111 bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), |
1054 pShading->m_ShadingType, &pObj->m_Matrix, | 1112 pShading->m_ShadingType, pObj->m_Matrix, |
1055 pShading->m_pFunctions, pShading->m_nFuncs, | 1113 pShading->m_pFunctions, pShading->m_nFuncs, |
1056 pShading->m_pCS)); | 1114 pShading->m_pCS)); |
1057 } | 1115 } |
1058 pObj->m_Left = bbox.left; | 1116 pObj->m_Left = bbox.left; |
1059 pObj->m_Right = bbox.right; | 1117 pObj->m_Right = bbox.right; |
1060 pObj->m_Top = bbox.top; | 1118 pObj->m_Top = bbox.top; |
1061 pObj->m_Bottom = bbox.bottom; | 1119 pObj->m_Bottom = bbox.bottom; |
1062 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); | 1120 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); |
1063 } | 1121 } |
1064 | 1122 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 } | 1215 } |
1158 CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name); | 1216 CPDF_Object* pCSObj = FindResourceObj("ColorSpace", name); |
1159 if (!pCSObj) { | 1217 if (!pCSObj) { |
1160 m_bResourceMissing = TRUE; | 1218 m_bResourceMissing = TRUE; |
1161 return NULL; | 1219 return NULL; |
1162 } | 1220 } |
1163 return m_pDocument->LoadColorSpace(pCSObj); | 1221 return m_pDocument->LoadColorSpace(pCSObj); |
1164 } | 1222 } |
1165 | 1223 |
1166 CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, | 1224 CPDF_Pattern* CPDF_StreamContentParser::FindPattern(const CFX_ByteString& name, |
1167 FX_BOOL bShading) { | 1225 bool bShading) { |
1168 CPDF_Object* pPattern = | 1226 CPDF_Object* pPattern = |
1169 FindResourceObj(bShading ? "Shading" : "Pattern", name); | 1227 FindResourceObj(bShading ? "Shading" : "Pattern", name); |
1170 if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { | 1228 if (!pPattern || (!pPattern->IsDictionary() && !pPattern->IsStream())) { |
1171 m_bResourceMissing = TRUE; | 1229 m_bResourceMissing = TRUE; |
1172 return NULL; | 1230 return nullptr; |
1173 } | 1231 } |
1174 return m_pDocument->LoadPattern(pPattern, bShading, | 1232 return m_pDocument->LoadPattern(pPattern, bShading, |
1175 &m_pCurStates->m_ParentMatrix); | 1233 m_pCurStates->m_ParentMatrix); |
1176 } | 1234 } |
1177 | 1235 |
1178 void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { | 1236 void CPDF_StreamContentParser::ConvertTextSpace(FX_FLOAT& x, FX_FLOAT& y) { |
1179 m_pCurStates->m_TextMatrix.Transform(x, y, x, y); | 1237 m_pCurStates->m_TextMatrix.Transform(x, y, x, y); |
1180 ConvertUserSpace(x, y); | 1238 ConvertUserSpace(x, y); |
1181 } | 1239 } |
1182 | 1240 |
1183 void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) { | 1241 void CPDF_StreamContentParser::ConvertUserSpace(FX_FLOAT& x, FX_FLOAT& y) { |
1184 m_pCurStates->m_CTM.Transform(x, y, x, y); | 1242 m_pCurStates->m_CTM.Transform(x, y, x, y); |
1185 m_mtContentToUser.Transform(x, y, x, y); | 1243 m_mtContentToUser.Transform(x, y, x, y); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 } else { | 1710 } else { |
1653 PDF_ReplaceAbbr(pElement); | 1711 PDF_ReplaceAbbr(pElement); |
1654 } | 1712 } |
1655 } | 1713 } |
1656 break; | 1714 break; |
1657 } | 1715 } |
1658 default: | 1716 default: |
1659 break; | 1717 break; |
1660 } | 1718 } |
1661 } | 1719 } |
OLD | NEW |