Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions core/fpdfdoc/cpdf_annot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,12 @@ std::optional<CFX_FloatRect> CPDF_Annot::GetDrawingRect(AppearanceMode mode) {
return GetRect();
}

// EmbedPDF(annot-appearance, reads-dont-write): what flattening paints for an
// annotation without a stored appearance.
RetainPtr<const CPDF_Stream> CPDF_Annot::GetAppearanceDrawnInMemory() {
return GetOrBuildEphemeralAP(AppearanceMode::kNormal);
}

CPDF_Annot::Subtype CPDF_Annot::GetSubtype() const {
return subtype_;
}
Expand Down Expand Up @@ -340,6 +346,20 @@ bool CPDF_Annot::IsHidden() const {
return !!(GetFlags() & pdfium::annotation_flags::kHidden);
}

// EmbedPDF(bug-fix): the Invisible flag applies to unknown types only (header).
// static
bool CPDF_Annot::IsHiddenByInvisibleFlag(const CPDF_Dictionary* annot_dict) {
if (!(annot_dict->GetIntegerFor(pdfium::annotation::kF) &
pdfium::annotation_flags::kInvisible)) {
return false;
}
const ByteString subtype =
annot_dict->GetNameFor(pdfium::annotation::kSubtype);
// Projection is standard since PDF 2.0, though PDFium has no Subtype for it.
return StringToAnnotSubtype(subtype) == Subtype::UNKNOWN &&
subtype != "Projection";
}

// EmbedPDF(reads-dont-write): reads take a const dictionary.
RetainPtr<CPDF_Stream> GetAnnotAP(const CPDF_Dictionary* pAnnotDict,
CPDF_Annot::AppearanceMode eMode) {
Expand Down
14 changes: 14 additions & 0 deletions core/fpdfdoc/cpdf_annot.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@ class CPDF_Annot {

bool IsHidden() const;

// EmbedPDF(bug-fix): whether the Invisible flag leaves |annot_dict| undrawn.
// ISO 32000-2 12.5.3 limits the flag to a type that isn't a standard one,
// which no handler draws; on a standard annotation it means nothing. Upstream
// drew such an unknown annotation anyway, and its flatten skipped every
// annotation with the flag. The renderer and flatten both ask here.
static bool IsHiddenByInvisibleFlag(const CPDF_Dictionary* annot_dict);

// EmbedPDF(annot-appearance): draw this state of an appearance subdictionary
// (/AP /N /Yes), whatever /AS says. Only a stored state is drawn: a mode
// whose entry is a single stream, a state the subdictionary lacks, or no
Expand All @@ -238,6 +245,13 @@ class CPDF_Annot {
// appearance into the file).
std::optional<CFX_FloatRect> GetDrawingRect(AppearanceMode mode);

// EmbedPDF(annot-appearance, reads-dont-write): what flattening paints for
// an annotation without a stored appearance.
// The normal appearance PDFium draws in memory when there is no stored one,
// built without writing anything. This object keeps it, and the fonts it
// uses, alive. Null when there is a stored appearance or nothing to draw.
RetainPtr<const CPDF_Stream> GetAppearanceDrawnInMemory();

bool DrawAppearance(CPDF_Page* pPage,
CFX_RenderDevice* pDevice,
const CFX_Matrix& mtUser2Device,
Expand Down
6 changes: 6 additions & 0 deletions core/fpdfdoc/cpdf_annotlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,12 @@ void CPDF_AnnotList::DisplayPass(CPDF_RenderContext* context,
continue;
}

// EmbedPDF(bug-fix): an unknown type with the Invisible flag isn't drawn;
// upstream drew it.
if (CPDF_Annot::IsHiddenByInvisibleFlag(pAnnot->GetAnnotDict())) {
continue;
}

if (bPrinting && (annot_flags & pdfium::annotation_flags::kPrint) == 0) {
continue;
}
Expand Down
3 changes: 3 additions & 0 deletions fpdfsdk/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ source_set("fpdfsdk") {
"epdf_form.cpp",
# EmbedPDF: layer-safe selective page and annotation flattening.
"epdf_flatten.cpp",
# EmbedPDF: copies objects across documents and in-memory stores.
"epdf_object_copier.cpp",
"epdf_object_copier.h",
"epdf_layer.cpp",
"epdf_outline.cpp",
# EmbedPDF: the catalog's /Names /Pages and /Templates name trees.
Expand Down
1 change: 1 addition & 0 deletions fpdfsdk/epdf_c_api_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ int CheckEmbedPDFCApi(void) {
CHK(EPDFText_RedactInRect);

// epdf_flatten.h
CHK(EPDFDoc_ExportPagesFlattened);
CHK(EPDFPage_ExportAnnotationsAsDocument);
CHK(EPDFPage_Flatten);
CHK(EPDFPage_FlattenAnnotations);
Expand Down
Loading