Commit 2d32f4db8fd125f2481ecf767d9f6506e80481f6
1 parent
9cb59987
Handle fallback font size in text appearances
If we end up using our fallback font size when generating appearances for text fields, reflect that in the Tf operator used in the appearance stream.
Showing
5 changed files
with
393 additions
and
355 deletions
ChangeLog
| 1 | 1 | 2019-01-20 Jay Berkenbilt <ejb@ql.org> |
| 2 | 2 | |
| 3 | + * Tweak the content code generated for variable text fields to | |
| 4 | + better handle font sizes and multi-line text. | |
| 5 | + | |
| 3 | 6 | * When generating appearance streams for variable text |
| 4 | 7 | annotations, properly handle the cases of there being no |
| 5 | 8 | appearance dictionary, no appearance stream, or an appearance | ... | ... |
libqpdf/QPDFFormFieldObjectHelper.cc
| ... | ... | @@ -715,17 +715,23 @@ class TfFinder: public QPDFObjectHandle::TokenFilter |
| 715 | 715 | virtual void handleToken(QPDFTokenizer::Token const&); |
| 716 | 716 | double getTf(); |
| 717 | 717 | std::string getFontName(); |
| 718 | + std::string getDA(); | |
| 718 | 719 | |
| 719 | 720 | private: |
| 720 | 721 | double tf; |
| 722 | + size_t tf_idx; | |
| 721 | 723 | std::string font_name; |
| 722 | 724 | double last_num; |
| 725 | + size_t last_num_idx; | |
| 723 | 726 | std::string last_name; |
| 727 | + std::vector<std::string> DA; | |
| 724 | 728 | }; |
| 725 | 729 | |
| 726 | 730 | TfFinder::TfFinder() : |
| 727 | 731 | tf(11.0), |
| 728 | - last_num(0.0) | |
| 732 | + tf_idx(0), | |
| 733 | + last_num(0.0), | |
| 734 | + last_num_idx(0) | |
| 729 | 735 | { |
| 730 | 736 | } |
| 731 | 737 | |
| ... | ... | @@ -734,11 +740,13 @@ TfFinder::handleToken(QPDFTokenizer::Token const& token) |
| 734 | 740 | { |
| 735 | 741 | QPDFTokenizer::token_type_e ttype = token.getType(); |
| 736 | 742 | std::string value = token.getValue(); |
| 743 | + DA.push_back(token.getRawValue()); | |
| 737 | 744 | switch (ttype) |
| 738 | 745 | { |
| 739 | 746 | case QPDFTokenizer::tt_integer: |
| 740 | 747 | case QPDFTokenizer::tt_real: |
| 741 | 748 | last_num = strtod(value.c_str(), 0); |
| 749 | + last_num_idx = DA.size() - 1; | |
| 742 | 750 | break; |
| 743 | 751 | |
| 744 | 752 | case QPDFTokenizer::tt_name: |
| ... | ... | @@ -754,6 +762,7 @@ TfFinder::handleToken(QPDFTokenizer::Token const& token) |
| 754 | 762 | // insane things or suffering from over/underflow |
| 755 | 763 | tf = last_num; |
| 756 | 764 | } |
| 765 | + tf_idx = last_num_idx; | |
| 757 | 766 | font_name = last_name; |
| 758 | 767 | break; |
| 759 | 768 | |
| ... | ... | @@ -769,6 +778,30 @@ TfFinder::getTf() |
| 769 | 778 | } |
| 770 | 779 | |
| 771 | 780 | std::string |
| 781 | +TfFinder::getDA() | |
| 782 | +{ | |
| 783 | + std::string result; | |
| 784 | + size_t n = this->DA.size(); | |
| 785 | + for (size_t i = 0; i < n; ++i) | |
| 786 | + { | |
| 787 | + std::string cur = this->DA.at(i); | |
| 788 | + if (i == tf_idx) | |
| 789 | + { | |
| 790 | + double delta = strtod(cur.c_str(), 0) - this->tf; | |
| 791 | + if ((delta > 0.001) || (delta < -0.001)) | |
| 792 | + { | |
| 793 | + // tf doesn't match the font size passed to Tf, so | |
| 794 | + // substitute. | |
| 795 | + QTC::TC("qpdf", "QPDFFormFieldObjectHelper fallback Tf"); | |
| 796 | + cur = QUtil::double_to_string(tf); | |
| 797 | + } | |
| 798 | + } | |
| 799 | + result += cur; | |
| 800 | + } | |
| 801 | + return result; | |
| 802 | +} | |
| 803 | + | |
| 804 | +std::string | |
| 772 | 805 | TfFinder::getFontName() |
| 773 | 806 | { |
| 774 | 807 | return this->font_name; |
| ... | ... | @@ -843,6 +876,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance( |
| 843 | 876 | tok.write(QUtil::unsigned_char_pointer(DA.c_str()), DA.length()); |
| 844 | 877 | tok.finish(); |
| 845 | 878 | double tf = tff.getTf(); |
| 879 | + DA = tff.getDA(); | |
| 846 | 880 | |
| 847 | 881 | std::string (*encoder)(std::string const&, char) = &QUtil::utf8_to_ascii; |
| 848 | 882 | std::string font_name = tff.getFontName(); | ... | ... |
qpdf/qpdf.testcov
| ... | ... | @@ -425,3 +425,4 @@ QPDFPageDocumentHelper ignore annotation with no appearance 0 |
| 425 | 425 | QPDFFormFieldObjectHelper create AS from scratch 0 |
| 426 | 426 | QPDFFormFieldObjectHelper create AP from scratch 0 |
| 427 | 427 | QPDFFormFieldObjectHelper replaced BMC at EOF 0 |
| 428 | +QPDFFormFieldObjectHelper fallback Tf 0 | ... | ... |
qpdf/qtest/qpdf/appearances-a-more2.pdf
No preview for this file type
qpdf/qtest/qpdf/need-appearances-more2.pdf
No preview for this file type