7#include "core/fpdfdoc/cpdf_annot.h"
12#include "build/build_config.h"
13#include "constants/annotation_common.h"
14#include "constants/annotation_flags.h"
15#include "core/fpdfapi/page/cpdf_form.h"
16#include "core/fpdfapi/page/cpdf_page.h"
17#include "core/fpdfapi/page/cpdf_pageimagecache.h"
18#include "core/fpdfapi/parser/cpdf_array.h"
19#include "core/fpdfapi/parser/cpdf_boolean.h"
20#include "core/fpdfapi/parser/cpdf_dictionary.h"
21#include "core/fpdfapi/parser/cpdf_document.h"
22#include "core/fpdfapi/parser/cpdf_stream.h"
23#include "core/fpdfapi/parser/fpdf_parser_utility.h"
24#include "core/fpdfapi/render/cpdf_rendercontext.h"
25#include "core/fpdfapi/render/cpdf_renderoptions.h"
26#include "core/fpdfdoc/cpdf_generateap.h"
27#include "core/fxcrt/check.h"
28#include "core/fxge/cfx_fillrenderoptions.h"
29#include "core/fxge/cfx_graphstatedata.h"
30#include "core/fxge/cfx_path.h"
31#include "core/fxge/cfx_renderdevice.h"
35const char kPDFiumKey_HasGeneratedAP[] =
"PDFIUM_HasGeneratedAP";
44CPDF_Form* AnnotGetMatrix(CPDF_Page* pPage,
53 CFX_Matrix form_matrix = pForm->GetDict()->GetMatrixFor(
"Matrix");
55 form_matrix.TransformRect(pForm->GetDict()->GetRectFor(
"BBox"));
78 bool bFallbackToNormal) {
80 pAnnotDict->GetMutableDictFor(pdfium::annotation::kAP);
84 const char* ap_entry =
"N";
89 if (bFallbackToNormal && !pAP->KeyExist(ap_entry))
96 RetainPtr<CPDF_Stream> pStream(psub->AsMutableStream());
107 if (value.IsEmpty()) {
109 pAnnotDict->GetDictFor(
"Parent");
110 value = pParentDict ? pParentDict->GetByteStringFor(
"V") :
ByteString();
112 as = (!value.IsEmpty() && pDict
->KeyExist(value
)) ? value :
"Off";
125 m_bIsTextMarkupAnnotation(IsTextMarkupAnnotation(m_nSubtype)),
128 GenerateAPIfNeeded();
136 if (!ShouldGenerateAP())
138 if (!CPDF_GenerateAP::GenerateAnnotAP(m_pDocument, m_pAnnotDict.Get(),
143 m_pAnnotDict->SetNewFor<CPDF_Boolean>(kPDFiumKey_HasGeneratedAP,
true);
144 m_bHasGeneratedAP =
true;
151 m_pAnnotDict->GetDictFor(pdfium::annotation::kAP);
152 if (pAP && pAP->GetDictFor(
"N"))
158bool CPDF_Annot::ShouldDrawAnnotation()
const {
173 bool bShouldUseQuadPointsCoords =
174 m_bIsTextMarkupAnnotation && m_bHasGeneratedAP;
175 if (bShouldUseQuadPointsCoords)
176 return BoundingRectFromQuadPoints(m_pAnnotDict.Get());
177 return m_pAnnotDict->GetRectFor(pdfium::annotation::kRect);
187 return m_pAnnotDict->GetIntegerFor(pdfium::annotation::kF);
197 return GetAnnotAPInternal(pAnnotDict, eMode,
true);
203 return GetAnnotAPInternal(pAnnotDict, eMode,
false);
207 RetainPtr<CPDF_Stream> pStream = GetAnnotAP(m_pAnnotDict.Get(), mode);
211 auto it = m_APMap.find(pStream);
212 if (it != m_APMap.end())
213 return it->second.get();
215 auto pNewForm = std::make_unique<CPDF_Form>(
216 m_pDocument, pPage->GetMutableResources(), pStream);
217 pNewForm->ParseContent();
219 CPDF_Form* pResult = pNewForm.get();
220 m_APMap[pStream] = std::move(pNewForm);
226 m_pPopupAnnot->SetOpenState(bOpenState);
232 return m_pPopupAnnot->GetRect();
239 DCHECK(nIndex < pArray->size() / 8);
253 pArray->GetFloatAt(4 + nIndex * 8), pArray->GetFloatAt(5 + nIndex * 8),
254 pArray->GetFloatAt(2 + nIndex * 8), pArray->GetFloatAt(3 + nIndex * 8));
262 size_t nQuadPointCount = pArray ? QuadPointCount(pArray.Get()) : 0;
263 if (nQuadPointCount == 0)
266 ret = RectFromQuadPointsArray(pArray.Get(), 0);
267 for (size_t i = 1; i < nQuadPointCount; ++i) {
268 CFX_FloatRect rect = RectFromQuadPointsArray(pArray.Get(), i);
278 size_t nQuadPointCount = pArray ? QuadPointCount(pArray.Get()) : 0;
279 if (nIndex >= nQuadPointCount)
281 return RectFromQuadPointsArray(pArray.Get(), nIndex);
287 if (sSubtype
== "Text")
289 if (sSubtype
== "Link")
291 if (sSubtype
== "FreeText")
293 if (sSubtype
== "Line")
295 if (sSubtype
== "Square")
297 if (sSubtype
== "Circle")
299 if (sSubtype
== "Polygon")
301 if (sSubtype
== "PolyLine")
303 if (sSubtype
== "Highlight")
305 if (sSubtype
== "Underline")
307 if (sSubtype
== "Squiggly")
309 if (sSubtype
== "StrikeOut")
311 if (sSubtype
== "Stamp")
313 if (sSubtype
== "Caret")
315 if (sSubtype
== "Ink")
317 if (sSubtype
== "Popup")
319 if (sSubtype
== "FileAttachment")
321 if (sSubtype
== "Sound")
323 if (sSubtype
== "Movie")
325 if (sSubtype
== "Widget")
327 if (sSubtype
== "Screen")
329 if (sSubtype
== "PrinterMark")
331 if (sSubtype
== "TrapNet")
333 if (sSubtype
== "Watermark")
335 if (sSubtype
== "3D")
337 if (sSubtype
== "RichMedia")
339 if (sSubtype
== "XFAWidget")
341 if (sSubtype
== "Redact")
381 return "FileAttachment";
391 return "PrinterMark";
409 return pArray->size() / 8;
416 if (!ShouldDrawAnnotation())
424 GenerateAPIfNeeded();
427 CPDF_Form* pForm = AnnotGetMatrix(pPage,
this, mode, mtUser2Device, &matrix);
432 pPage->GetMutablePageResources(),
443 if (!ShouldDrawAnnotation())
451 GenerateAPIfNeeded();
454 CPDF_Form* pForm = AnnotGetMatrix(pPage,
this, mode, mtUser2Device, &matrix);
472 bool is_printing = pDevice->GetDeviceType() == DeviceType::kPrinter;
473 if (is_printing && (annot_flags & pdfium::annotation_flags::kPrint) == 0) {
477 const bool is_printing =
false;
490 m_pAnnotDict->GetArrayFor(pdfium::annotation::kBorder);
493 width = pBorderArray->GetFloatAt(2);
494 if (pBorderArray->size() == 4) {
495 pDashArray = pBorderArray->GetArrayAt(3);
499 size_t nLen = pDashArray->size();
501 for (; i < nLen; ++i) {
503 if (pObj && pObj->GetInteger()) {
516 ByteString style = pBS->GetByteStringFor(
"S");
517 pDashArray = pBS->GetArrayFor(
"D");
518 style_char = style[0];
519 width = pBS->GetFloatFor(
"W");
525 m_pAnnotDict->GetArrayFor(pdfium::annotation::kC);
526 uint32_t argb = 0xff000000;
528 int R =
static_cast<int32_t>(pColor->GetFloatAt(0) * 255);
529 int G =
static_cast<int32_t>(pColor->GetFloatAt(1) * 255);
530 int B =
static_cast<int32_t>(pColor->GetFloatAt(2) * 255);
535 if (style_char ==
'U') {
541 if (style_char ==
'D') {
543 graph_state.m_DashArray =
544 ReadArrayElementsToVector(pDashArray.Get(), pDashArray->size());
545 if (graph_state.m_DashArray.size() % 2)
546 graph_state.m_DashArray.push_back(graph_state.m_DashArray.back());
548 graph_state.m_DashArray = {3.0f, 3.0f};
fxcrt::ByteString ByteString
constexpr CFX_FloatRect()=default
void Deflate(float x, float y)
void Union(const CFX_FloatRect &other_rect)
void MatchRect(const CFX_FloatRect &dest, const CFX_FloatRect &src)
void Rotate(float fRadian)
constexpr CFX_Matrix(float a1, float b1, float c1, float d1, float e1, float f1)
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)
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)
Subtype GetSubtype() const
static Subtype StringToAnnotSubtype(const ByteString &sSubtype)
std::optional< CFX_FloatRect > GetPopupAnnotRect() const
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)
std::vector< RetainPtr< CPDF_Object > >::const_iterator const_iterator
bool KeyExist(const ByteString &key) const
RetainPtr< CPDF_Stream > GetMutableStreamFor(const ByteString &key)
ByteString GetByteStringFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
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
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 CFX_FillRenderOptions()