source: git/src/avenprcore.cc @ c8fcf66

RELEASE/1.2debug-cidebug-ci-sanitisersstereowalls-data
Last change on this file since c8fcf66 was c8fcf66, checked in by Olly Betts <olly@…>, 9 years ago

src/avenprcore.cc,src/message.c,src/message.h: msg() has returned a
persistent copy of the message for decades, so the code's bound to
rely on that in some places. And there's no real reason it
shouldn't continue to as the messages are under 20KB of UTF-8 text
for any language, so lazy loading isn't worth the complication. So
remove msgPerm() and the unused msgFree() macro, and document that
msg() returns a persistent copy.

  • Property mode set to 100644
File size: 6.0 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 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#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
24
25#include <stdio.h>
26#include <stdlib.h>
27#include <limits.h>
28#include <math.h>
29#include <string.h>
30#include <ctype.h>
31#include <float.h>
32
33#include "mainfrm.h"
34
35#include "useful.h"
36#include "filename.h"
37#include "message.h"
38#include "filelist.h"
39#include "img_hosted.h"
40#include "avenprcore.h"
41#include "debug.h"
42
43#if defined __WXMSW__ || defined __WXMAC__
44# include <wx/dcprint.h>
45#else
46# include <wx/dcps.h>
47#endif
48
49layout::layout(wxPageSetupDialogData* data)
50        : show_mask(0),
51          SkipBlank(false), Border(true), Cutlines(true), Legend(true),
52          title(), datestamp(), Scale(0), rot(0), tilt(0),
53          view(PLAN), scX(1), scY(1), xMin(0), xMax(-1), yMin(0), yMax(-1),
54          pagesX(1), pagesY(1), pages(1), xOrg(0), yOrg(0), footer()
55{
56    if (data) {
57        // Printing.
58
59        // Create a temporary wxPrinterDC/wxPostScriptDC so we can get access
60        // to the size of the printable area in mm to allow us to calculate how
61        // many pages will be needed.
62#if defined __WXMSW__ || defined __WXMAC__
63        wxPrinterDC pdc(data->GetPrintData());
64#else
65        wxPostScriptDC pdc(data->GetPrintData());
66#endif
67        int width, depth;
68        pdc.GetSizeMM(&width, &depth);
69        width -= data->GetMarginBottomRight().x + data->GetMarginTopLeft().x;
70        PaperWidth = width;
71        depth -= data->GetMarginBottomRight().y + data->GetMarginTopLeft().y;
72        // Allow for the 10mm footer.
73        PaperDepth = depth - 10;
74    } else {
75        // Exporting.
76        PaperWidth = PaperDepth = 0;
77    }
78}
79
80void
81layout::pages_required() {
82    double image_dx, image_dy;
83    double image_centre_x, image_centre_y;
84    double paper_centre_x, paper_centre_y;
85
86    double allow = 21.0;
87    if (Legend) allow += 30.0;
88    double Sc = 1000 / Scale;
89    image_dx = (xMax - xMin) * Sc;
90    if (PaperWidth > 0.0) {
91        pagesX = (int)ceil((image_dx + 19.0) / PaperWidth);
92    } else {
93        /* paperwidth not fixed (eg window or roll printer/plotter) */
94        pagesX = 1;
95        PaperWidth = image_dx + 19.0;
96    }
97    paper_centre_x = (pagesX * PaperWidth) / 2;
98    image_centre_x = Sc * (xMax + xMin) / 2;
99    xOrg = paper_centre_x - image_centre_x;
100
101    image_dy = (yMax - yMin) * Sc;
102    if (PaperDepth > 0.0) {
103        pagesY = (int)ceil((image_dy + allow) / PaperDepth);
104    } else {
105        /* paperdepth not fixed (eg window or roll printer/plotter) */
106        pagesY = 1;
107        PaperDepth = image_dy + allow;
108    }
109    paper_centre_y = 20 + (pagesY * PaperDepth) / 2;
110    image_centre_y = Sc * (yMax + yMin) / 2;
111    yOrg = paper_centre_y - image_centre_y;
112
113    pages = pagesX * pagesY;
114}
115
116#define DEF_RATIO (1.0/(double)DEFAULT_SCALE)
117
118/* pick a scale which will make it fit in the desired size */
119void
120layout::pick_scale(int x, int y)
121{
122   double Sc_x, Sc_y;
123   /*    pagesY = ceil((image_dy+allow)/PaperDepth)
124    * so (image_dy+allow)/PaperDepth <= pagesY < (image_dy+allow)/PaperDepth+1
125    * so image_dy <= pagesY*PaperDepth-allow < image_dy+PaperDepth
126    * and Sc = image_dy / (yMax-yMin)
127    * so Sc <= (pagesY*PaperDepth-allow)/(yMax-yMin) < Sc+PaperDepth/(yMax-yMin)
128    */
129   Sc_x = Sc_y = DEF_RATIO;
130   if (PaperWidth > 0.0 && xMax > xMin)
131      Sc_x = (x * PaperWidth - 19.0) / (xMax - xMin);
132   if (PaperDepth > 0.0 && yMax > yMin) {
133      double allow = 21.0;
134      if (Legend) allow += 30.0;
135      Sc_y = (y * PaperDepth - allow) / (yMax - yMin);
136   }
137
138   Sc_x = min(Sc_x, Sc_y) * 0.99; /* shrink by 1% so we don't cock up */
139#if 0 /* this picks a nice (in some sense) ratio, but is too stingy */
140   double E = pow(10.0, floor(log10(Sc_x)));
141   Sc_x = floor(Sc_x / E) * E;
142#endif
143
144   double Scale_exact = 1000.0 / Sc_x;
145
146   /* trim to 2 s.f. (rounding up) */
147   double w = pow(10.0, floor(log10(Scale_exact) - 1.0));
148   Scale = ceil(Scale_exact / w) * w;
149}
150
151#if 0
152bool fBlankPage = fFalse;
153
154void print_all(MainFrm *m_parent, layout *l, device *pri) {
155    int cPasses, pass;
156    unsigned int cPagesPrinted;
157    const char *msg166;
158    int state;
159    char *p;
160    int old_charset;
161    int page, pageLim;
162    pageLim = l->pagesX*l->pagesY;
163    PaperWidth = l->PaperWidth;
164    PaperDepth = l->PaperDepth;
165    /* if no explicit Alloc, default to one pass */
166    cPasses = Pre(l->pages, l->title);
167
168    /* note down so we can switch to printer charset */
169    msg166 = msg(/*Page %d of %d*/166);
170    old_charset = select_charset(CHARSET_ISO_8859_1);
171
172    l->footer = msg(/*Survey “%s”   Page %d (of %d)   Processed on %s*/167);
173
174    cPagesPrinted = 0;
175    page = state = 0;
176    p = l->szPages;
177    while (1) {
178        if (pageLim == 1) {
179            if (page == 0)
180                page = 1;
181            else
182                page = 0; /* we've already printed the only page */
183        } else if (!*l->szPages) {
184            page++;
185            if (page > pageLim) page = 0; /* all pages printed */
186        } else {
187            page = next_page(&state, &p, pageLim);
188        }
189        SVX_ASSERT(state >= 0); /* errors should have been caught above */
190        if (page == 0) break;
191        cPagesPrinted++;
192        if (l->pages > 1) {
193            putchar('\r');
194            printf(msg166, (int)cPagesPrinted, l->pages);
195        }
196        /* don't skip the page with the legend on */
197        if (l->SkipBlank && (int)page != (l->pagesY - 1) * l->pagesX + 1) {
198            pass = -1;
199            fBlankPage = fTrue;
200        } else {
201            pass = 0;
202            fBlankPage = fFalse;
203        }
204        print_page(m_parent, l, page, pass, cPasses);
205    }
206
207    Quit();
208    select_charset(old_charset);
209}
210#endif
Note: See TracBrowser for help on using the repository browser.