diff options
author | Jane Liu <janeliulwq@google.com> | 2017-06-01 18:56:09 -0400 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-06-01 23:17:03 +0000 |
commit | 4fd9a47465c0f2f17aa2a840d8452b2bee6bec33 (patch) | |
tree | 4dbd633596216ceddf817e693376a3626e28f112 /fpdfsdk/fpdfannot.cpp | |
parent | 8cb884102c17ef0530277126fd8da054d329d065 (diff) | |
download | pdfium-4fd9a47465c0f2f17aa2a840d8452b2bee6bec33.tar.xz |
Basic APIs and tests for extracting annotations
1. Added API for extracting annotation properties:
* Added testing flag "--annot" that outputs the annotation properties
into a .txt file.
* Added two embedder tests covering all the API functions.
Bug=pdfium:737
Change-Id: I95943a9b2b3d5d431bc8a74a31b27b4f4b521026
Reviewed-on: https://pdfium-review.googlesource.com/6092
Commit-Queue: Jane Liu <janeliulwq@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'fpdfsdk/fpdfannot.cpp')
-rw-r--r-- | fpdfsdk/fpdfannot.cpp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/fpdfsdk/fpdfannot.cpp b/fpdfsdk/fpdfannot.cpp new file mode 100644 index 0000000000..6e5b7ba063 --- /dev/null +++ b/fpdfsdk/fpdfannot.cpp @@ -0,0 +1,238 @@ +// Copyright 2017 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 "public/fpdf_annot.h" + +#include "core/fpdfapi/page/cpdf_page.h" +#include "core/fpdfapi/parser/cpdf_array.h" +#include "core/fpdfapi/parser/cpdf_dictionary.h" +#include "core/fpdfdoc/cpdf_annot.h" +#include "core/fpdfdoc/cpvt_color.h" +#include "core/fpdfdoc/cpvt_generateap.h" +#include "fpdfsdk/fsdk_define.h" + +// These checks ensure the consistency of annotation subtype values across core/ +// and public. +static_assert(static_cast<int>(CPDF_Annot::Subtype::UNKNOWN) == + FPDF_ANNOT_UNKNOWN, + "CPDF_Annot::UNKNOWN value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::TEXT) == FPDF_ANNOT_TEXT, + "CPDF_Annot::TEXT value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::LINK) == FPDF_ANNOT_LINK, + "CPDF_Annot::LINK value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::FREETEXT) == + FPDF_ANNOT_FREETEXT, + "CPDF_Annot::FREETEXT value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::LINE) == FPDF_ANNOT_LINE, + "CPDF_Annot::LINE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUARE) == + FPDF_ANNOT_SQUARE, + "CPDF_Annot::SQUARE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::CIRCLE) == + FPDF_ANNOT_CIRCLE, + "CPDF_Annot::CIRCLE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYGON) == + FPDF_ANNOT_POLYGON, + "CPDF_Annot::POLYGON value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::POLYLINE) == + FPDF_ANNOT_POLYLINE, + "CPDF_Annot::POLYLINE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::HIGHLIGHT) == + FPDF_ANNOT_HIGHLIGHT, + "CPDF_Annot::HIGHLIGHT value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::UNDERLINE) == + FPDF_ANNOT_UNDERLINE, + "CPDF_Annot::UNDERLINE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::SQUIGGLY) == + FPDF_ANNOT_SQUIGGLY, + "CPDF_Annot::SQUIGGLY value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::STRIKEOUT) == + FPDF_ANNOT_STRIKEOUT, + "CPDF_Annot::STRIKEOUT value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::STAMP) == FPDF_ANNOT_STAMP, + "CPDF_Annot::STAMP value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::CARET) == FPDF_ANNOT_CARET, + "CPDF_Annot::CARET value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::INK) == FPDF_ANNOT_INK, + "CPDF_Annot::INK value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::POPUP) == FPDF_ANNOT_POPUP, + "CPDF_Annot::POPUP value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::FILEATTACHMENT) == + FPDF_ANNOT_FILEATTACHMENT, + "CPDF_Annot::FILEATTACHMENT value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::SOUND) == FPDF_ANNOT_SOUND, + "CPDF_Annot::SOUND value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::MOVIE) == FPDF_ANNOT_MOVIE, + "CPDF_Annot::MOVIE value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::WIDGET) == + FPDF_ANNOT_WIDGET, + "CPDF_Annot::WIDGET value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::SCREEN) == + FPDF_ANNOT_SCREEN, + "CPDF_Annot::SCREEN value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::PRINTERMARK) == + FPDF_ANNOT_PRINTERMARK, + "CPDF_Annot::PRINTERMARK value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::TRAPNET) == + FPDF_ANNOT_TRAPNET, + "CPDF_Annot::TRAPNET value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::WATERMARK) == + FPDF_ANNOT_WATERMARK, + "CPDF_Annot::WATERMARK value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::THREED) == + FPDF_ANNOT_THREED, + "CPDF_Annot::THREED value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::RICHMEDIA) == + FPDF_ANNOT_RICHMEDIA, + "CPDF_Annot::RICHMEDIA value mismatch"); +static_assert(static_cast<int>(CPDF_Annot::Subtype::XFAWIDGET) == + FPDF_ANNOT_XFAWIDGET, + "CPDF_Annot::XFAWIDGET value mismatch"); + +DLLEXPORT int STDCALL FPDFPage_GetAnnotCount(FPDF_PAGE page) { + CPDF_Page* pPage = CPDFPageFromFPDFPage(page); + if (!pPage || !pPage->m_pFormDict) + return 0; + CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); + return pAnnots ? pAnnots->GetCount() : 0; +} + +DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetAnnot(FPDF_PAGE page, + int index, + FPDF_ANNOTATION* annot) { + CPDF_Page* pPage = CPDFPageFromFPDFPage(page); + if (!pPage || !pPage->m_pFormDict || index < 0 || !annot) + return false; + CPDF_Array* pAnnots = pPage->m_pFormDict->GetArrayFor("Annots"); + if (!pAnnots || static_cast<size_t>(index) >= pAnnots->GetCount()) + return false; + + CPDF_Dictionary* pDict = ToDictionary(pAnnots->GetDirectObjectAt(index)); + *annot = FPDFAnnotationFromCPDFDictionary(pDict); + return *annot ? true : false; +} + +DLLEXPORT FPDF_ANNOTATION_SUBTYPE STDCALL +FPDFAnnot_GetSubtype(FPDF_ANNOTATION annot) { + CPDF_Dictionary* pAnnotDict = CPDFDictionaryFromFPDFAnnotation(annot); + if (!pAnnotDict) + return FPDF_ANNOT_UNKNOWN; + return static_cast<FPDF_ANNOTATION_SUBTYPE>( + CPDF_Annot::StringToAnnotSubtype(pAnnotDict->GetStringFor("Subtype"))); +} + +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_GetColor(FPDF_ANNOTATION annot, + FPDFANNOT_COLORTYPE type, + unsigned int* R, + unsigned int* G, + unsigned int* B, + unsigned int* A) { + CPDF_Dictionary* pAnnotDict = CPDFDictionaryFromFPDFAnnotation(annot); + if (!pAnnotDict || !R || !G || !B || !A) + return false; + + CPDF_Array* pColor = pAnnotDict->GetArrayFor( + type == FPDFANNOT_COLORTYPE_InteriorColor ? "IC" : "C"); + *A = + (pAnnotDict->KeyExist("CA") ? pAnnotDict->GetNumberFor("CA") : 1) * 255.f; + if (!pColor) { + // Use default color. The default colors must be consistent with the ones + // used to generate AP. See calls to GetColorStringWithDefault() in + // CPVT_GenerateAP::Generate*AP(). + if (pAnnotDict->GetStringFor("Subtype") == "Highlight") { + *R = 255; + *G = 255; + *B = 0; + } else { + *R = 0; + *G = 0; + *B = 0; + } + return true; + } + CPVT_Color color = CPVT_Color::ParseColor(*pColor); + switch (color.nColorType) { + case CPVT_Color::kRGB: + *R = color.fColor1 * 255.f; + *G = color.fColor2 * 255.f; + *B = color.fColor3 * 255.f; + break; + case CPVT_Color::kGray: + *R = 255.f * color.fColor1; + *G = 255.f * color.fColor1; + *B = 255.f * color.fColor1; + break; + case CPVT_Color::kCMYK: + *R = 255.f * (1 - color.fColor1) * (1 - color.fColor4); + *G = 255.f * (1 - color.fColor2) * (1 - color.fColor4); + *B = 255.f * (1 - color.fColor3) * (1 - color.fColor4); + break; + case CPVT_Color::kTransparent: + *R = 0; + *G = 0; + *B = 0; + break; + } + return true; +} + +DLLEXPORT FPDF_BOOL STDCALL +FPDFAnnot_HasAttachmentPoints(FPDF_ANNOTATION annot) { + if (!annot) + return false; + FPDF_ANNOTATION_SUBTYPE subtype = FPDFAnnot_GetSubtype(annot); + return subtype == FPDF_ANNOT_LINK || subtype == FPDF_ANNOT_HIGHLIGHT || + subtype == FPDF_ANNOT_UNDERLINE || subtype == FPDF_ANNOT_SQUIGGLY || + subtype == FPDF_ANNOT_STRIKEOUT; +} + +DLLEXPORT FPDF_BOOL STDCALL +FPDFAnnot_GetAttachmentPoints(FPDF_ANNOTATION annot, + FS_QUADPOINTSF* quadPoints) { + if (!annot || !quadPoints || !FPDFAnnot_HasAttachmentPoints(annot)) + return false; + CPDF_Array* pArray = + CPDFDictionaryFromFPDFAnnotation(annot)->GetArrayFor("QuadPoints"); + if (!pArray) + return false; + quadPoints->x1 = pArray->GetNumberAt(0); + quadPoints->y1 = pArray->GetNumberAt(1); + quadPoints->x2 = pArray->GetNumberAt(2); + quadPoints->y2 = pArray->GetNumberAt(3); + quadPoints->x3 = pArray->GetNumberAt(4); + quadPoints->y3 = pArray->GetNumberAt(5); + quadPoints->x4 = pArray->GetNumberAt(6); + quadPoints->y4 = pArray->GetNumberAt(7); + return true; +} + +DLLEXPORT FPDF_BOOL STDCALL FPDFAnnot_GetRect(FPDF_ANNOTATION annot, + FS_RECTF* rect) { + CPDF_Dictionary* pAnnotDict = CPDFDictionaryFromFPDFAnnotation(annot); + if (!rect || !pAnnotDict) + return false; + CFX_FloatRect rt = pAnnotDict->GetRectFor("Rect"); + rect->left = rt.left; + rect->bottom = rt.bottom; + rect->right = rt.right; + rect->top = rt.top; + return true; +} + +DLLEXPORT unsigned long STDCALL FPDFAnnot_GetText(FPDF_ANNOTATION annot, + FPDFANNOT_TEXTTYPE type, + char* buffer, + unsigned long buflen) { + CPDF_Dictionary* pAnnotDict = CPDFDictionaryFromFPDFAnnotation(annot); + if (!pAnnotDict) + return 0; + CFX_ByteString key = type == FPDFANNOT_TEXTTYPE_Author ? "T" : "Contents"; + CFX_ByteString contents = pAnnotDict->GetUnicodeTextFor(key).UTF16LE_Encode(); + unsigned long len = contents.GetLength(); + if (buffer && buflen >= len) + memcpy(buffer, contents.c_str(), len); + return len; +} |