| 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 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" | 24 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" |
| 25 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | 25 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 26 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" | 26 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" |
| 27 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 27 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 28 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" | 28 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
| 29 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" | 29 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" |
| 30 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" | 30 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" |
| 31 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 31 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
| 32 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" | 32 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" |
| 33 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" | 33 #include "core/fpdfapi/fpdf_parser/include/fpdf_parser_decode.h" |
| 34 #include "core/fxcrt/include/fx_safe_types.h" |
| 34 | 35 |
| 35 namespace { | 36 namespace { |
| 36 | 37 |
| 37 const int kSingleCoordinatePair = 1; | 38 const int kSingleCoordinatePair = 1; |
| 38 const int kTensorCoordinatePairs = 16; | 39 const int kTensorCoordinatePairs = 16; |
| 39 const int kCoonsCoordinatePairs = 12; | 40 const int kCoonsCoordinatePairs = 12; |
| 40 const int kSingleColorPerPatch = 1; | 41 const int kSingleColorPerPatch = 1; |
| 41 const int kQuadColorsPerPatch = 4; | 42 const int kQuadColorsPerPatch = 4; |
| 42 | 43 |
| 43 const char kPathOperatorSubpath = 'm'; | 44 const char kPathOperatorSubpath = 'm'; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, | 91 CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPair* table, |
| 91 size_t count, | 92 size_t count, |
| 92 const CFX_ByteStringC& abbr) { | 93 const CFX_ByteStringC& abbr) { |
| 93 auto it = std::find_if( | 94 auto it = std::find_if( |
| 94 table, table + count, | 95 table, table + count, |
| 95 [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); | 96 [abbr](const PDF_AbbrPair& pair) { return pair.abbr == abbr; }); |
| 96 return it != table + count ? CFX_ByteStringC(it->full_name) | 97 return it != table + count ? CFX_ByteStringC(it->full_name) |
| 97 : CFX_ByteStringC(); | 98 : CFX_ByteStringC(); |
| 98 } | 99 } |
| 99 | 100 |
| 100 CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream, | 101 CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading, |
| 101 ShadingType type, | 102 const CFX_Matrix& matrix) { |
| 102 const CFX_Matrix& matrix, | 103 ShadingType type = pShading->GetShadingType(); |
| 103 CPDF_Function** pFuncs, | 104 CPDF_Stream* pStream = ToStream(pShading->GetShadingObject()); |
| 104 int nFuncs, | 105 CPDF_ColorSpace* pCS = pShading->GetCS(); |
| 105 CPDF_ColorSpace* pCS) { | 106 if (!pStream || !pCS) |
| 106 if (!pStream || !pFuncs || !pCS) | |
| 107 return CFX_FloatRect(0, 0, 0, 0); | 107 return CFX_FloatRect(0, 0, 0, 0); |
| 108 | 108 |
| 109 CPDF_MeshStream stream; | 109 CPDF_MeshStream stream(pShading->GetFuncs(), pCS); |
| 110 if (!stream.Load(pStream, pFuncs, nFuncs, pCS)) | 110 if (!stream.Load(pStream)) |
| 111 return CFX_FloatRect(0, 0, 0, 0); | 111 return CFX_FloatRect(0, 0, 0, 0); |
| 112 | 112 |
| 113 CFX_FloatRect rect; | 113 CFX_FloatRect rect; |
| 114 bool bStarted = false; | 114 bool bStarted = false; |
| 115 bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || | 115 bool bGouraud = type == kFreeFormGouraudTriangleMeshShading || |
| 116 type == kLatticeFormGouraudTriangleMeshShading; | 116 type == kLatticeFormGouraudTriangleMeshShading; |
| 117 | 117 |
| 118 int point_count = kSingleCoordinatePair; | 118 int point_count = kSingleCoordinatePair; |
| 119 if (type == kTensorProductPatchMeshShading) | 119 if (type == kTensorProductPatchMeshShading) |
| 120 point_count = kTensorCoordinatePairs; | 120 point_count = kTensorCoordinatePairs; |
| 121 else if (type == kCoonsPatchMeshShading) | 121 else if (type == kCoonsPatchMeshShading) |
| 122 point_count = kCoonsCoordinatePairs; | 122 point_count = kCoonsCoordinatePairs; |
| 123 | 123 |
| 124 int color_count = kSingleColorPerPatch; | 124 int color_count = kSingleColorPerPatch; |
| 125 if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) | 125 if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading) |
| 126 color_count = kQuadColorsPerPatch; | 126 color_count = kQuadColorsPerPatch; |
| 127 | 127 |
| 128 while (!stream.m_BitStream.IsEOF()) { | 128 while (!stream.BitStream()->IsEOF()) { |
| 129 uint32_t flag = 0; | 129 uint32_t flag = 0; |
| 130 if (type != kLatticeFormGouraudTriangleMeshShading) | 130 if (type != kLatticeFormGouraudTriangleMeshShading) |
| 131 flag = stream.GetFlag(); | 131 flag = stream.GetFlag(); |
| 132 | 132 |
| 133 if (!bGouraud && flag) { | 133 if (!bGouraud && flag) { |
| 134 point_count -= 4; | 134 point_count -= 4; |
| 135 color_count -= 2; | 135 color_count -= 2; |
| 136 } | 136 } |
| 137 | 137 |
| 138 for (int i = 0; i < point_count; i++) { | 138 for (int i = 0; i < point_count; i++) { |
| 139 FX_FLOAT x; | 139 FX_FLOAT x; |
| 140 FX_FLOAT y; | 140 FX_FLOAT y; |
| 141 stream.GetCoords(x, y); | 141 stream.GetCoords(x, y); |
| 142 if (bStarted) { | 142 if (bStarted) { |
| 143 rect.UpdateRect(x, y); | 143 rect.UpdateRect(x, y); |
| 144 } else { | 144 } else { |
| 145 rect.InitRect(x, y); | 145 rect.InitRect(x, y); |
| 146 bStarted = true; | 146 bStarted = true; |
| 147 } | 147 } |
| 148 } | 148 } |
| 149 stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits * | 149 FX_SAFE_UINT32 nBits = stream.comps(); |
| 150 color_count); | 150 nBits *= stream.CompBits(); |
| 151 nBits *= color_count; |
| 152 if (!nBits.IsValid()) |
| 153 break; |
| 154 |
| 155 stream.BitStream()->SkipBits(nBits.ValueOrDie()); |
| 151 if (bGouraud) | 156 if (bGouraud) |
| 152 stream.m_BitStream.ByteAlign(); | 157 stream.BitStream()->ByteAlign(); |
| 153 } | 158 } |
| 154 rect.Transform(&matrix); | 159 rect.Transform(&matrix); |
| 155 return rect; | 160 return rect; |
| 156 } | 161 } |
| 157 | 162 |
| 158 } // namespace | 163 } // namespace |
| 159 | 164 |
| 160 CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { | 165 CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr) { |
| 161 return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), | 166 return PDF_FindFullName(PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), |
| 162 abbr); | 167 abbr); |
| 163 } | 168 } |
| 164 | 169 |
| 165 CFX_ByteStringC PDF_FindValueAbbreviationForTesting( | 170 CFX_ByteStringC PDF_FindValueAbbreviationForTesting( |
| 166 const CFX_ByteStringC& abbr) { | 171 const CFX_ByteStringC& abbr) { |
| 167 return PDF_FindFullName(PDF_InlineValueAbbr, | 172 return PDF_FindFullName(PDF_InlineValueAbbr, |
| 168 FX_ArraySize(PDF_InlineValueAbbr), abbr); | 173 FX_ArraySize(PDF_InlineValueAbbr), abbr); |
| 169 } | 174 } |
| 170 | 175 |
| 171 bool IsPathOperator(const uint8_t* buf, size_t len) { | 176 bool IsPathOperator(const uint8_t* buf, size_t len) { |
| 172 if (len == 1) { | 177 if (len == 1) { |
| 173 uint8_t op = buf[0]; | 178 uint8_t op = buf[0]; |
| 174 if (op == kPathOperatorSubpath || op == kPathOperatorLine || | 179 return op == kPathOperatorSubpath || op == kPathOperatorLine || |
| 175 op == kPathOperatorCubicBezier1 || op == kPathOperatorCubicBezier2 || | 180 op == kPathOperatorCubicBezier1 || op == kPathOperatorCubicBezier2 || |
| 176 op == kPathOperatorCubicBezier3) { | 181 op == kPathOperatorCubicBezier3; |
| 177 return true; | 182 } |
| 178 } | 183 if (len == 2) { |
| 179 } else if (len == 2) { | 184 return buf[0] == kPathOperatorRectangle[0] && |
| 180 if (buf[0] == kPathOperatorRectangle[0] && | 185 buf[1] == kPathOperatorRectangle[1]; |
| 181 buf[1] == kPathOperatorRectangle[1]) { | |
| 182 return true; | |
| 183 } | |
| 184 } | 186 } |
| 185 return false; | 187 return false; |
| 186 } | 188 } |
| 187 | 189 |
| 188 CPDF_StreamContentParser::CPDF_StreamContentParser( | 190 CPDF_StreamContentParser::CPDF_StreamContentParser( |
| 189 CPDF_Document* pDocument, | 191 CPDF_Document* pDocument, |
| 190 CPDF_Dictionary* pPageResources, | 192 CPDF_Dictionary* pPageResources, |
| 191 CPDF_Dictionary* pParentResources, | 193 CPDF_Dictionary* pParentResources, |
| 192 const CFX_Matrix* pmtContentToUser, | 194 const CFX_Matrix* pmtContentToUser, |
| 193 CPDF_PageObjectHolder* pObjHolder, | 195 CPDF_PageObjectHolder* pObjHolder, |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1080 | 1082 |
| 1081 void CPDF_StreamContentParser::Handle_ShadeFill() { | 1083 void CPDF_StreamContentParser::Handle_ShadeFill() { |
| 1082 CPDF_Pattern* pPattern = FindPattern(GetString(0), true); | 1084 CPDF_Pattern* pPattern = FindPattern(GetString(0), true); |
| 1083 if (!pPattern) | 1085 if (!pPattern) |
| 1084 return; | 1086 return; |
| 1085 | 1087 |
| 1086 CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); | 1088 CPDF_ShadingPattern* pShading = pPattern->AsShadingPattern(); |
| 1087 if (!pShading) | 1089 if (!pShading) |
| 1088 return; | 1090 return; |
| 1089 | 1091 |
| 1090 if (!pShading->m_bShadingObj || !pShading->Load()) | 1092 if (!pShading->IsShadingObject() || !pShading->Load()) |
| 1091 return; | 1093 return; |
| 1092 | 1094 |
| 1093 std::unique_ptr<CPDF_ShadingObject> pObj(new CPDF_ShadingObject); | 1095 std::unique_ptr<CPDF_ShadingObject> pObj(new CPDF_ShadingObject); |
| 1094 pObj->m_pShading = pShading; | 1096 pObj->m_pShading = pShading; |
| 1095 SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); | 1097 SetGraphicStates(pObj.get(), FALSE, FALSE, FALSE); |
| 1096 pObj->m_Matrix = m_pCurStates->m_CTM; | 1098 pObj->m_Matrix = m_pCurStates->m_CTM; |
| 1097 pObj->m_Matrix.Concat(m_mtContentToUser); | 1099 pObj->m_Matrix.Concat(m_mtContentToUser); |
| 1098 CFX_FloatRect bbox = | 1100 CFX_FloatRect bbox = |
| 1099 pObj->m_ClipPath.IsNull() ? m_BBox : pObj->m_ClipPath.GetClipBox(); | 1101 pObj->m_ClipPath.IsNull() ? m_BBox : pObj->m_ClipPath.GetClipBox(); |
| 1100 if (pShading->IsMeshShading()) { | 1102 if (pShading->IsMeshShading()) |
| 1101 bbox.Intersect(GetShadingBBox(ToStream(pShading->m_pShadingObj), | 1103 bbox.Intersect(GetShadingBBox(pShading, pObj->m_Matrix)); |
| 1102 pShading->m_ShadingType, pObj->m_Matrix, | |
| 1103 pShading->m_pFunctions, pShading->m_nFuncs, | |
| 1104 pShading->m_pCS)); | |
| 1105 } | |
| 1106 pObj->m_Left = bbox.left; | 1104 pObj->m_Left = bbox.left; |
| 1107 pObj->m_Right = bbox.right; | 1105 pObj->m_Right = bbox.right; |
| 1108 pObj->m_Top = bbox.top; | 1106 pObj->m_Top = bbox.top; |
| 1109 pObj->m_Bottom = bbox.bottom; | 1107 pObj->m_Bottom = bbox.bottom; |
| 1110 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); | 1108 m_pObjectHolder->GetPageObjectList()->push_back(std::move(pObj)); |
| 1111 } | 1109 } |
| 1112 | 1110 |
| 1113 void CPDF_StreamContentParser::Handle_SetCharSpace() { | 1111 void CPDF_StreamContentParser::Handle_SetCharSpace() { |
| 1114 m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0); | 1112 m_pCurStates->m_TextState.GetModify()->m_CharSpace = GetNumber(0); |
| 1115 } | 1113 } |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1698 } else { | 1696 } else { |
| 1699 PDF_ReplaceAbbr(pElement); | 1697 PDF_ReplaceAbbr(pElement); |
| 1700 } | 1698 } |
| 1701 } | 1699 } |
| 1702 break; | 1700 break; |
| 1703 } | 1701 } |
| 1704 default: | 1702 default: |
| 1705 break; | 1703 break; |
| 1706 } | 1704 } |
| 1707 } | 1705 } |
| OLD | NEW |