Snap for 13632198 from 103bfa7b57a068fc1ce83cd259dafb05eeaa67c3 to 25Q4-release Change-Id: I3f97f05f08be8f27b6bcc25e0a534d47286e7cab
diff --git a/core/fpdfdoc/cpdf_bafontmap.cpp b/core/fpdfdoc/cpdf_bafontmap.cpp index 694778c..ea67a8f 100644 --- a/core/fpdfdoc/cpdf_bafontmap.cpp +++ b/core/fpdfdoc/cpdf_bafontmap.cpp
@@ -252,9 +252,12 @@ return nullptr; CPDF_DefaultAppearance appearance(sDA); - float font_size; - std::optional<ByteString> font = appearance.GetFont(&font_size); - *sAlias = font.value_or(ByteString()); + auto maybe_font_name_and_size = appearance.GetFont(); + if (maybe_font_name_and_size.has_value()) { + *sAlias = maybe_font_name_and_size.value().name; + } else { + sAlias->clear(); + } RetainPtr<CPDF_Dictionary> pFontDict; if (RetainPtr<CPDF_Dictionary> pAPDict =
diff --git a/core/fpdfdoc/cpdf_defaultappearance.cpp b/core/fpdfdoc/cpdf_defaultappearance.cpp index cb8e6e5..9edcdb0 100644 --- a/core/fpdfdoc/cpdf_defaultappearance.cpp +++ b/core/fpdfdoc/cpdf_defaultappearance.cpp
@@ -9,14 +9,30 @@ #include <algorithm> #include <vector> +#include "core/fpdfapi/parser/cpdf_dictionary.h" #include "core/fpdfapi/parser/cpdf_simple_parser.h" #include "core/fpdfapi/parser/fpdf_parser_utility.h" +#include "core/fpdfdoc/cpdf_formfield.h" #include "core/fxcrt/fx_string.h" #include "core/fxcrt/notreached.h" #include "core/fxge/cfx_color.h" namespace { +ByteString GetDefaultAppearanceString(const CPDF_Dictionary* annot_dict, + const CPDF_Dictionary* acroform_dict) { + ByteString default_appearance_string; + RetainPtr<const CPDF_Object> default_appearance_object = + CPDF_FormField::GetFieldAttrForDict(annot_dict, "DA"); + if (default_appearance_object) { + default_appearance_string = default_appearance_object->GetString(); + } + if (default_appearance_string.IsEmpty() && acroform_dict) { + default_appearance_string = acroform_dict->GetByteStringFor("DA"); + } + return default_appearance_string; +} + // Find the token and its |nParams| parameters from the start of data, // and move the current position to the start of those parameters. bool FindTagParamFromStart(CPDF_SimpleParser* parser, @@ -58,24 +74,37 @@ : m_csDA(csDA) {} CPDF_DefaultAppearance::CPDF_DefaultAppearance( - const CPDF_DefaultAppearance& cDA) = default; + const CPDF_Dictionary* annot_dict, + const CPDF_Dictionary* acroform_dict) + : CPDF_DefaultAppearance( + GetDefaultAppearanceString(annot_dict, acroform_dict)) {} CPDF_DefaultAppearance::~CPDF_DefaultAppearance() = default; -std::optional<ByteString> CPDF_DefaultAppearance::GetFont( - float* fFontSize) const { - *fFontSize = 0.0f; +std::optional<CPDF_DefaultAppearance::FontNameAndSize> +CPDF_DefaultAppearance::GetFont() const { if (m_csDA.IsEmpty()) - return std::nullopt; + return std::nullopt; - ByteString csFontNameTag; CPDF_SimpleParser syntax(m_csDA.AsStringView().unsigned_span()); - if (FindTagParamFromStart(&syntax, "Tf", 2)) { - csFontNameTag = ByteString(syntax.GetWord()); - csFontNameTag.Delete(0, 1); - *fFontSize = StringToFloat(syntax.GetWord()); + if (!FindTagParamFromStart(&syntax, "Tf", 2)) { + return FontNameAndSize(); } - return PDF_NameDecode(csFontNameTag.AsStringView()); + + // Deliberately using separate statements here to ensure the correct + // evaluation order. + FontNameAndSize result; + result.name = PDF_NameDecode(syntax.GetWord().Substr(1)); + result.size = StringToFloat(syntax.GetWord()); + return result; +} + +float CPDF_DefaultAppearance::GetFontSizeOrZero() const { + auto maybe_font_name_and_size = GetFont(); + if (!maybe_font_name_and_size.has_value()) { + return 0; + } + return maybe_font_name_and_size.value().size; } std::optional<CFX_Color> CPDF_DefaultAppearance::GetColor() const {
diff --git a/core/fpdfdoc/cpdf_defaultappearance.h b/core/fpdfdoc/cpdf_defaultappearance.h index 78180ad..a177e0f 100644 --- a/core/fpdfdoc/cpdf_defaultappearance.h +++ b/core/fpdfdoc/cpdf_defaultappearance.h
@@ -12,15 +12,25 @@ #include "core/fxcrt/bytestring.h" #include "core/fxge/cfx_color.h" + +class CPDF_Dictionary; class CPDF_SimpleParser; class CPDF_DefaultAppearance { public: + struct FontNameAndSize { + ByteString name; + float size = 0; // Defaults to 0 if not found. + }; explicit CPDF_DefaultAppearance(const ByteString& csDA); - CPDF_DefaultAppearance(const CPDF_DefaultAppearance& cDA); + CPDF_DefaultAppearance(const CPDF_Dictionary* annot_dict, + const CPDF_Dictionary* acroform_dict); + CPDF_DefaultAppearance(const CPDF_DefaultAppearance&) = delete; + CPDF_DefaultAppearance& operator=(const CPDF_DefaultAppearance&) = delete; ~CPDF_DefaultAppearance(); - std::optional<ByteString> GetFont(float* fFontSize) const; + std::optional<FontNameAndSize> GetFont() const; + float GetFontSizeOrZero() const; std::optional<CFX_Color> GetColor() const; std::optional<CFX_Color::TypeAndARGB> GetColorARGB() const;
diff --git a/core/fpdfdoc/cpdf_formcontrol.cpp b/core/fpdfdoc/cpdf_formcontrol.cpp index ef81603..a7bae23 100644 --- a/core/fpdfdoc/cpdf_formcontrol.cpp +++ b/core/fpdfdoc/cpdf_formcontrol.cpp
@@ -203,19 +203,20 @@ } RetainPtr<CPDF_Font> CPDF_FormControl::GetDefaultControlFont() const { - float fFontSize; - CPDF_DefaultAppearance cDA = GetDefaultAppearance(); - std::optional<ByteString> csFontNameTag = cDA.GetFont(&fFontSize); - if (!csFontNameTag.has_value() || csFontNameTag->IsEmpty()) + CPDF_DefaultAppearance default_appearance = GetDefaultAppearance(); + auto maybe_font_name_and_size = default_appearance.GetFont(); + if (!maybe_font_name_and_size.has_value() || + maybe_font_name_and_size.value().name.IsEmpty()) { return nullptr; - + } + const ByteString &font_name = maybe_font_name_and_size.value().name; RetainPtr<CPDF_Dictionary> pDRDict = ToDictionary( - CPDF_FormField::GetMutableFieldAttrForDict(m_pWidgetDict.Get(), "DR")); + CPDF_FormField::GetMutableFieldAttrForDict(m_pWidgetDict.Get(), "DR")); if (pDRDict) { RetainPtr<CPDF_Dictionary> pFonts = pDRDict->GetMutableDictFor("Font"); if (ValidateFontResourceDict(pFonts.Get())) { RetainPtr<CPDF_Dictionary> pElement = - pFonts->GetMutableDictFor(csFontNameTag.value()); + pFonts->GetMutableDictFor(font_name); if (pElement) { RetainPtr<CPDF_Font> pFont = m_pForm->GetFontForElement(std::move(pElement)); @@ -224,13 +225,13 @@ } } } - RetainPtr<CPDF_Font> pFormFont = m_pForm->GetFormFont(csFontNameTag.value()); + RetainPtr<CPDF_Font> pFormFont = m_pForm->GetFormFont(font_name); if (pFormFont) return pFormFont; RetainPtr<CPDF_Dictionary> pPageDict = m_pWidgetDict->GetMutableDictFor("P"); RetainPtr<CPDF_Dictionary> pDict = ToDictionary( - CPDF_FormField::GetMutableFieldAttrForDict(pPageDict.Get(), "Resources")); + CPDF_FormField::GetMutableFieldAttrForDict(pPageDict.Get(), "Resources")); if (!pDict) return nullptr; @@ -238,8 +239,7 @@ if (!ValidateFontResourceDict(pFonts.Get())) return nullptr; - RetainPtr<CPDF_Dictionary> pElement = - pFonts->GetMutableDictFor(csFontNameTag.value()); + RetainPtr<CPDF_Dictionary> pElement = pFonts->GetMutableDictFor(font_name); if (!pElement) return nullptr;
diff --git a/core/fpdfdoc/cpdf_generateap.cpp b/core/fpdfdoc/cpdf_generateap.cpp index 568fc2c..0b1b2d6 100644 --- a/core/fpdfdoc/cpdf_generateap.cpp +++ b/core/fpdfdoc/cpdf_generateap.cpp
@@ -92,18 +92,24 @@ return PDF_EncodeString(words) + " Tj\n"; } +ByteString StringFromFontNameAndSize(const ByteString& font_name, + float font_size) { + fxcrt::ostringstream font_stream; + if (font_name.GetLength() > 0 && font_size > 0) { + font_stream << "/" << font_name << " "; + WriteFloat(font_stream, font_size) << " Tf\n"; + } + return ByteString(font_stream); +} + ByteString GetFontSetString(IPVT_FontMap* font_map, int32_t font_index, float font_size) { - fxcrt::ostringstream font_stream; - if (font_map) { - ByteString font_alias = font_map->GetPDFFontAlias(font_index); - if (font_alias.GetLength() > 0 && font_size > 0) { - font_stream << "/" << font_alias << " "; - WriteFloat(font_stream, font_size) << " Tf\n"; - } + if (!font_map) { + return ByteString(); } - return ByteString(font_stream); + return StringFromFontNameAndSize(font_map->GetPDFFontAlias(font_index), + font_size); } void SetVtFontSize(float font_size, CPVT_VariableText& vt) { @@ -246,20 +252,6 @@ }; } -ByteString GetDefaultAppearanceString(CPDF_Dictionary* annot_dict, - CPDF_Dictionary* form_dict) { - ByteString default_appearance_string; - RetainPtr<const CPDF_Object> default_appearance_object = - CPDF_FormField::GetFieldAttrForDict(annot_dict, "DA"); - if (default_appearance_object) { - default_appearance_string = default_appearance_object->GetString(); - } - if (default_appearance_string.IsEmpty()) { - default_appearance_string = form_dict->GetByteStringFor("DA"); - } - return default_appearance_string; -} - struct DefaultAppearanceInfo { ByteString font_name; float font_size; @@ -267,22 +259,17 @@ }; std::optional<DefaultAppearanceInfo> GetDefaultAppearanceInfo( - const ByteString& default_appearance_string) { - if (default_appearance_string.IsEmpty()) { - return std::nullopt; - } - - CPDF_DefaultAppearance appearance(default_appearance_string); - - float font_size = 0; - std::optional<ByteString> font = appearance.GetFont(&font_size); - if (!font.has_value()) { + const CPDF_Dictionary* annot_dict, + const CPDF_Dictionary* acroform_dict) { + CPDF_DefaultAppearance appearance(annot_dict, acroform_dict); + auto maybe_font_name_and_size = appearance.GetFont(); + if (!maybe_font_name_and_size.has_value()) { return std::nullopt; } return DefaultAppearanceInfo{ - .font_name = font.value(), - .font_size = font_size, + .font_name = maybe_font_name_and_size.value().name, + .font_size = maybe_font_name_and_size.value().size, .text_color = appearance.GetColor().value_or(CFX_Color())}; } @@ -1057,8 +1044,7 @@ } std::optional<DefaultAppearanceInfo> default_appearance_info = - GetDefaultAppearanceInfo( - GetDefaultAppearanceString(annot_dict, form_dict)); + GetDefaultAppearanceInfo(annot_dict, form_dict); if (!default_appearance_info.has_value()) { return false; } @@ -1459,8 +1445,7 @@ } std::optional<DefaultAppearanceInfo> default_appearance_info = - GetDefaultAppearanceInfo( - GetDefaultAppearanceString(annot_dict, form_dict)); + GetDefaultAppearanceInfo(annot_dict, form_dict); if (!default_appearance_info.has_value()) { return; } @@ -1620,4 +1605,48 @@ default: return false; } +} + +// static +bool CPDF_GenerateAP::GenerateDefaultAppearanceWithColor( + CPDF_Document* doc, + CPDF_Dictionary* annot_dict, + const CFX_Color& color) { + CHECK(doc); + CHECK(annot_dict); + + RetainPtr<CPDF_Dictionary> root_dict = doc->GetMutableRoot(); + if (!root_dict) { + return false; + } + + RetainPtr<CPDF_Dictionary> acroform_dict = + root_dict->GetMutableDictFor("AcroForm"); + if (!acroform_dict) { + acroform_dict = CPDF_InteractiveForm::InitAcroFormDict(doc); + CHECK(acroform_dict); + } + + CPDF_DefaultAppearance default_appearance(annot_dict, acroform_dict); + auto maybe_font_name_and_size = default_appearance.GetFont(); + if (!maybe_font_name_and_size.has_value()) { + return false; + } + + ByteString new_default_appearance_font_name_and_size = + StringFromFontNameAndSize(maybe_font_name_and_size.value().name, + maybe_font_name_and_size.value().size); + if (new_default_appearance_font_name_and_size.IsEmpty()) { + return false; + } + + ByteString new_default_appearance_color = + GenerateColorAP(color, PaintOperation::kFill); + CHECK(!new_default_appearance_color.IsEmpty()); + annot_dict->SetNewFor<CPDF_String>( + "DA", + new_default_appearance_font_name_and_size + new_default_appearance_color); + + // TODO(thestig): Call GenerateAnnotAP(); + return true; } \ No newline at end of file
diff --git a/core/fpdfdoc/cpdf_generateap.h b/core/fpdfdoc/cpdf_generateap.h index 520ce4f..60b158b 100644 --- a/core/fpdfdoc/cpdf_generateap.h +++ b/core/fpdfdoc/cpdf_generateap.h
@@ -11,6 +11,7 @@ class CPDF_Dictionary; class CPDF_Document; +struct CFX_Color; class CPDF_GenerateAP { public: @@ -26,6 +27,10 @@ CPDF_Dictionary* pAnnotDict, CPDF_Annot::Subtype subtype); + static bool GenerateDefaultAppearanceWithColor(CPDF_Document* doc, + CPDF_Dictionary* annot_dict, + const CFX_Color& color); + CPDF_GenerateAP() = delete; CPDF_GenerateAP(const CPDF_GenerateAP&) = delete; CPDF_GenerateAP& operator=(const CPDF_GenerateAP&) = delete;
diff --git a/core/fpdfdoc/cpdf_interactiveform.h b/core/fpdfdoc/cpdf_interactiveform.h index e6431c4..4e0e7c4 100644 --- a/core/fpdfdoc/cpdf_interactiveform.h +++ b/core/fpdfdoc/cpdf_interactiveform.h
@@ -105,6 +105,7 @@ const std::vector<UnownedPtr<CPDF_FormControl>>& GetControlsForField( const CPDF_FormField* field); + CPDF_Document* document() { return m_pDocument; } private: void LoadField(RetainPtr<CPDF_Dictionary> field_dict, int nLevel); void AddTerminalField(RetainPtr<CPDF_Dictionary> field_dict);
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp index b7b06ca..3ef528d 100644 --- a/fpdfsdk/cpdfsdk_appstream.cpp +++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -1190,13 +1190,10 @@ std::optional<CFX_Color> color = da.GetColor(); CFX_Color crText = color.value_or(CFX_Color(CFX_Color::Type::kGray, 0)); - float fFontSize; - ByteString csNameTag; - std::optional<ByteString> font = da.GetFont(&fFontSize); - if (font.has_value()) - csNameTag = font.value(); - else - fFontSize = 12.0f; + const float font_size = + da.GetFont() + .value_or(CPDF_DefaultAppearance::FontNameAndSize{.size = 12.0f}) + .size; WideString csWCaption; WideString csNormalCaption; @@ -1237,7 +1234,7 @@ crRightBottom, nBorderStyle, dsBorder) + GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, pNormalIcon, iconFit, csNormalCaption, - crText, fFontSize, nLayout); + crText, font_size, nLayout); Write("N", csAP, ByteString()); if (pNormalIcon) @@ -1264,7 +1261,7 @@ crRightBottom, nBorderStyle, dsBorder) + GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, pRolloverIcon, iconFit, - csRolloverCaption, crText, fFontSize, nLayout); + csRolloverCaption, crText, font_size, nLayout); Write("R", csAP, ByteString()); if (pRolloverIcon) @@ -1300,7 +1297,7 @@ crRightBottom, nBorderStyle, dsBorder) + GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map, pDownIcon, iconFit, csDownCaption, - crText, fFontSize, nLayout); + crText, font_size, nLayout); Write("D", csAP, ByteString()); if (pDownIcon)
diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index 3cb26d7..b8fa489 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp
@@ -471,11 +471,7 @@ } float CPDFSDK_Widget::GetFontSize() const { - CPDF_FormControl* pFormCtrl = GetFormControl(); - CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance(); - float fFontSize; - pDa.GetFont(&fFontSize); - return fFontSize; + return GetFormControl()->GetDefaultAppearance().GetFontSizeOrZero(); } int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
diff --git a/fpdfsdk/fpdf_annot.cpp b/fpdfsdk/fpdf_annot.cpp index e42e6db..adbd1a4 100644 --- a/fpdfsdk/fpdf_annot.cpp +++ b/fpdfsdk/fpdf_annot.cpp
@@ -11,6 +11,7 @@ #include <vector> #include "constants/annotation_common.h" +#include "core/fpdfapi/edit/cpdf_contentstream_write_utils.h" #include "core/fpdfapi/edit/cpdf_pagecontentgenerator.h" #include "core/fpdfapi/page/cpdf_annotcontext.h" #include "core/fpdfapi/page/cpdf_form.h" @@ -352,6 +353,27 @@ : nullptr; } +std::optional<CFX_Color::TypeAndARGB> GetFreetextFontColor( + FPDF_FORMHANDLE handle, + FPDF_ANNOTATION annot) { + const CPDF_Dictionary* annot_dict = GetAnnotDictFromFPDFAnnotation(annot); + CHECK(annot_dict); // Has to be true to determine `annot` is for Freetext. + + CPDFSDK_InteractiveForm* form = FormHandleToInteractiveForm(handle); + CPDF_Document* doc = form ? form->GetInteractiveForm()->document() : nullptr; + const CPDF_Dictionary* root_dict = doc ? doc->GetRoot() : nullptr; + RetainPtr<const CPDF_Dictionary> acroform_dict = + root_dict ? root_dict->GetDictFor("AcroForm") : nullptr; + CPDF_DefaultAppearance default_appearance(annot_dict, acroform_dict); + return default_appearance.GetColorARGB(); +} + +std::optional<FX_COLORREF> GetWidgetFontColor(FPDF_FORMHANDLE handle, + FPDF_ANNOTATION annot) { + const CPDFSDK_Widget* widget = GetWidgetOfTypes(handle, annot, {}); + return widget ? widget->GetTextColor() : std::nullopt; +} + } // namespace FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV @@ -1386,6 +1408,46 @@ } FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFAnnot_SetFontColor(FPDF_FORMHANDLE handle, + FPDF_ANNOTATION annot, + unsigned int R, + unsigned int G, + unsigned int B) { + RetainPtr<CPDF_Dictionary> annot_dict = + GetMutableAnnotDictFromFPDFAnnotation(annot); + if (!annot_dict || R > 255 || G > 255 || B > 255) { + return false; + } + + const CPDF_Annot::Subtype subtype = CPDF_Annot::StringToAnnotSubtype( + annot_dict->GetNameFor(pdfium::annotation::kSubtype)); + if (subtype != CPDF_Annot::Subtype::FREETEXT) { + // TODO(thestig): Consider adding widget support to mirror + // FPDFAnnot_GetFontColor(). + return false; + } + + CPDFSDK_InteractiveForm* form = FormHandleToInteractiveForm(handle); + if (!form) { + return false; + } + + bool generated = CPDF_GenerateAP::GenerateDefaultAppearanceWithColor( + form->GetInteractiveForm()->document(), annot_dict, CFX_Color(R, G, B)); + if (!generated) { + return false; + } + + // Remove the appearance stream. Otherwise PDF viewers will render that and + // not use the new color. + // + // TODO(thestig) When GenerateDefaultAppearanceWithColor() properly updates + // the annotation's appearance stream, remove this. + annot_dict->RemoveFor(pdfium::annotation::kAP); + return true; +} + +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDFAnnot_GetFontColor(FPDF_FORMHANDLE hHandle, FPDF_ANNOTATION annot, unsigned int* R, @@ -1395,19 +1457,32 @@ return false; } - const CPDFSDK_Widget* widget = GetWidgetOfTypes(hHandle, annot, {}); - if (!widget) { - return false; + FX_COLORREF font_color; + switch (FPDFAnnot_GetSubtype(annot)) { + case FPDF_ANNOT_FREETEXT: { + auto maybe_font_color = GetFreetextFontColor(hHandle, annot); + if (!maybe_font_color.has_value()) { + return false; + } + font_color = ArgbToColorRef(maybe_font_color.value().argb); + break; + } + case FPDF_ANNOT_WIDGET: { + auto maybe_font_color = GetWidgetFontColor(hHandle, annot); + if (!maybe_font_color.has_value()) { + return false; + } + font_color = maybe_font_color.value(); + break; + } + default: { + return false; + } } - std::optional<FX_COLORREF> text_color = widget->GetTextColor(); - if (!text_color) { - return false; - } - - *R = FXSYS_GetRValue(*text_color); - *G = FXSYS_GetGValue(*text_color); - *B = FXSYS_GetBValue(*text_color); + *R = FXSYS_GetRValue(font_color); + *G = FXSYS_GetGValue(font_color); + *B = FXSYS_GetBValue(font_color); return true; }
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c index 1765faf..3c49c47 100644 --- a/fpdfsdk/fpdf_view_c_api_test.c +++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -94,6 +94,7 @@ CHK(FPDFAnnot_SetColor); CHK(FPDFAnnot_SetFlags); CHK(FPDFAnnot_SetFocusableSubtypes); + CHK(FPDFAnnot_SetFontColor); CHK(FPDFAnnot_SetRect); CHK(FPDFAnnot_SetStringValue); CHK(FPDFAnnot_SetURI);
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp index d230b06..49c3030 100644 --- a/fxjs/cjs_field.cpp +++ b/fxjs/cjs_field.cpp
@@ -1984,10 +1984,10 @@ if (!pFormControl) return CJS_Result::Failure(JSMessage::kBadObjectError); - float fFontSize; - CPDF_DefaultAppearance FieldAppearance = pFormControl->GetDefaultAppearance(); - FieldAppearance.GetFont(&fFontSize); - return CJS_Result::Success(pRuntime->NewNumber(static_cast<int>(fFontSize))); + CPDF_DefaultAppearance field_appearance = + pFormControl->GetDefaultAppearance(); + return CJS_Result::Success(pRuntime->NewNumber( + static_cast<int>(field_appearance.GetFontSizeOrZero()))); } CJS_Result CJS_Field::set_text_size(CJS_Runtime* pRuntime,
diff --git a/public/fpdf_annot.h b/public/fpdf_annot.h index ef30d9a..cc63679 100644 --- a/public/fpdf_annot.h +++ b/public/fpdf_annot.h
@@ -846,6 +846,27 @@ float* value); // Experimental API. +// Set the text color of an annotation. +// +// handle - handle to the form fill module, returned by +// FPDFDOC_InitFormFillEnvironment. +// annot - handle to an annotation. +// R - the red component for the text color. +// G - the green component for the text color. +// B - the blue component for the text color. +// +// Returns true if successful. +// +// Currently supported subtypes: freetext. +// The range for the color components is 0 to 255. +FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV +FPDFAnnot_SetFontColor(FPDF_FORMHANDLE handle, + FPDF_ANNOTATION annot, + unsigned int R, + unsigned int G, + unsigned int B); + +// Experimental API. // Get the RGB value of the font color for an |annot| with variable text. // // hHandle - handle to the form fill module, returned by