[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] gwc-no-xslfo 28d5b17 04/12: Import 'group_quote_pdf_
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] gwc-no-xslfo 28d5b17 04/12: Import 'group_quote_pdf_gen_wx.cpp' changes verbatim from vz-no-xslfo |
Date: |
Sat, 27 Jan 2018 04:23:33 -0500 (EST) |
branch: gwc-no-xslfo
commit 28d5b1748a7ab848510aa3b488116c5db5ec5298
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Import 'group_quote_pdf_gen_wx.cpp' changes verbatim from vz-no-xslfo
---
group_quote_pdf_gen_wx.cpp | 556 +++++++++++++++------------------------------
1 file changed, 185 insertions(+), 371 deletions(-)
diff --git a/group_quote_pdf_gen_wx.cpp b/group_quote_pdf_gen_wx.cpp
index 4043a99..42b659c 100644
--- a/group_quote_pdf_gen_wx.cpp
+++ b/group_quote_pdf_gen_wx.cpp
@@ -28,6 +28,7 @@
#include "calendar_date.hpp" // jdn_t()
#include "data_directory.hpp" // AddDataDir()
#include "force_linking.hpp"
+#include "html.hpp"
#include "ledger.hpp"
#include "ledger_invariant.hpp"
#include "ledger_text_formats.hpp" // ledger_format()
@@ -36,6 +37,7 @@
#include "miscellany.hpp" // split_into_lines()
#include "oecumenic_enumerations.hpp" // oenum_format_style
#include "path_utility.hpp" // fs::path inserter
+#include "pdf_writer_wx.hpp"
#include "version.hpp"
#include "wx_table_generator.hpp"
#include "wx_utility.hpp" // ConvertDateToWx()
@@ -44,10 +46,7 @@
#include <boost/filesystem/path.hpp>
#include <wx/datetime.h>
-#include <wx/html/htmlcell.h>
-#include <wx/html/winpars.h>
#include <wx/image.h>
-#include <wx/pdfdc.h>
#include <cstring> // strstr()
#include <limits>
@@ -61,119 +60,28 @@ LMI_FORCE_LINKING_IN_SITU(group_quote_pdf_generator_wx)
namespace
{
-enum enum_output_mode
- {e_output_normal
- ,e_output_measure_only
- };
-
-/// Escape special XML characters in the given string, ensuring that it appears
-/// correctly inside HTML element contents. Notice that we don't need to escape
-/// quotes here as we never use the result of this function inside an HTML
-/// attribute, only inside HTML elements.
-
-wxString escape_for_html_elem(std::string const& s)
-{
- wxString const u = wxString::FromUTF8(s.c_str());
-
- wxString z;
- z.reserve(u.length());
- for(auto const& i : u)
- {
- switch(i.GetValue())
- {
- case '<': z += "<" ; break;
- case '>': z += ">" ; break;
- case '&': z += "&"; break;
- default : z += i ;
- }
- }
- return z;
-}
-
-/// Namespace for helpers used for HTML generation.
-
-namespace html
-{
-
-/// Namespace for the support HTML tags.
-///
-/// Tags are only used as template arguments, so they don't need to be defined,
-/// just declared -- and tag_info below specialized for them.
+/// Transform 's' -> '<br><br>s', but return empty string unchanged.
-namespace tag
+html::text brbr(std::string const& s)
{
+ using namespace html;
-struct b;
-struct br;
-
-} // namespace tag
-
-template<typename T>
-struct tag_info;
-
-template<>
-struct tag_info<tag::b>
-{
- static char const* get_name() { return "b"; }
- static bool has_end() { return true; }
-};
-
-template<>
-struct tag_info<tag::br>
-{
- static char const* get_name() { return "br"; }
- static bool has_end() { return false; }
-};
-
-} // namespace html
-
-/// Wrap the given text in an HTML tag if it is not empty, otherwise just
-/// return an empty string.
-///
-/// For the tags without matching closing tags, such as e.g. "<br>", wrapping
-/// the text means just prepending the tag to it. This is still done only if
-/// the text is not empty.
-
-template<typename T>
-wxString wrap_if_not_empty(wxString const& html)
-{
- wxString result;
- if(!html.empty())
- {
- result << '<' << html::tag_info<T>::get_name() << '>' << html;
- if(html::tag_info<T>::has_end())
- {
- result << "</" << html::tag_info<T>::get_name() << '>';
- }
- }
-
- return result;
+ return s.empty()
+ ? text()
+ : tag::br + tag::br + text::from(s)
+ ;
}
-/// Transform 'html' -> '<br><br>html', but return empty string unchanged.
+/// Transform 's' -> '<br><br><b>s</b>', but return empty string unchanged.
-wxString brbr(std::string const& html)
+html::text brbrb(std::string const& s)
{
- return
- wrap_if_not_empty<html::tag::br>
- (wrap_if_not_empty<html::tag::br>
- (escape_for_html_elem(html)
- )
- );
-}
-
-/// Transform 'html' -> '<br><br><b>html</b>', but return empty string
unchanged.
+ using namespace html;
-wxString brbrb(std::string const& html)
-{
- return
- wrap_if_not_empty<html::tag::br>
- (wrap_if_not_empty<html::tag::br>
- (wrap_if_not_empty<html::tag::b>
- (escape_for_html_elem(html)
- )
- )
- );
+ return s.empty()
+ ? text()
+ : tag::br + tag::br + tag::b(text::from(s))
+ ;
}
/// Generate HTML representation of a field name and value in an HTML table.
@@ -181,18 +89,27 @@ wxString brbrb(std::string const& html)
/// The HTML fragment generated by this function contains two <td> tags with
/// the given contents.
-wxString name_value_as_html_table_data
+html::text name_value_as_html_table_data
(std::string const& name
,std::string const& value
)
{
- return wxString::Format
- ("<td nowrap align=\"right\"><b>%s%s </b></td>"
- "<td>%s </td>"
- ,escape_for_html_elem(name)
- ,(value.empty() ? "" : ":")
- ,escape_for_html_elem(value)
- );
+ using namespace html;
+
+ auto const nbsp2 = text::nbsp() + text::nbsp();
+
+ return
+ tag::td[attr::nowrap][attr::align("right")]
+ (tag::b
+ (text::from(name))
+ (text::from(value.empty() ? "" : ":"))
+ (nbsp2)
+ )
+ +
+ tag::td
+ (text::from(value))
+ (nbsp2 + nbsp2)
+ ;
}
/// Simple description of a custom field, consisting of a non-empty name and a
@@ -301,100 +218,6 @@ wxImage load_image(char const* file)
return image;
}
-/// Output an image at the given scale into the PDF.
-///
-/// The scale specifies how many times the image should be shrunk:
-/// scale > 1 makes the image smaller, while scale < 1 makes it larger.
-///
-/// Updates pos_y by increasing it by the height of the specified
-/// image at the given scale.
-
-void output_image
- (wxPdfDC& pdf_dc
- ,wxImage const& image
- ,char const* image_name
- ,double scale
- ,int x
- ,int* pos_y
- ,enum_output_mode output_mode = e_output_normal
- )
-{
- int const y = wxRound(image.GetHeight() / scale);
-
- switch(output_mode)
- {
- case e_output_normal:
- {
- // Use wxPdfDocument API directly as wxDC doesn't provide a way to
- // set the image scale at PDF level and also because passing via
- // wxDC wastefully converts wxImage to wxBitmap only to convert it
- // back to wxImage when embedding it into the PDF.
- wxPdfDocument* const pdf_doc = pdf_dc.GetPdfDocument();
- LMI_ASSERT(pdf_doc);
-
- pdf_doc->SetImageScale(scale);
- pdf_doc->Image(image_name, image, x, *pos_y);
- pdf_doc->SetImageScale(1);
- }
- break;
- case e_output_measure_only:
- // Do nothing.
- break;
- default:
- {
- alarum() << "Case " << output_mode << " not found." << LMI_FLUSH;
- }
- }
-
- *pos_y += y;
-}
-
-/// Render, or just pretend rendering in order to measure it, the given HTML
-/// contents at the specified position wrapping it at the given width.
-/// Return the height of the output (using this width).
-
-int output_html
- (wxHtmlWinParser& html_parser
- ,int x
- ,int y
- ,int width
- ,wxString const& html
- ,enum_output_mode output_mode = e_output_normal
- )
-{
- std::unique_ptr<wxHtmlContainerCell> const cell
- (static_cast<wxHtmlContainerCell*>(html_parser.Parse(html))
- );
- LMI_ASSERT(cell);
-
- cell->Layout(width);
- switch(output_mode)
- {
- case e_output_normal:
- {
- wxHtmlRenderingInfo rendering_info;
- cell->Draw
- (*html_parser.GetDC()
- ,x
- ,y
- ,0
- ,std::numeric_limits<int>::max()
- ,rendering_info
- );
- }
- break;
- case e_output_measure_only:
- // Do nothing.
- break;
- default:
- {
- alarum() << "Case " << output_mode << " not found." << LMI_FLUSH;
- }
- }
-
- return cell->GetHeight();
-}
-
enum enum_group_quote_columns
{e_col_number
,e_col_name
@@ -450,52 +273,46 @@ class group_quote_pdf_generator_wx
void save(std::string const& output_filename) override;
private:
- // These margins are arbitrary and can be changed to conform to subjective
+ // This value is arbitrary and can be changed to conform to subjective
// preferences.
- static int const horz_margin = 24;
- static int const vert_margin = 36;
- static int const vert_skip = 12;
+ static int const vert_skip = 12;
// Ctor is private as it is only used by do_create().
group_quote_pdf_generator_wx() = default;
- // Generate the PDF once we have all the data.
- void do_generate_pdf(wxPdfDC& pdf_dc);
-
// Compute the number of pages needed by the table rows in the output given
// the space remaining on the first page, the heights of the header, one
// table row and the footer and the last row position.
// Remaining space contains the space on the first page on input and is
// updated with the space remaining on the last page on output.
int compute_pages_for_table_rows
- (int* remaining_space
+ (pdf_writer_wx& pdf_writer
+ ,int* remaining_space
,int header_height
,int row_height
,int last_row_y
);
void output_page_number_and_version
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,int total_pages
,int current_page
);
void output_image_header
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,int* pos_y
);
void output_document_header
- (wxPdfDC& pdf_dc
- ,wxHtmlWinParser& html_parser
+ (pdf_writer_wx& pdf_writer
,int* pos_y
);
void output_aggregate_values
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,wx_table_generator& table_gen
,int* pos_y
);
void output_footer
- (wxPdfDC& pdf_dc
- ,wxHtmlWinParser& html_parser
+ (pdf_writer_wx& pdf_writer
,int* pos_y
,enum_output_mode output_mode = e_output_normal
);
@@ -514,7 +331,7 @@ class group_quote_pdf_generator_wx
std::string premium_mode_;
std::string contract_state_;
std::string effective_date_;
- wxString footer_html_;
+ html::text footer_html_;
// Dynamically-determined fields.
std::string elected_riders_;
@@ -561,24 +378,6 @@ class group_quote_pdf_generator_wx
};
totals_data totals_;
- struct page_metrics
- {
- page_metrics()
- :width_(0)
- {
- }
-
- void initialize(wxDC const& dc)
- {
- total_size_ = dc.GetSize();
- width_ = total_size_.x - 2 * horz_margin;
- }
-
- wxSize total_size_;
- int width_;
- };
- page_metrics page_;
-
int row_num_ {0};
int individual_selection_ {99};
};
@@ -858,59 +657,20 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger
const& ledger)
void group_quote_pdf_generator_wx::save(std::string const& output_filename)
{
- // Create a wxPrintData object just to describe the paper to use.
- wxPrintData print_data;
- print_data.SetOrientation(wxLANDSCAPE);
- print_data.SetPaperId(wxPAPER_LETTER);
- print_data.SetFilename(output_filename);
-
- wxPdfDC pdf_dc(print_data);
- page_.initialize(pdf_dc);
- do_generate_pdf(pdf_dc);
- pdf_dc.EndDoc();
-}
-
-void group_quote_pdf_generator_wx::do_generate_pdf(wxPdfDC& pdf_dc)
-{
- // Ensure that the output is independent of the current display resolution:
- // it seems that this is only the case with the PDF map mode and wxDC mode
- // different from wxMM_TEXT.
- pdf_dc.SetMapModeStyle(wxPDF_MAPMODESTYLE_PDF);
-
- // For simplicity, use points for everything: font sizers are expressed in
- // them anyhow, so it's convenient to use them for everything else too.
- pdf_dc.SetMapMode(wxMM_POINTS);
-
- pdf_dc.StartDoc(wxString()); // Argument is not used.
- pdf_dc.StartPage();
-
- // Use a standard PDF Helvetica font (without embedding any custom fonts in
- // the generated file, the only other realistic choice is Times New Roman).
- pdf_dc.SetFont
- (wxFontInfo(8).Family(wxFONTFAMILY_SWISS).FaceName("Helvetica")
- );
-
- // Create an HTML parser to allow easily adding HTML contents to the
output.
- wxHtmlWinParser html_parser(nullptr);
- html_parser.SetDC(&pdf_dc);
- html_parser.SetStandardFonts
- (pdf_dc.GetFont().GetPointSize()
- ,"Helvetica"
- ,"Courier"
- );
+ pdf_writer_wx pdf_writer(output_filename, wxLANDSCAPE);
int pos_y = 0;
- output_image_header(pdf_dc, &pos_y);
+ output_image_header(pdf_writer, &pos_y);
pos_y += 2 * vert_skip;
- output_document_header(pdf_dc, html_parser, &pos_y);
+ output_document_header(pdf_writer, &pos_y);
pos_y += 2 * vert_skip;
wx_table_generator table_gen
- (pdf_dc
- ,horz_margin
- ,page_.width_
+ (pdf_writer.dc()
+ ,pdf_writer.get_horz_margin()
+ ,pdf_writer.get_page_width()
);
// Some of the table columns don't need to be shown if all the values in
@@ -976,21 +736,22 @@ void
group_quote_pdf_generator_wx::do_generate_pdf(wxPdfDC& pdf_dc)
table_gen.add_column(header, cd.widest_text_);
}
- output_aggregate_values(pdf_dc, table_gen, &pos_y);
+ output_aggregate_values(pdf_writer, table_gen, &pos_y);
int const y_before_header = pos_y;
table_gen.output_header(&pos_y);
int const header_height = pos_y - y_before_header;
int y_after_footer = pos_y;
- output_footer(pdf_dc, html_parser, &y_after_footer, e_output_measure_only);
+ output_footer(pdf_writer, &y_after_footer, e_output_measure_only);
int const footer_height = y_after_footer - pos_y;
- int const last_row_y = page_.total_size_.y - vert_margin;
+ int const last_row_y = pdf_writer.get_page_bottom();
int remaining_space = last_row_y - pos_y;
int total_pages = compute_pages_for_table_rows
- (&remaining_space
+ (pdf_writer
+ ,&remaining_space
,header_height
,table_gen.row_height()
,last_row_y
@@ -1013,38 +774,39 @@ void
group_quote_pdf_generator_wx::do_generate_pdf(wxPdfDC& pdf_dc)
if(last_row_y <= pos_y)
{
- output_page_number_and_version(pdf_dc, total_pages, current_page);
+ output_page_number_and_version(pdf_writer, total_pages,
current_page);
current_page++;
- pdf_dc.StartPage();
+ pdf_writer.dc().StartPage();
- pos_y = vert_margin;
+ pos_y = pdf_writer.get_vert_margin();
table_gen.output_header(&pos_y);
}
}
if(footer_on_its_own_page)
{
- output_page_number_and_version(pdf_dc, total_pages, current_page);
+ output_page_number_and_version(pdf_writer, total_pages, current_page);
current_page++;
- pdf_dc.StartPage();
+ pdf_writer.dc().StartPage();
- pos_y = vert_margin;
+ pos_y = pdf_writer.get_vert_margin();
}
else
{
pos_y += 2 * vert_skip;
}
- output_footer(pdf_dc, html_parser, &pos_y);
+ output_footer(pdf_writer, &pos_y);
LMI_ASSERT(current_page == total_pages);
- output_page_number_and_version(pdf_dc, total_pages, current_page);
+ output_page_number_and_version(pdf_writer, total_pages, current_page);
}
int group_quote_pdf_generator_wx::compute_pages_for_table_rows
- (int* remaining_space
+ (pdf_writer_wx& pdf_writer
+ ,int* remaining_space
,int header_height
,int row_height
,int last_row_y
@@ -1060,7 +822,8 @@ int
group_quote_pdf_generator_wx::compute_pages_for_table_rows
// rest of them.
remaining_rows -= max_rows_on_first_page;
- int const page_area_y = last_row_y - vert_margin - header_height;
+ int const first_row_y = pdf_writer.get_vert_margin() + header_height;
+ int const page_area_y = last_row_y - first_row_y;
int const rows_per_page = page_area_y / row_height;
total_pages += (remaining_rows + rows_per_page - 1) / rows_per_page;
*remaining_space = page_area_y;
@@ -1073,18 +836,20 @@ int
group_quote_pdf_generator_wx::compute_pages_for_table_rows
}
void group_quote_pdf_generator_wx::output_page_number_and_version
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,int total_pages
,int current_page
)
{
wxRect const footer_area
- (horz_margin
- ,page_.total_size_.y - vert_margin
- ,page_.width_
- ,vert_margin
+ (pdf_writer.get_horz_margin()
+ ,pdf_writer.get_page_bottom()
+ ,pdf_writer.get_page_width()
+ ,pdf_writer.get_vert_margin()
);
+ auto& pdf_dc = pdf_writer.dc();
+
pdf_dc.DrawLabel
(wxString::Format("System version: %s", LMI_VERSION)
,footer_area
@@ -1099,7 +864,7 @@ void
group_quote_pdf_generator_wx::output_page_number_and_version
}
void group_quote_pdf_generator_wx::output_image_header
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,int* pos_y
)
{
@@ -1110,15 +875,17 @@ void group_quote_pdf_generator_wx::output_image_header
}
// Set the scale to fit the image to the document width.
- double const
- scale = static_cast<double>(banner_image.GetWidth()) /
page_.total_size_.x;
+ double const image_width = banner_image.GetWidth();
+ double const scale = image_width / pdf_writer.get_total_width();
int const pos_top = *pos_y;
- output_image(pdf_dc, banner_image, "banner", scale, 0, pos_y);
+ pdf_writer.output_image(banner_image, "banner", scale, 0, pos_y);
+
+ auto& pdf_dc = pdf_writer.dc();
wxDCFontChanger set_bigger_font(pdf_dc, pdf_dc.GetFont().Scaled(1.5));
wxDCTextColourChanger set_white_text(pdf_dc, *wxWHITE);
- // Don't use escape_for_html_elem() here: instead, call
+ // Don't use html::text::from() here: instead, call
// wxString::FromUTF8() directly, e.g., to preserve literal '&'.
wxString const image_text
(wxString::FromUTF8(report_data_.short_product_.c_str())
@@ -1128,7 +895,7 @@ void group_quote_pdf_generator_wx::output_image_header
pdf_dc.DrawLabel
(image_text
,wxRect
- (wxPoint(horz_margin, (pos_top + *pos_y) / 2),
+ (wxPoint(pdf_writer.get_horz_margin(), (pos_top + *pos_y) / 2),
pdf_dc.GetMultiLineTextExtent(image_text)
)
,wxALIGN_CENTER_HORIZONTAL
@@ -1136,45 +903,53 @@ void group_quote_pdf_generator_wx::output_image_header
}
void group_quote_pdf_generator_wx::output_document_header
- (wxPdfDC& pdf_dc
- ,wxHtmlWinParser& html_parser
+ (pdf_writer_wx& pdf_writer
,int* pos_y
)
{
- wxString const title_html = wxString::Format
- ("<table width=\"100%%\">"
- "<tr>"
- "<td align=\"center\"><i><font size=\"+1\">%s</font></i></td>"
- "</tr>"
- "<tr>"
- "<td align=\"center\"><i>Prepared Date: %s</i></td>"
- "</tr>"
- "<tr>"
- "<td align=\"center\"><i>Prepared By: %s</i></td>"
- "</tr>"
- "</table>"
- ,escape_for_html_elem(report_data_.company_)
- ,wxDateTime::Today().FormatDate()
- ,escape_for_html_elem(report_data_.prepared_by_)
+ using namespace html;
+
+ auto title_html =
+ tag::table[attr::width("100%")]
+ (tag::tr
+ (tag::td[attr::align("center")]
+ (tag::i
+ (tag::font[attr::size("+1")]
+ (text::from(report_data_.company_)
+ )
+ )
+ )
+ )
+ )
+ (tag::tr
+ (tag::td[attr::align("center")]
+ (tag::i
+ (text::from
+ ("Prepared Date: "
+ +wxDateTime::Today().FormatDate().ToStdString()
+ )
+ )
+ )
+ )
+ )
+ (tag::tr
+ (tag::td[attr::align("center")]
+ (tag::i
+ (text::from("Prepared By: " +
report_data_.prepared_by_)
+ )
+ )
+ )
+ );
+
+ pdf_writer.output_html
+ (pdf_writer.get_horz_margin()
+ ,*pos_y
+ ,pdf_writer.get_page_width() / 2
+ ,title_html
);
- output_html(html_parser, horz_margin, *pos_y, page_.width_ / 2,
title_html);
-
- // Build the summary table with all the mandatory fields.
- wxString summary_html =
- "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">"
- // This extra top empty row works around a bug in wxHTML
- // table positioning code: it uses the provided ordinate
- // coordinate as a base line of the first table line and
- // not as its top, as it ought to, so without this line
- // the rectangle drawn below wouldn't contain the header.
- "<tr>"
- "<td align=\"center\" colspan=\"4\"> </td>"
- "</tr>"
- "<tr>"
- "<td align=\"center\" colspan=\"4\"><font size=\"+1\">Plan Details
Summary</font></td>"
- "</tr>"
- ;
+ // Build the summary table with all the mandatory fields, starting by
+ // building the (partly) dynamic fields rows part.
// Add fixed fields first, then any additional ones,
// in left-to-right then top-to-bottom order.
@@ -1196,34 +971,66 @@ void group_quote_pdf_generator_wx::output_document_header
std::vector<extra_summary_field> const& f = report_data_.extra_fields_;
fields.insert(fields.end(), f.begin(), f.end());
- bool parity = true;
- for(auto const& i : fields)
+ text fields_html;
+ for(std::size_t i = 0; i < fields.size(); i += 2)
{
- summary_html += parity ? "<tr>" : "";
- summary_html += name_value_as_html_table_data(i.name, i.value);
- summary_html += parity ? "" : "</tr>";
- parity = !parity;
+ auto row_html = name_value_as_html_table_data
+ (fields[i].name, fields[i].value
+ )
+ ;
+
+ if(i + 1 < fields.size())
+ {
+ row_html += name_value_as_html_table_data
+ (fields[i + 1].name, fields[i + 1].value
+ )
+ ;
+ }
+
+ fields_html += tag::tr(row_html);
}
- summary_html += parity ? "" : "</tr>";
// Finally close the summary table.
- summary_html += "</table>";
+ auto const summary_html =
+ tag::table[attr::width("100%")]
+ [attr::cellspacing("0")]
+ [attr::cellpadding("0")]
+ // This extra top empty row works around a bug in wxHTML
+ // table positioning code: it uses the provided ordinate
+ // coordinate as a base line of the first table line and
+ // not as its top, as it ought to, so without this line
+ // the rectangle drawn below wouldn't contain the header.
+ (tag::tr
+ (tag::td[attr::align("center")][attr::colspan("4")]
+ (text::nbsp())
+ )
+ )
+ (tag::tr
+ (tag::td[attr::align("center")][attr::colspan("4")]
+ (tag::font[attr::size("+1")]
+ (text::from("Plan Details Summary"))
+ )
+ )
+ )
+ (fields_html
+ )
+ ;
- int const summary_height = output_html
- (html_parser
- ,horz_margin + page_.width_ / 2
+ int const summary_height = pdf_writer.output_html
+ (pdf_writer.get_horz_margin() + pdf_writer.get_page_width() / 2
,*pos_y
- ,page_.width_ / 2
+ ,pdf_writer.get_page_width() / 2
,summary_html
);
// wxHTML tables don't support "frame" attribute, so draw the border around
// the table manually.
+ auto& pdf_dc = pdf_writer.dc();
pdf_dc.SetBrush(*wxTRANSPARENT_BRUSH);
pdf_dc.DrawRectangle
- (horz_margin + page_.width_ / 2
+ (pdf_writer.get_horz_margin() + pdf_writer.get_page_width() / 2
,*pos_y
- ,page_.width_ / 2
+ ,pdf_writer.get_page_width() / 2
,summary_height
);
@@ -1231,7 +1038,7 @@ void group_quote_pdf_generator_wx::output_document_header
}
void group_quote_pdf_generator_wx::output_aggregate_values
- (wxPdfDC& pdf_dc
+ (pdf_writer_wx& pdf_writer
,wx_table_generator& table_gen
,int* pos_y
)
@@ -1248,6 +1055,8 @@ void group_quote_pdf_generator_wx::output_aggregate_values
table_gen.output_vert_separator(e_col_number, y);
table_gen.output_vert_separator(e_col_number, y_next);
+ auto& pdf_dc = pdf_writer.dc();
+
// Render "Census" in bold.
wxDCFontChanger set_bold_font(pdf_dc, pdf_dc.GetFont().Bold());
pdf_dc.DrawLabel
@@ -1364,8 +1173,7 @@ void group_quote_pdf_generator_wx::output_aggregate_values
}
void group_quote_pdf_generator_wx::output_footer
- (wxPdfDC& pdf_dc
- ,wxHtmlWinParser& html_parser
+ (pdf_writer_wx& pdf_writer
,int* pos_y
,enum_output_mode output_mode
)
@@ -1375,18 +1183,24 @@ void group_quote_pdf_generator_wx::output_footer
{
// Arbitrarily scale down the logo by a factor of 2 to avoid making it
// too big.
- output_image(pdf_dc, logo_image, "company_logo", 2.0, horz_margin,
pos_y, output_mode);
+ pdf_writer.output_image
+ (logo_image
+ ,"company_logo"
+ ,2.0
+ ,pdf_writer.get_horz_margin()
+ ,pos_y
+ ,output_mode
+ );
*pos_y += vert_skip;
}
- wxString const footer_html = "<p>" + report_data_.footer_html_ + "</p>";
+ auto footer_html = html::tag::p(report_data_.footer_html_);
- *pos_y += output_html
- (html_parser
- ,horz_margin
+ *pos_y += pdf_writer.output_html
+ (pdf_writer.get_horz_margin()
,*pos_y
- ,page_.width_
+ ,pdf_writer.get_page_width()
,footer_html
,output_mode
);
- [lmi-commits] [lmi] gwc-no-xslfo 4a983d0 01/12: Import makefile changes verbatim from vz-no-xslfo, (continued)
- [lmi-commits] [lmi] gwc-no-xslfo 4a983d0 01/12: Import makefile changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo ec4fcc0 07/12: Restore vz-no-xslfo deletions, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo c216db3 05/12: Allow 'PDF !!' markers, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 90d858b 10/12: Import 'emit_ledger.cpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo adb7ff0 11/12: Restore a deleted header, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 89df28a 06/12: Import 'ledger.hpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 88cc286 08/12: Import 'main_wx*.cpp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo f294831 09/12: Mark some deferred PDF issues, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo aec2811 12/12: Enable old and new PDF implementations to coexist, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 4fcbd32 03/12: Import 'wx_table_generator.?pp' changes verbatim from vz-no-xslfo, Greg Chicares, 2018/01/27
- [lmi-commits] [lmi] gwc-no-xslfo 28d5b17 04/12: Import 'group_quote_pdf_gen_wx.cpp' changes verbatim from vz-no-xslfo,
Greg Chicares <=