| OLD | NEW |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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/include/cpdf_clippath.h" | 7 #include "core/fpdfapi/fpdf_page/include/cpdf_clippath.h" |
| 8 | 8 |
| 9 #include <utility> |
| 10 |
| 9 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" | 11 #include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h" |
| 12 #include "third_party/base/stl_util.h" |
| 10 | 13 |
| 11 #define FPDF_CLIPPATH_MAX_TEXTS 1024 | 14 #define FPDF_CLIPPATH_MAX_TEXTS 1024 |
| 12 | 15 |
| 16 uint32_t CPDF_ClipPath::GetPathCount() const { |
| 17 return pdfium::CollectionSize<uint32_t>(m_pObject->m_PathAndTypeList); |
| 18 } |
| 19 |
| 20 CPDF_Path CPDF_ClipPath::GetPath(size_t i) const { |
| 21 return m_pObject->m_PathAndTypeList[i].first; |
| 22 } |
| 23 |
| 24 uint8_t CPDF_ClipPath::GetClipType(size_t i) const { |
| 25 return m_pObject->m_PathAndTypeList[i].second; |
| 26 } |
| 27 |
| 28 uint32_t CPDF_ClipPath::GetTextCount() const { |
| 29 return pdfium::CollectionSize<uint32_t>(m_pObject->m_TextList); |
| 30 } |
| 31 |
| 32 CPDF_TextObject* CPDF_ClipPath::GetText(size_t i) const { |
| 33 return m_pObject->m_TextList[i].get(); |
| 34 } |
| 35 |
| 13 CFX_FloatRect CPDF_ClipPath::GetClipBox() const { | 36 CFX_FloatRect CPDF_ClipPath::GetClipBox() const { |
| 14 CFX_FloatRect rect; | 37 CFX_FloatRect rect; |
| 15 FX_BOOL bStarted = FALSE; | 38 FX_BOOL bStarted = FALSE; |
| 16 int count = GetPathCount(); | 39 int count = GetPathCount(); |
| 17 if (count) { | 40 if (count) { |
| 18 rect = GetPath(0).GetBoundingBox(); | 41 rect = GetPath(0).GetBoundingBox(); |
| 19 for (int i = 1; i < count; i++) { | 42 for (int i = 1; i < count; i++) { |
| 20 CFX_FloatRect path_rect = GetPath(i).GetBoundingBox(); | 43 CFX_FloatRect path_rect = GetPath(i).GetBoundingBox(); |
| 21 rect.Intersect(path_rect); | 44 rect.Intersect(path_rect); |
| 22 } | 45 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 42 bLayerStarted = TRUE; | 65 bLayerStarted = TRUE; |
| 43 } else { | 66 } else { |
| 44 layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr))); | 67 layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr))); |
| 45 } | 68 } |
| 46 } | 69 } |
| 47 } | 70 } |
| 48 } | 71 } |
| 49 return rect; | 72 return rect; |
| 50 } | 73 } |
| 51 | 74 |
| 52 void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) { | 75 void CPDF_ClipPath::AppendPath(CPDF_Path path, uint8_t type, bool bAutoMerge) { |
| 53 CPDF_ClipPathData* pData = GetModify(); | 76 CPDF_ClipPathData* pData = GetModify(); |
| 54 if (pData->m_PathCount && bAutoMerge) { | 77 if (!pData->m_PathAndTypeList.empty() && bAutoMerge) { |
| 55 CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1]; | 78 const CPDF_Path& old_path = pData->m_PathAndTypeList.back().first; |
| 56 if (old_path.IsRect()) { | 79 if (old_path.IsRect()) { |
| 57 CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), | 80 CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0), |
| 58 old_path.GetPointX(2), old_path.GetPointY(2)); | 81 old_path.GetPointX(2), old_path.GetPointY(2)); |
| 59 CFX_FloatRect new_rect = path.GetBoundingBox(); | 82 CFX_FloatRect new_rect = path.GetBoundingBox(); |
| 60 if (old_rect.Contains(new_rect)) { | 83 if (old_rect.Contains(new_rect)) |
| 61 pData->m_PathCount--; | 84 pData->m_PathAndTypeList.pop_back(); |
| 62 pData->m_pPathList[pData->m_PathCount].SetNull(); | |
| 63 } | |
| 64 } | 85 } |
| 65 } | 86 } |
| 66 if (pData->m_PathCount % 8 == 0) { | 87 pData->m_PathAndTypeList.push_back(std::make_pair(path, type)); |
| 67 CPDF_Path* pNewPath = new CPDF_Path[pData->m_PathCount + 8]; | |
| 68 for (int i = 0; i < pData->m_PathCount; i++) { | |
| 69 pNewPath[i] = pData->m_pPathList[i]; | |
| 70 } | |
| 71 delete[] pData->m_pPathList; | |
| 72 uint8_t* pNewType = FX_Alloc(uint8_t, pData->m_PathCount + 8); | |
| 73 FXSYS_memcpy(pNewType, pData->m_pTypeList, pData->m_PathCount); | |
| 74 FX_Free(pData->m_pTypeList); | |
| 75 pData->m_pPathList = pNewPath; | |
| 76 pData->m_pTypeList = pNewType; | |
| 77 } | |
| 78 pData->m_pPathList[pData->m_PathCount] = path; | |
| 79 pData->m_pTypeList[pData->m_PathCount] = (uint8_t)type; | |
| 80 pData->m_PathCount++; | |
| 81 } | 88 } |
| 82 | 89 |
| 83 void CPDF_ClipPath::DeletePath(int index) { | 90 void CPDF_ClipPath::AppendTexts( |
| 91 std::vector<std::unique_ptr<CPDF_TextObject>>* pTexts) { |
| 84 CPDF_ClipPathData* pData = GetModify(); | 92 CPDF_ClipPathData* pData = GetModify(); |
| 85 if (index >= pData->m_PathCount) { | 93 if (pData->m_TextList.size() + pTexts->size() <= FPDF_CLIPPATH_MAX_TEXTS) { |
| 86 return; | 94 for (size_t i = 0; i < pTexts->size(); i++) |
| 95 pData->m_TextList.push_back(std::move((*pTexts)[i])); |
| 96 pData->m_TextList.push_back(std::unique_ptr<CPDF_TextObject>()); |
| 87 } | 97 } |
| 88 pData->m_pPathList[index].SetNull(); | 98 pTexts->clear(); |
| 89 for (int i = index; i < pData->m_PathCount - 1; i++) { | |
| 90 pData->m_pPathList[i] = pData->m_pPathList[i + 1]; | |
| 91 } | |
| 92 pData->m_pPathList[pData->m_PathCount - 1].SetNull(); | |
| 93 FXSYS_memmove(pData->m_pTypeList + index, pData->m_pTypeList + index + 1, | |
| 94 pData->m_PathCount - index - 1); | |
| 95 pData->m_PathCount--; | |
| 96 } | |
| 97 | |
| 98 void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count) { | |
| 99 CPDF_ClipPathData* pData = GetModify(); | |
| 100 if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) { | |
| 101 for (int i = 0; i < count; i++) { | |
| 102 delete pTexts[i]; | |
| 103 } | |
| 104 return; | |
| 105 } | |
| 106 CPDF_TextObject** pNewList = | |
| 107 FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1); | |
| 108 if (pData->m_pTextList) { | |
| 109 FXSYS_memcpy(pNewList, pData->m_pTextList, | |
| 110 pData->m_TextCount * sizeof(CPDF_TextObject*)); | |
| 111 FX_Free(pData->m_pTextList); | |
| 112 } | |
| 113 pData->m_pTextList = pNewList; | |
| 114 for (int i = 0; i < count; i++) { | |
| 115 pData->m_pTextList[pData->m_TextCount + i] = pTexts[i]; | |
| 116 } | |
| 117 pData->m_pTextList[pData->m_TextCount + count] = NULL; | |
| 118 pData->m_TextCount += count + 1; | |
| 119 } | 99 } |
| 120 | 100 |
| 121 void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) { | 101 void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) { |
| 122 CPDF_ClipPathData* pData = GetModify(); | 102 CPDF_ClipPathData* pData = GetModify(); |
| 123 int i; | 103 for (auto& obj : pData->m_PathAndTypeList) |
| 124 for (i = 0; i < pData->m_PathCount; i++) { | 104 obj.first.Transform(&matrix); |
| 125 pData->m_pPathList[i].Transform(&matrix); | 105 for (auto& text : pData->m_TextList) { |
| 106 if (text) |
| 107 text->Transform(matrix); |
| 126 } | 108 } |
| 127 for (i = 0; i < pData->m_TextCount; i++) | |
| 128 if (pData->m_pTextList[i]) { | |
| 129 pData->m_pTextList[i]->Transform(matrix); | |
| 130 } | |
| 131 } | 109 } |
| OLD | NEW |