[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master f950086 07/10: Split some code into new sourc
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master f950086 07/10: Split some code into new source files, adding an inchoate unit test |
Date: |
Fri, 27 Jul 2018 17:03:56 -0400 (EDT) |
branch: master
commit f95008675833861e5e62632b6eb9183ca1523c11
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Split some code into new source files, adding an inchoate unit test
---
Makefile.am | 9 ++
objects.make | 7 ++
report_table.cpp | 232 ++++++++++++++++++++++++++++++++++++++
report_table.hpp | 120 ++++++++++++++++++++
report_table_test.cpp | 31 ++++++
wx_table_generator.cpp | 294 -------------------------------------------------
wx_table_generator.hpp | 3 +-
7 files changed, 400 insertions(+), 296 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index c9d159a..bd2fcdb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -130,6 +130,7 @@ TESTS = \
test_progress_meter \
test_rate_table \
test_regex \
+ test_report_table \
test_round \
test_round_to \
test_rtti_lmi \
@@ -423,6 +424,7 @@ liblmi_la_SOURCES = \
mortality_rates_fetch.cpp \
preferences_model.cpp \
product_data.cpp \
+ report_table.cpp \
rounding_rules.cpp \
stratified_algorithms.cpp \
stratified_charges.cpp \
@@ -1004,6 +1006,12 @@ test_regex_CXXFLAGS = $(AM_CXXFLAGS)
test_regex_LDADD = \
$(BOOST_LIBS)
+test_report_table_SOURCES = \
+ $(common_test_objects) \
+ report_table.cpp \
+ report_table_test.cpp
+test_report_table_CXXFLAGS = $(AM_CXXFLAGS)
+
test_round_SOURCES = \
$(common_test_objects) \
round_glibc.cpp \
@@ -1281,6 +1289,7 @@ noinst_HEADERS = \
product_data.hpp \
product_editor.hpp \
progress_meter.hpp \
+ report_table.hpp \
round_to.hpp \
rounding_document.hpp \
rounding_rules.hpp \
diff --git a/objects.make b/objects.make
index baec96a..964b70e 100644
--- a/objects.make
+++ b/objects.make
@@ -309,6 +309,7 @@ lmi_common_objects := \
mortality_rates_fetch.o \
preferences_model.o \
product_data.o \
+ report_table.o \
rounding_rules.o \
stratified_algorithms.o \
stratified_charges.o \
@@ -453,6 +454,7 @@ unit_test_targets := \
progress_meter_test \
rate_table_test \
regex_test \
+ report_table_test \
round_test \
round_to_test \
rtti_lmi_test \
@@ -888,6 +890,11 @@ regex_test$(EXEEXT): \
regex_test.o \
timer.o \
+report_table_test$(EXEEXT): \
+ $(common_test_objects) \
+ report_table.o \
+ report_table_test.o \
+
round_test$(EXEEXT): \
$(common_test_objects) \
round_glibc.o \
diff --git a/report_table.cpp b/report_table.cpp
new file mode 100644
index 0000000..53b68f7
--- /dev/null
+++ b/report_table.cpp
@@ -0,0 +1,232 @@
+// Platform-independent support for report tables.
+//
+// Copyright (C) 2015, 2016, 2017, 2018 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#include "pchfile.hpp"
+
+#include "report_table.hpp"
+
+#include "alert.hpp"
+#include "math_functions.hpp" // outward_quotient()
+
+/// Compute column widths.
+///
+/// First, allocate adequate width to each inelastic column; then
+/// distribute any excess width left over among elastic columns.
+///
+/// The width of each inelastic column reflects:
+/// - a mask like "999,999" (ideally, there would instead be a
+/// quasi-global data structure mapping symbolic column names
+/// to their corresponding headers and maximal widths)
+/// - the header width
+/// - PDF !! the bilateral margins added as a first step below
+/// The margins may be slightly reduced by this function to make
+/// everything fit when it otherwise wouldn't.
+
+void set_column_widths
+ (int total_width
+ ,int & column_margin
+ ,std::vector<table_column_info>& all_columns
+ )
+//
+// const total_width max table width (page width - page margins)
+// mutable column_margin spacing on both left and right of column
+// mutable all_columns std::vector<table_column_info>
+// table_column_info::col_width_ is the only member changed
+{
+ // PDF !! Unconditionally add bilateral margins even though they
+ // may conditionally be removed below. This is a questionable
+ // design decision; if it is later reversed, then remove the
+ // comment about it above the implementation.
+ for(auto& i : all_columns)
+ {
+ if(!i.is_hidden() && !i.is_elastic())
+ {
+ i.col_width_ += 2 * column_margin;
+ }
+ }
+
+ // Number of non-hidden columns.
+ int number_of_columns = 0;
+
+ // Number of non-hidden elastic columns.
+ int number_of_elastic_columns = 0;
+
+ // Total width of all non-hidden inelastic columns.
+ int total_inelastic_width = 0;
+
+ for(auto const& i : all_columns)
+ {
+ if(i.is_hidden())
+ {
+ continue;
+ }
+
+ ++number_of_columns;
+
+ if(i.is_elastic())
+ {
+ ++number_of_elastic_columns;
+ }
+ else
+ {
+ total_inelastic_width += i.col_width();
+ }
+ }
+
+ if(total_width < total_inelastic_width)
+ {
+ // The inelastic columns don't all fit with their original
+ // one-em presumptive bilateral margins. Try to make them fit
+ // by reducing the margins slightly.
+ //
+ // The number of pixels that would need to be removed is:
+ auto const overflow = total_inelastic_width - total_width;
+
+ // Because inelastic columns take more than the available
+ // horizontal space, there's no room to fit any elastic
+ // columns, so the column-fitting problem is overconstrained.
+ // Therefore, don't even try reducing margins if there are any
+ // elastic columns.
+ if(!number_of_elastic_columns)
+ {
+// Also calculate the number of pixels by which it overflows for each column
+ // We need to round up in division here to be sure that all columns
+ // fit into the available width.
+ auto const overflow_per_column = outward_quotient
+ (overflow
+ ,number_of_columns
+ );
+// Now determine whether reducing the margins will make the table fit.
+// If that works, then do it; else don't do it, and print a warning.
+//
+// column_margin is the padding on each side of every column, so
+// the number of pixels between columns, as the table was originally
+// laid out, is two times column_margin--which, as we just determined,
+// was too generous, so we're going to try reducing it.
+// Then this conditional compares
+// the number of pixels by which we must shrink each column, to
+// the number of pixels of padding between columns
+// Reducing the padding is a workable strategy if the desired reduction
+// is less than the padding.
+//
+// Is this as good as it can be, given that coordinates are integers?
+// Answer: Yes--the integers count points, not ems or characters, and
+// typographers wouldn't use any finer unit for this task.
+ if(overflow_per_column <= 2 * column_margin)
+ {
+ // We are going to reduce the total width by more than
+ // necessary, in general, because of rounding up above, so
+ // compensate for it by giving 1 extra pixel until we run out
+ // of these "underflow" pixels.
+// Defect: the number of pixels separating columns might now be zero.
+// '9' is five PDF pixels wide; do we need, say, two pixels between columns?
+//
+// Suggestion: change the
+// overflow_per_column <= column_margin
+// condition to something like:
+// overflow_per_column <= column_margin - 4 // two pixels on each side
+// overflow_per_column <= column_margin - 2 // one pixel on each side
+ auto underflow = overflow_per_column * number_of_columns -
overflow;
+
+ for(auto& i : all_columns)
+ {
+ if(i.is_hidden())
+ {
+ continue;
+ }
+
+ i.col_width_ -= overflow_per_column;
+
+ if(0 < underflow)
+ {
+ ++i.col_width_;
+ --underflow;
+ }
+ }
+
+ column_margin -= (overflow_per_column + 1) / 2;
+
+ // We condensed the columns enough to make them fit, so no need
+ // for the warning and we don't have any elastic columns, so
+ // we're done.
+ return;
+ }
+// If overflow_per_column is 1, then column_margin -= 1
+// " " " 2, " " 1
+// " " " 3, " " 2
+// " " " 4, " " 2
+// The 'underflow' logic shrinks columns by the exact number of pixels
+// to use up all the available width. But the column_margin reduction
+// isn't exact due to truncation: when the margin is added (on both sides),
+// is the total of all (margin+column+margin) widths lower than the maximum,
+// so that this is just a small aesthetic issue, or is it too wide, so that
+// not everything fits?
+//
+// Answer:
+// This is an issue of aligning the column text, not of fitting, because the
+// margin is used when positioning the text inside the column width. And the
+// width is correct, so the worst that can happen here is that the text is
+// offset by 0.5 pixels -- but, of course, if we rounded it down, it would be
+// offset by 0.5 pixels in the other direction. So maybe we should write
+//
+// column_margin -= overflow_per_column / 2;
+//
+// just because it's shorter and not necessarily worse (nor better).
+ }
+
+ warning()
+ << "Not enough space for all " << number_of_columns << " columns."
+ << "\nPrintable width is " << total_width << " points."
+ << "\nData alone require " << total_inelastic_width - 2 *
column_margin * number_of_columns
+ << " points without any margins for legibility."
+ << "\nColumn margins of " << column_margin << " points on both
sides"
+ << " would take up " << 2 * column_margin * number_of_columns << "
additional points."
+ << LMI_FLUSH
+ ;
+ return;
+ }
+
+ // Lay out elastic columns in whatever space is left over after
+ // accounting for all inelastic columns. Clip to make them fit.
+ //
+ // If there's more than enough space for them, then expand them
+ // to consume all available space.
+ if(number_of_elastic_columns)
+ {
+ int const width_of_each_elastic_column = outward_quotient
+ (total_width - total_inelastic_width
+ ,number_of_elastic_columns
+ );
+
+ for(auto& i : all_columns)
+ {
+ if(i.is_hidden())
+ {
+ continue;
+ }
+
+ if(i.is_elastic())
+ {
+ i.col_width_ = width_of_each_elastic_column;
+ }
+ }
+ }
+}
diff --git a/report_table.hpp b/report_table.hpp
new file mode 100644
index 0000000..e337f6e
--- /dev/null
+++ b/report_table.hpp
@@ -0,0 +1,120 @@
+// Platform-independent support for report tables.
+//
+// Copyright (C) 2015, 2016, 2017, 2018 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#ifndef report_table_hpp
+#define report_table_hpp
+
+#include "config.hpp"
+
+#include "oecumenic_enumerations.hpp"
+#include "so_attributes.hpp"
+
+#include <string>
+#include <vector>
+
+// Elasticity and clipping
+//
+// Most columns are inelastic: they have a fixed minimum width and
+// are not clipped lest crucial information (e.g., part of a number)
+// be lost. The archetypal elastic column is a personal name, whose
+// width is practically unlimited and might even exceed the total page
+// width; it is better to truncate one extremely long personal name
+// than to present an error message and produce no report at all.
+//
+// An ideal report generator might call GetTextExtent() on every row
+// of data to determine a column's ideal width, but this one favors
+// speed by setting a presumptive maximum width for each column.
+// Therefore, it treats a personal-name column as having no natural
+// width at all. Its minimum width might be set equal to its header
+// width, but such a refinement is needless in the problem domain. In
+// the most extreme case, all inelastic columns would fit, but there
+// would be not a single pixel available for elastic columns, which
+// would all in effect be dropped; again, in the problem domain, that
+// would actually be preferable to failing to produce any output.
+//
+// Therefore, elastic columns are clipped, and inelastic ones are not.
+// All other column properties are independent, and specified by
+// arguments, but clipping depends on the elasticity argument. It is
+// distinguished only because clipping is a distinct layout operation.
+//
+// - is_hidden(): Data for every row of all potential columns are
+// passed into this class; hidden columns are suppressed so that
+// they don't appear in the output at all.
+//
+// - is_elastic(): An elastic column has no innate fixed or preferred
+// width. After all inelastic columns have claimed their required
+// widths, any remaining width available is prorated among elastic
+// columns, which therefore may be wider than their widest contents
+// or narrower than their narrowest. As a consequence, elastic
+// columns are clipped--vide supra.
+//
+// - is_clipped(): A clipped column is truncated to fit its allotted
+// space. Only elastic columns are clipped--vide supra.
+
+class LMI_SO table_column_info
+{
+ public:
+ table_column_info
+ (std::string const& header
+ ,int width
+ ,oenum_h_align const alignment
+ ,oenum_visibility const visibility
+ ,oenum_elasticity const elasticity
+ )
+ :col_header_ (header)
+ ,col_width_ (width)
+ ,alignment_ (alignment)
+ ,is_hidden_ (oe_hidden == visibility)
+ ,is_elastic_ (oe_elastic == elasticity)
+ {
+ }
+
+ std::string const& col_header() const {return col_header_;}
+ int col_width() const {return col_width_;}
+ oenum_h_align alignment() const {return alignment_;}
+ bool is_hidden() const {return is_hidden_;}
+ bool is_elastic() const {return is_elastic_;}
+ bool is_clipped() const {return is_elastic();}
+
+ private:
+ std::string const col_header_;
+
+ public:
+ // PDF !! Modified directly by set_column_widths(), hence neither
+ // private nor const.
+ //
+ // Width in pixels. Because the wxPdfDC uses wxMM_POINTS, each
+ // pixel is one point = 1/72 inch.
+ int col_width_;
+
+ private:
+ oenum_h_align const alignment_;
+ bool const is_hidden_;
+ bool const is_elastic_;
+};
+
+void LMI_SO set_column_widths
+ (int total_width
+ ,int & column_margin
+ ,std::vector<table_column_info>& all_columns
+ );
+
+#endif // report_table_hpp
diff --git a/report_table_test.cpp b/report_table_test.cpp
new file mode 100644
index 0000000..178ef8e
--- /dev/null
+++ b/report_table_test.cpp
@@ -0,0 +1,31 @@
+// Platform-independent support for report tables: unit test.
+//
+// Copyright (C) 2018 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+#include "pchfile.hpp"
+
+#include "report_table.hpp"
+
+#include "test_tools.hpp"
+
+int test_main(int, char*[])
+{
+ return EXIT_SUCCESS;
+}
diff --git a/wx_table_generator.cpp b/wx_table_generator.cpp
index a074477..59c5569 100644
--- a/wx_table_generator.cpp
+++ b/wx_table_generator.cpp
@@ -23,9 +23,7 @@
#include "wx_table_generator.hpp"
-#include "alert.hpp"
#include "assert_lmi.hpp"
-#include "math_functions.hpp" // outward_quotient()
#include "miscellany.hpp" // count_newlines(), split_into_lines()
#include <algorithm> // max()
@@ -33,93 +31,6 @@
// Default size of various characters for illustrations and group quotes:
// 'M' 7pt; 'N' 6pt; '1' 4pt; '9' 4pt; ',' 2pt
-// Elasticity and clipping
-//
-// Most columns are inelastic: they have a fixed minimum width and
-// are not clipped lest crucial information (e.g., part of a number)
-// be lost. The archetypal elastic column is a personal name, whose
-// width is practically unlimited and might even exceed the total page
-// width; it is better to truncate one extremely long personal name
-// than to present an error message and produce no report at all.
-//
-// An ideal report generator might call GetTextExtent() on every row
-// of data to determine a column's ideal width, but this one favors
-// speed by setting a presumptive maximum width for each column.
-// Therefore, it treats a personal-name column as having no natural
-// width at all. Its minimum width might be set equal to its header
-// width, but such a refinement is needless in the problem domain. In
-// the most extreme case, all inelastic columns would fit, but there
-// would be not a single pixel available for elastic columns, which
-// would all in effect be dropped; again, in the problem domain, that
-// would actually be preferable to failing to produce any output.
-//
-// Therefore, elastic columns are clipped, and inelastic ones are not.
-// All other column properties are independent, and specified by
-// arguments, but clipping depends on the elasticity argument. It is
-// distinguished only because clipping is a distinct layout operation.
-//
-// - is_hidden(): Data for every row of all potential columns are
-// passed into this class; hidden columns are suppressed so that
-// they don't appear in the output at all.
-//
-// - is_elastic(): An elastic column has no innate fixed or preferred
-// width. After all inelastic columns have claimed their required
-// widths, any remaining width available is prorated among elastic
-// columns, which therefore may be wider than their widest contents
-// or narrower than their narrowest. As a consequence, elastic
-// columns are clipped--vide supra.
-//
-// - is_clipped(): A clipped column is truncated to fit its allotted
-// space. Only elastic columns are clipped--vide supra.
-
-class table_column_info
-{
- public:
- table_column_info
- (std::string const& header
- ,int width
- ,oenum_h_align const alignment
- ,oenum_visibility const visibility
- ,oenum_elasticity const elasticity
- )
- :col_header_ (header)
- ,col_width_ (width)
- ,alignment_ (alignment)
- ,is_hidden_ (oe_hidden == visibility)
- ,is_elastic_ (oe_elastic == elasticity)
- {
- }
-
- std::string const& col_header() const {return col_header_;}
- int col_width() const {return col_width_;}
- oenum_h_align alignment() const {return alignment_;}
- bool is_hidden() const {return is_hidden_;}
- bool is_elastic() const {return is_elastic_;}
- bool is_clipped() const {return is_elastic();}
-
- private:
- std::string const col_header_;
-
- public:
- // PDF !! Modified directly by set_column_widths(), hence neither
- // private nor const.
- //
- // Width in pixels. Because the wxPdfDC uses wxMM_POINTS, each
- // pixel is one point = 1/72 inch.
- int col_width_;
-
- private:
- oenum_h_align const alignment_;
- bool const is_hidden_;
- bool const is_elastic_;
-};
-
-void set_column_widths
- (int total_width
- ,int & column_margin
- ,std::vector<table_column_info>& all_columns
- );
-
wx_table_generator::wx_table_generator
(group_quote_style_tag // tag not referenced
,std::vector<column_parameters> const& vc
@@ -505,211 +416,6 @@ LMI_ASSERT(std::size_t(h / lh) == 1u +
count_newlines(z.header));
);
}
-/// Compute column widths.
-///
-/// First, allocate adequate width to each inelastic column; then
-/// distribute any excess width left over among elastic columns.
-///
-/// The width of each inelastic column reflects:
-/// - a mask like "999,999" (ideally, there would instead be a
-/// quasi-global data structure mapping symbolic column names
-/// to their corresponding headers and maximal widths)
-/// - the header width
-/// - PDF !! the bilateral margins added as a first step below
-/// The margins may be slightly reduced by this function to make
-/// everything fit when it otherwise wouldn't.
-
-void set_column_widths
- (int total_width
- ,int & column_margin
- ,std::vector<table_column_info>& all_columns
- )
-//
-// const total_width max table width (page width - page margins)
-// mutable column_margin spacing on both left and right of column
-// mutable all_columns std::vector<table_column_info>
-// table_column_info::col_width_ is the only member changed
-{
- // PDF !! Unconditionally add bilateral margins even though they
- // may conditionally be removed below. This is a questionable
- // design decision; if it is later reversed, then remove the
- // comment about it above the implementation.
- for(auto& i : all_columns)
- {
- if(!i.is_hidden() && !i.is_elastic())
- {
- i.col_width_ += 2 * column_margin;
- }
- }
-
- // Number of non-hidden columns.
- int number_of_columns = 0;
-
- // Number of non-hidden elastic columns.
- int number_of_elastic_columns = 0;
-
- // Total width of all non-hidden inelastic columns.
- int total_inelastic_width = 0;
-
- for(auto const& i : all_columns)
- {
- if(i.is_hidden())
- {
- continue;
- }
-
- ++number_of_columns;
-
- if(i.is_elastic())
- {
- ++number_of_elastic_columns;
- }
- else
- {
- total_inelastic_width += i.col_width();
- }
- }
-
- if(total_width < total_inelastic_width)
- {
- // The inelastic columns don't all fit with their original
- // one-em presumptive bilateral margins. Try to make them fit
- // by reducing the margins slightly.
- //
- // The number of pixels that would need to be removed is:
- auto const overflow = total_inelastic_width - total_width;
-
- // Because inelastic columns take more than the available
- // horizontal space, there's no room to fit any elastic
- // columns, so the column-fitting problem is overconstrained.
- // Therefore, don't even try reducing margins if there are any
- // elastic columns.
- if(!number_of_elastic_columns)
- {
-// Also calculate the number of pixels by which it overflows for each column
- // We need to round up in division here to be sure that all columns
- // fit into the available width.
- auto const overflow_per_column = outward_quotient
- (overflow
- ,number_of_columns
- );
-// Now determine whether reducing the margins will make the table fit.
-// If that works, then do it; else don't do it, and print a warning.
-//
-// column_margin is the padding on each side of every column, so
-// the number of pixels between columns, as the table was originally
-// laid out, is two times column_margin--which, as we just determined,
-// was too generous, so we're going to try reducing it.
-// Then this conditional compares
-// the number of pixels by which we must shrink each column, to
-// the number of pixels of padding between columns
-// Reducing the padding is a workable strategy if the desired reduction
-// is less than the padding.
-//
-// Is this as good as it can be, given that coordinates are integers?
-// Answer: Yes--the integers count points, not ems or characters, and
-// typographers wouldn't use any finer unit for this task.
- if(overflow_per_column <= 2 * column_margin)
- {
- // We are going to reduce the total width by more than
- // necessary, in general, because of rounding up above, so
- // compensate for it by giving 1 extra pixel until we run out
- // of these "underflow" pixels.
-// Defect: the number of pixels separating columns might now be zero.
-// '9' is five PDF pixels wide; do we need, say, two pixels between columns?
-//
-// Suggestion: change the
-// overflow_per_column <= column_margin
-// condition to something like:
-// overflow_per_column <= column_margin - 4 // two pixels on each side
-// overflow_per_column <= column_margin - 2 // one pixel on each side
- auto underflow = overflow_per_column * number_of_columns -
overflow;
-
- for(auto& i : all_columns)
- {
- if(i.is_hidden())
- {
- continue;
- }
-
- i.col_width_ -= overflow_per_column;
-
- if(0 < underflow)
- {
- ++i.col_width_;
- --underflow;
- }
- }
-
- column_margin -= (overflow_per_column + 1) / 2;
-
- // We condensed the columns enough to make them fit, so no need
- // for the warning and we don't have any elastic columns, so
- // we're done.
- return;
- }
-// If overflow_per_column is 1, then column_margin -= 1
-// " " " 2, " " 1
-// " " " 3, " " 2
-// " " " 4, " " 2
-// The 'underflow' logic shrinks columns by the exact number of pixels
-// to use up all the available width. But the column_margin reduction
-// isn't exact due to truncation: when the margin is added (on both sides),
-// is the total of all (margin+column+margin) widths lower than the maximum,
-// so that this is just a small aesthetic issue, or is it too wide, so that
-// not everything fits?
-//
-// Answer:
-// This is an issue of aligning the column text, not of fitting, because the
-// margin is used when positioning the text inside the column width. And the
-// width is correct, so the worst that can happen here is that the text is
-// offset by 0.5 pixels -- but, of course, if we rounded it down, it would be
-// offset by 0.5 pixels in the other direction. So maybe we should write
-//
-// column_margin -= overflow_per_column / 2;
-//
-// just because it's shorter and not necessarily worse (nor better).
- }
-
- warning()
- << "Not enough space for all " << number_of_columns << " columns."
- << "\nPrintable width is " << total_width << " points."
- << "\nData alone require " << total_inelastic_width - 2 *
column_margin * number_of_columns
- << " points without any margins for legibility."
- << "\nColumn margins of " << column_margin << " points on both
sides"
- << " would take up " << 2 * column_margin * number_of_columns << "
additional points."
- << LMI_FLUSH
- ;
- return;
- }
-
- // Lay out elastic columns in whatever space is left over after
- // accounting for all inelastic columns. Clip to make them fit.
- //
- // If there's more than enough space for them, then expand them
- // to consume all available space.
- if(number_of_elastic_columns)
- {
- int const width_of_each_elastic_column = outward_quotient
- (total_width - total_inelastic_width
- ,number_of_elastic_columns
- );
-
- for(auto& i : all_columns)
- {
- if(i.is_hidden())
- {
- continue;
- }
-
- if(i.is_elastic())
- {
- i.col_width_ = width_of_each_elastic_column;
- }
- }
- }
-}
-
void wx_table_generator::do_output_single_row
(int& pos_x
,int& pos_y
diff --git a/wx_table_generator.hpp b/wx_table_generator.hpp
index af79c07..de075ed 100644
--- a/wx_table_generator.hpp
+++ b/wx_table_generator.hpp
@@ -25,6 +25,7 @@
#include "config.hpp"
#include "oecumenic_enumerations.hpp"
+#include "report_table.hpp" // table_column_info
#include <wx/dc.h>
#include <wx/font.h>
@@ -33,8 +34,6 @@
#include <string>
#include <vector>
-class table_column_info;
-
/// Aggregate of per-column table-generator ctor arguments.
struct column_parameters
- [lmi-commits] [lmi] master updated (da8e769 -> caaecd8), Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master e30fcc9 01/10: Transplant code that adds bilateral column margins, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master 1430c70 03/10: Consolidate documentation, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master 521d3c4 04/10: Improve documentation, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master 3b4357b 05/10: Consolidate documentation, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master 6d64140 02/10: Rename class wx_table_generator::column_info --> table_column_info, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master caaecd8 10/10: Fix defect introduced 20180723T1356Z: passkey not updated, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master a525e18 08/10: Reformat a block comment, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master 74183c6 09/10: Augment unit test, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master f89e234 06/10: Replace a member with a free function, Greg Chicares, 2018/07/27
- [lmi-commits] [lmi] master f950086 07/10: Split some code into new source files, adding an inchoate unit test,
Greg Chicares <=