7#include "core/fpdfdoc/cpdf_annot.h"
12#include "constants/annotation_common.h"
13#include "constants/annotation_flags.h"
14#include "core/fpdfapi/page/cpdf_form.h"
15#include "core/fpdfapi/page/cpdf_page.h"
16#include "core/fpdfapi/page/cpdf_pageimagecache.h"
17#include "core/fpdfapi/parser/cpdf_array.h"
18#include "core/fpdfapi/parser/cpdf_boolean.h"
19#include "core/fpdfapi/parser/cpdf_dictionary.h"
20#include "core/fpdfapi/parser/cpdf_document.h"
21#include "core/fpdfapi/parser/cpdf_stream.h"
22#include "core/fpdfapi/parser/fpdf_parser_utility.h"
23#include "core/fpdfapi/render/cpdf_rendercontext.h"
24#include "core/fpdfapi/render/cpdf_renderoptions.h"
25#include "core/fpdfdoc/cpdf_generateap.h"
26#include "core/fxge/cfx_fillrenderoptions.h"
27#include "core/fxge/cfx_graphstatedata.h"
28#include "core/fxge/cfx_path.h"
29#include "core/fxge/cfx_renderdevice.h"
30#include "third_party/base/check.h"
34const char kPDFiumKey_HasGeneratedAP[] =
"PDFIUM_HasGeneratedAP";
43CPDF_Form* AnnotGetMatrix(CPDF_Page* pPage,
52 CFX_Matrix form_matrix = pForm->GetDict()->GetMatrixFor(
"Matrix");
54 form_matrix.TransformRect(pForm->GetDict()->GetRectFor(
"BBox"));
75RetainPtr<CPDF_Stream> GetAnnotAPInternal(CPDF_Dictionary* pAnnotDict,
77 bool bFallbackToNormal) {
79 pAnnotDict->GetMutableDictFor(pdfium::annotation::kAP);
83 const char* ap_entry =
"N";
88 if (bFallbackToNormal && !pAP->KeyExist(ap_entry))
95 RetainPtr<CPDF_Stream> pStream(psub->AsMutableStream());
99 CPDF_Dictionary* pDict = psub->AsMutableDictionary();
107 RetainPtr<
const CPDF_Dictionary> pParentDict =
108 pAnnotDict->GetDictFor(
"Parent");
109 value = pParentDict ? pParentDict->GetByteStringFor(
"V") : ByteString
();
124 m_bIsTextMarkupAnnotation(IsTextMarkupAnnotation(m_nSubtype)),
127 GenerateAPIfNeeded();
135 if (!ShouldGenerateAP())
137 if (!CPDF_GenerateAP::GenerateAnnotAP(m_pDocument, m_pAnnotDict.Get(),
142 m_pAnnotDict->SetNewFor<CPDF_Boolean>(kPDFiumKey_HasGeneratedAP,
true);
143 m_bHasGeneratedAP =
true;
150 m_pAnnotDict->GetDictFor(pdfium::annotation::kAP);
151 if (pAP && pAP->GetDictFor(
"N"))
157bool CPDF_Annot::ShouldDrawAnnotation()
const {
172 bool bShouldUseQuadPointsCoords =
173 m_bIsTextMarkupAnnotation && m_bHasGeneratedAP;
174 if (bShouldUseQuadPointsCoords)
175 return BoundingRectFromQuadPoints(m_pAnnotDict.Get());
176 return m_pAnnotDict->GetRectFor(pdfium::annotation::kRect);
186 return m_pAnnotDict->GetIntegerFor(pdfium::annotation::kF);
196 return GetAnnotAPInternal(pAnnotDict, eMode,
true);
202 return GetAnnotAPInternal(pAnnotDict, eMode,
false);
206 RetainPtr<CPDF_Stream> pStream = GetAnnotAP(m_pAnnotDict.Get(), mode);
210 auto it = m_APMap.find(pStream);
211 if (it != m_APMap.end())
212 return it->second.get();
214 auto pNewForm = std::make_unique<CPDF_Form>(
215 m_pDocument, pPage->GetMutableResources(), pStream);
216 pNewForm->ParseContent();
218 CPDF_Form* pResult = pNewForm.get();
219 m_APMap[pStream] = std::move(pNewForm);
225 m_pPopupAnnot->SetOpenState(bOpenState);
230 return absl::nullopt;
231 return m_pPopupAnnot->GetRect();
238 DCHECK(nIndex < pArray->size() / 8);
252 pArray->GetFloatAt(4 + nIndex * 8), pArray->GetFloatAt(5 + nIndex * 8),
253 pArray->GetFloatAt(2 + nIndex * 8), pArray->GetFloatAt(3 + nIndex * 8));
258 const CPDF_Dictionary* pAnnotDict) {
260 RetainPtr<
const CPDF_Array> pArray = pAnnotDict->GetArrayFor(
"QuadPoints");
261 size_t nQuadPointCount = pArray ? QuadPointCount(pArray.Get()) : 0;
262 if (nQuadPointCount == 0)
265 ret = RectFromQuadPointsArray(pArray.Get(), 0);
266 for (size_t i = 1; i < nQuadPointCount; ++i) {
267 CFX_FloatRect rect = RectFromQuadPointsArray(pArray.Get(), i);
276 RetainPtr<
const CPDF_Array> pArray = pAnnotDict->GetArrayFor(
"QuadPoints");
277 size_t nQuadPointCount = pArray ? QuadPointCount(pArray.Get()) : 0;
278 if (nIndex >= nQuadPointCount)
280 return RectFromQuadPointsArray(pArray.Get(), nIndex);
285 const ByteString& sSubtype) {
286 if (sSubtype
== "Text")
288 if (sSubtype
== "Link")
290 if (sSubtype
== "FreeText")
292 if (sSubtype
== "Line")
294 if (sSubtype
== "Square")
296 if (sSubtype
== "Circle")
298 if (sSubtype
== "Polygon")
300 if (sSubtype
== "PolyLine")
302 if (sSubtype
== "Highlight")
304 if (sSubtype
== "Underline")
306 if (sSubtype
== "Squiggly")
308 if (sSubtype
== "StrikeOut")
310 if (sSubtype
== "Stamp")
312 if (sSubtype
== "Caret")
314 if (sSubtype
== "Ink")
316 if (sSubtype
== "Popup")
318 if (sSubtype
== "FileAttachment")
320 if (sSubtype
== "Sound")
322 if (sSubtype
== "Movie")
324 if (sSubtype
== "Widget")
326 if (sSubtype
== "Screen")
328 if (sSubtype
== "PrinterMark")
330 if (sSubtype
== "TrapNet")
332 if (sSubtype
== "Watermark")
334 if (sSubtype
== "3D")
336 if (sSubtype
== "RichMedia")
338 if (sSubtype
== "XFAWidget")
340 if (sSubtype
== "Redact")
380 return "FileAttachment";
390 return "PrinterMark";
408 return pArray->size() / 8;
415 if (!ShouldDrawAnnotation())
423 GenerateAPIfNeeded();
426 CPDF_Form* pForm = AnnotGetMatrix(pPage,
this, mode, mtUser2Device, &matrix);
431 pPage->GetMutablePageResources(),
442 if (!ShouldDrawAnnotation())
450 GenerateAPIfNeeded();
453 CPDF_Form* pForm = AnnotGetMatrix(pPage,
this, mode, mtUser2Device, &matrix);
477 RetainPtr<
const CPDF_Dictionary> pBS = m_pAnnotDict->GetDictFor(
"BS");
482 RetainPtr<
const CPDF_Array> pBorderArray =
483 m_pAnnotDict->GetArrayFor(pdfium::annotation::kBorder);
486 width = pBorderArray->GetFloatAt(2);
487 if (pBorderArray->size() == 4) {
488 pDashArray = pBorderArray->GetArrayAt(3);
492 size_t nLen = pDashArray->size();
494 for (; i < nLen; ++i) {
496 if (pObj && pObj->GetInteger()) {
509 ByteString style = pBS->GetByteStringFor(
"S");
510 pDashArray = pBS->GetArrayFor(
"D");
511 style_char = style
[0
];
512 width = pBS->GetFloatFor(
"W");
518 m_pAnnotDict->GetArrayFor(pdfium::annotation::kC);
519 uint32_t argb = 0xff000000;
521 int R =
static_cast<int32_t>(pColor->GetFloatAt(0) * 255);
522 int G =
static_cast<int32_t>(pColor->GetFloatAt(1) * 255);
523 int B =
static_cast<int32_t>(pColor->GetFloatAt(2) * 255);
528 if (style_char ==
'U') {
534 if (style_char ==
'D') {
536 graph_state.m_DashArray =
537 ReadArrayElementsToVector(pDashArray.Get(), pDashArray->size());
538 if (graph_state.m_DashArray.size() % 2)
539 graph_state.m_DashArray.push_back(graph_state.m_DashArray.back());
541 graph_state.m_DashArray = {3.0f, 3.0f};
constexpr CFX_FloatRect()=default
void Deflate(float x, float y)
void Union(const CFX_FloatRect &other_rect)
CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
void MatchRect(const CFX_FloatRect &dest, const CFX_FloatRect &src)
void Rotate(float fRadian)
void Concat(const CFX_Matrix &right)
void AppendFloatRect(const CFX_FloatRect &rect)
bool DrawPath(const CFX_Path &path, const CFX_Matrix *pObject2Device, const CFX_GraphStateData *pGraphState, uint32_t fill_color, uint32_t stroke_color, const CFX_FillRenderOptions &fill_options)
DeviceType GetDeviceType() const
uint32_t GetFlags() const
CPDF_Form * GetAPForm(CPDF_Page *pPage, AppearanceMode mode)
bool DrawInContext(CPDF_Page *pPage, CPDF_RenderContext *pContext, const CFX_Matrix &mtUser2Device, AppearanceMode mode)
static ByteString AnnotSubtypeToString(Subtype nSubtype)
absl::optional< CFX_FloatRect > GetPopupAnnotRect() const
Subtype GetSubtype() const
static Subtype StringToAnnotSubtype(const ByteString &sSubtype)
CFX_FloatRect GetRect() const
CPDF_Annot(RetainPtr< CPDF_Dictionary > pDict, CPDF_Document *pDocument)
bool DrawAppearance(CPDF_Page *pPage, CFX_RenderDevice *pDevice, const CFX_Matrix &mtUser2Device, AppearanceMode mode)
void DrawBorder(CFX_RenderDevice *pDevice, const CFX_Matrix *pUser2Device)
static CFX_FloatRect BoundingRectFromQuadPoints(const CPDF_Dictionary *pAnnotDict)
void SetPopupAnnotOpenState(bool bOpenState)
bool KeyExist(const ByteString &key) const
RetainPtr< CPDF_Stream > GetMutableStreamFor(const ByteString &key)
ByteString GetByteStringFor(const ByteString &key) const
CPDF_Document * GetDocument() const override
int GetPageRotation() const
CPDF_PageImageCache * GetPageImageCache()
void AppendLayer(CPDF_PageObjectHolder *pObjectHolder, const CFX_Matrix &mtObject2Device)
void Render(CFX_RenderDevice *pDevice, const CPDF_PageObject *pStopObj, const CPDF_RenderOptions *pOptions, const CFX_Matrix *pLastMatrix)
bool operator==(const char *ptr) const
ByteString & operator=(ByteString &&that) noexcept
CharType operator[](const size_t index) const
RetainPtr< CPDF_Stream > GetAnnotAPNoFallback(CPDF_Dictionary *pAnnotDict, CPDF_Annot::AppearanceMode eMode)
RetainPtr< CPDF_Stream > GetAnnotAP(CPDF_Dictionary *pAnnotDict, CPDF_Annot::AppearanceMode eMode)
constexpr FX_ARGB ArgbEncode(uint32_t a, uint32_t r, uint32_t g, uint32_t b)
constexpr uint32_t kNoView
constexpr uint32_t kHidden
constexpr uint32_t kNoRotate
constexpr uint32_t kPrint
constexpr CFX_FillRenderOptions()