| Index: core/fpdfapi/fpdf_page/cpdf_clippath.cpp
|
| diff --git a/core/fpdfapi/fpdf_page/cpdf_clippath.cpp b/core/fpdfapi/fpdf_page/cpdf_clippath.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3a3300ae2f8fc62ce5a0df83f90786f5912b33ac
|
| --- /dev/null
|
| +++ b/core/fpdfapi/fpdf_page/cpdf_clippath.cpp
|
| @@ -0,0 +1,131 @@
|
| +// Copyright 2016 PDFium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
| +
|
| +#include "core/fpdfapi/fpdf_page/include/cpdf_clippath.h"
|
| +
|
| +#include "core/fpdfapi/fpdf_page/include/cpdf_textobject.h"
|
| +
|
| +#define FPDF_CLIPPATH_MAX_TEXTS 1024
|
| +
|
| +CFX_FloatRect CPDF_ClipPath::GetClipBox() const {
|
| + CFX_FloatRect rect;
|
| + FX_BOOL bStarted = FALSE;
|
| + int count = GetPathCount();
|
| + if (count) {
|
| + rect = GetPath(0).GetBoundingBox();
|
| + for (int i = 1; i < count; i++) {
|
| + CFX_FloatRect path_rect = GetPath(i).GetBoundingBox();
|
| + rect.Intersect(path_rect);
|
| + }
|
| + bStarted = TRUE;
|
| + }
|
| + count = GetTextCount();
|
| + if (count) {
|
| + CFX_FloatRect layer_rect;
|
| + FX_BOOL bLayerStarted = FALSE;
|
| + for (int i = 0; i < count; i++) {
|
| + CPDF_TextObject* pTextObj = GetText(i);
|
| + if (!pTextObj) {
|
| + if (!bStarted) {
|
| + rect = layer_rect;
|
| + bStarted = TRUE;
|
| + } else {
|
| + rect.Intersect(layer_rect);
|
| + }
|
| + bLayerStarted = FALSE;
|
| + } else {
|
| + if (!bLayerStarted) {
|
| + layer_rect = CFX_FloatRect(pTextObj->GetBBox(nullptr));
|
| + bLayerStarted = TRUE;
|
| + } else {
|
| + layer_rect.Union(CFX_FloatRect(pTextObj->GetBBox(nullptr)));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return rect;
|
| +}
|
| +
|
| +void CPDF_ClipPath::AppendPath(CPDF_Path path, int type, FX_BOOL bAutoMerge) {
|
| + CPDF_ClipPathData* pData = GetModify();
|
| + if (pData->m_PathCount && bAutoMerge) {
|
| + CPDF_Path old_path = pData->m_pPathList[pData->m_PathCount - 1];
|
| + if (old_path.IsRect()) {
|
| + CFX_FloatRect old_rect(old_path.GetPointX(0), old_path.GetPointY(0),
|
| + old_path.GetPointX(2), old_path.GetPointY(2));
|
| + CFX_FloatRect new_rect = path.GetBoundingBox();
|
| + if (old_rect.Contains(new_rect)) {
|
| + pData->m_PathCount--;
|
| + pData->m_pPathList[pData->m_PathCount].SetNull();
|
| + }
|
| + }
|
| + }
|
| + if (pData->m_PathCount % 8 == 0) {
|
| + CPDF_Path* pNewPath = new CPDF_Path[pData->m_PathCount + 8];
|
| + for (int i = 0; i < pData->m_PathCount; i++) {
|
| + pNewPath[i] = pData->m_pPathList[i];
|
| + }
|
| + delete[] pData->m_pPathList;
|
| + uint8_t* pNewType = FX_Alloc(uint8_t, pData->m_PathCount + 8);
|
| + FXSYS_memcpy(pNewType, pData->m_pTypeList, pData->m_PathCount);
|
| + FX_Free(pData->m_pTypeList);
|
| + pData->m_pPathList = pNewPath;
|
| + pData->m_pTypeList = pNewType;
|
| + }
|
| + pData->m_pPathList[pData->m_PathCount] = path;
|
| + pData->m_pTypeList[pData->m_PathCount] = (uint8_t)type;
|
| + pData->m_PathCount++;
|
| +}
|
| +
|
| +void CPDF_ClipPath::DeletePath(int index) {
|
| + CPDF_ClipPathData* pData = GetModify();
|
| + if (index >= pData->m_PathCount) {
|
| + return;
|
| + }
|
| + pData->m_pPathList[index].SetNull();
|
| + for (int i = index; i < pData->m_PathCount - 1; i++) {
|
| + pData->m_pPathList[i] = pData->m_pPathList[i + 1];
|
| + }
|
| + pData->m_pPathList[pData->m_PathCount - 1].SetNull();
|
| + FXSYS_memmove(pData->m_pTypeList + index, pData->m_pTypeList + index + 1,
|
| + pData->m_PathCount - index - 1);
|
| + pData->m_PathCount--;
|
| +}
|
| +
|
| +void CPDF_ClipPath::AppendTexts(CPDF_TextObject** pTexts, int count) {
|
| + CPDF_ClipPathData* pData = GetModify();
|
| + if (pData->m_TextCount + count > FPDF_CLIPPATH_MAX_TEXTS) {
|
| + for (int i = 0; i < count; i++) {
|
| + delete pTexts[i];
|
| + }
|
| + return;
|
| + }
|
| + CPDF_TextObject** pNewList =
|
| + FX_Alloc(CPDF_TextObject*, pData->m_TextCount + count + 1);
|
| + if (pData->m_pTextList) {
|
| + FXSYS_memcpy(pNewList, pData->m_pTextList,
|
| + pData->m_TextCount * sizeof(CPDF_TextObject*));
|
| + FX_Free(pData->m_pTextList);
|
| + }
|
| + pData->m_pTextList = pNewList;
|
| + for (int i = 0; i < count; i++) {
|
| + pData->m_pTextList[pData->m_TextCount + i] = pTexts[i];
|
| + }
|
| + pData->m_pTextList[pData->m_TextCount + count] = NULL;
|
| + pData->m_TextCount += count + 1;
|
| +}
|
| +
|
| +void CPDF_ClipPath::Transform(const CFX_Matrix& matrix) {
|
| + CPDF_ClipPathData* pData = GetModify();
|
| + int i;
|
| + for (i = 0; i < pData->m_PathCount; i++) {
|
| + pData->m_pPathList[i].Transform(&matrix);
|
| + }
|
| + for (i = 0; i < pData->m_TextCount; i++)
|
| + if (pData->m_pTextList[i]) {
|
| + pData->m_pTextList[i]->Transform(matrix);
|
| + }
|
| +}
|
|
|