source: git/src/avenprcore.cc

walls-data
Last change on this file was 4c83f84, checked in by Olly Betts <olly@…>, 5 days ago

Don't check HAVE_CONFIG_H in most cases

This check is only useful for img.c, which is intended to be usable
outside of Survex (and had fallbacks for functions which may not be
available which will get used if built in a non-autotools project).
For all the other source files it's just useless boilerplate.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/* avenprcore.cc
2 * Printer independent parts of Survex printer drivers
3 * Copyright (C) 1993-2002,2004,2005,2006,2010,2011,2012,2013,2014,2015,2016 Olly Betts
4 * Copyright (C) 2004 Philip Underwood
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 */
20
21#include <config.h>
22
23#include <algorithm>
24#include <math.h>
25
26#include "useful.h"
27#include "avenprcore.h"
28
29#if defined __WXMSW__ || defined __WXMAC__
30# include <wx/dcprint.h>
31#else
32# include <wx/dcps.h>
33#endif
34#include <wx/print.h>
35
36layout::layout(wxPageSetupDialogData* data)
37        : show_mask(0),
38          SkipBlank(false), Border(true), Cutlines(true), Legend(true),
39          title(), datestamp(), Scale(0), rot(0), tilt(0),
40          view(PLAN), scX(1), scY(1), xMin(0), xMax(-1), yMin(0), yMax(-1),
41          pagesX(1), pagesY(1), pages(1), xOrg(0), yOrg(0)
42{
43    if (data) {
44        // Printing.
45
46        // Create a temporary wxPrinterDC/wxPostScriptDC so we can get access
47        // to the size of the printable area in mm to allow us to calculate how
48        // many pages will be needed.
49        //
50        // It may seem like data->GetPaperSize() would tell us this page size
51        // without having to construct a temporary DC, but that just returns
52        // (0, 0) for the size, at least with wxGTK 3.0.2.
53#if defined __WXMSW__ || defined __WXMAC__
54        wxPrinterDC pdc(data->GetPrintData());
55#else
56        wxPostScriptDC pdc(data->GetPrintData());
57#endif
58        // Calculate the size of the printable area in mm to allow us to work
59        // out how many pages will be needed for a given scale.
60        wxSize size = pdc.GetSizeMM();
61        size.DecBy(data->GetMarginBottomRight());
62        size.DecBy(data->GetMarginTopLeft());
63        PaperWidth = size.x;
64        // Allow for our footer.
65        PaperDepth = size.y - FOOTER_HEIGHT_MM;
66    } else {
67        // Exporting.
68        PaperWidth = PaperDepth = 0;
69    }
70}
71
72void
73layout::pages_required() {
74    double image_dx, image_dy;
75    double image_centre_x, image_centre_y;
76    double paper_centre_x, paper_centre_y;
77
78    double allow = 21.0;
79    if (Legend) allow += 30.0;
80    double Sc = 1000 / Scale;
81    image_dx = (xMax - xMin) * Sc;
82    if (PaperWidth > 0.0) {
83        pagesX = (int)ceil((image_dx + 19.0) / PaperWidth);
84    } else {
85        /* paperwidth not fixed (eg window or roll printer/plotter) */
86        pagesX = 1;
87        PaperWidth = image_dx + 19.0;
88    }
89    paper_centre_x = (pagesX * PaperWidth) / 2;
90    image_centre_x = Sc * (xMax + xMin) / 2;
91    xOrg = paper_centre_x - image_centre_x;
92
93    image_dy = (yMax - yMin) * Sc;
94    if (PaperDepth > 0.0) {
95        pagesY = (int)ceil((image_dy + allow) / PaperDepth);
96    } else {
97        /* paperdepth not fixed (eg window or roll printer/plotter) */
98        pagesY = 1;
99        PaperDepth = image_dy + allow;
100    }
101    paper_centre_y = 20 + (pagesY * PaperDepth) / 2;
102    image_centre_y = Sc * (yMax + yMin) / 2;
103    yOrg = paper_centre_y - image_centre_y;
104
105    pages = pagesX * pagesY;
106}
107
108#define DEF_RATIO (1.0/(double)DEFAULT_SCALE)
109
110/* pick a scale which will make it fit in the desired size */
111void
112layout::pick_scale(int x, int y)
113{
114   pagesX = x;
115   pagesY = y;
116   pages = x * y;
117
118   double Sc_x, Sc_y;
119   /*    pagesY = ceil((image_dy+allow)/PaperDepth)
120    * so (image_dy+allow)/PaperDepth <= pagesY < (image_dy+allow)/PaperDepth+1
121    * so image_dy <= pagesY*PaperDepth-allow < image_dy+PaperDepth
122    * and Sc = image_dy / (yMax-yMin)
123    * so Sc <= (pagesY*PaperDepth-allow)/(yMax-yMin) < Sc+PaperDepth/(yMax-yMin)
124    */
125   Sc_x = Sc_y = DEF_RATIO;
126   if (PaperWidth > 0.0 && xMax > xMin)
127      Sc_x = (x * PaperWidth - 19.0) / (xMax - xMin);
128   if (PaperDepth > 0.0 && yMax > yMin) {
129      double allow = 21.0;
130      if (Legend) allow += 30.0;
131      Sc_y = (y * PaperDepth - allow) / (yMax - yMin);
132   }
133
134   Sc_x = std::min(Sc_x, Sc_y) * 0.99; /* shrink by 1% so we don't cock up */
135#if 0 /* this picks a nice (in some sense) ratio, but is too stingy */
136   double E = pow(10.0, floor(log10(Sc_x)));
137   Sc_x = floor(Sc_x / E) * E;
138#endif
139
140   double Scale_exact = 1000.0 / Sc_x;
141
142   /* trim to 2 s.f. (rounding up) */
143   double w = pow(10.0, floor(log10(Scale_exact) - 1.0));
144   Scale = ceil(Scale_exact / w) * w;
145}
Note: See TracBrowser for help on using the repository browser.