source: git/src/printwin.c @ bd58a74

RELEASE/1.0RELEASE/1.1RELEASE/1.2debug-cidebug-ci-sanitisersfaster-cavernloglog-selectstereowalls-datawalls-data-hanging-as-warningwarn-only-for-hanging-survey
Last change on this file since bd58a74 was bd171e1a, checked in by Olly Betts <olly@…>, 23 years ago

Removed --output option from printwin (there is no output file) and
--calibrate option for everything apart from in printdm.

printdm now refuses to print if there's no calibration in the .ini
rather than printing to the wrong scale. Calibration pages can still
be printed of course.

git-svn-id: file:///home/survex-svn/survex/trunk@1412 4b37db11-9a0c-4f06-9ece-9ab7cdaee568

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[396b9dd]1/* printwin.c */
[55b7334]2/* Device dependent part of Survex Win32 driver */
[4888f06]3/* Copyright (C) 1993-2001 Olly Betts
4 * Copyright (C) 2001 Philip Underwood
[55b7334]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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 <math.h>
28#include <string.h>
29#include <time.h>
30#include <ctype.h>
31#include <float.h>
32#include <limits.h>
33
34#include "useful.h"
35#include "filename.h"
36#include "message.h"
37#include "prio.h"
38#include "filelist.h"
39#include "debug.h" /* for BUG and ASSERT */
40#include "prcore.h"
41#include <windows.h>
42
[6974a34]43static double MarginLeft, MarginRight, MarginTop, MarginBottom;
[55b7334]44static int fontsize, fontsize_labels;
[6974a34]45static double LineWidth;
[55b7334]46
47static char *fontname, *fontname_labels;
48
49#define WIN_TS 9 /* size of alignment 'ticks' on multipage printouts */
50#define WIN_CROSS_SIZE 2 /* length of cross arms (in points!) */
51
52#define fontname_symbol "Symbol"
53
54static const char *win_Name(void);
55static int win_Pre(int pagesToPrint, const char *title);
56static void win_NewPage(int pg, int pass, int pagesX, int pagesY);
[e1fb3cb]57static void win_Init(FILE **fh_list, const char *pth, const char *outfnm,
[6974a34]58                     double *pscX, double *pscY);
[08e95aa]59static int  win_Charset(void);
[55b7334]60static void win_MoveTo(long x, long y);
61static void win_DrawTo(long x, long y);
62static void win_DrawCross(long x, long y);
63static void win_WriteString(const char *s);
64static void win_DrawCircle(long x, long y, long r);
65static void win_ShowPage(const char *szPageDetails);
66static void win_Quit(void);
67
68device printer = {
[bd171e1a]69   PR_FLAG_NOFILEOUTPUT|PR_FLAG_NOINI,
[55b7334]70   win_Name,
71   win_Init,
[08e95aa]72   win_Charset,
[55b7334]73   win_Pre,
74   win_NewPage,
75   win_MoveTo,
76   win_DrawTo,
77   win_DrawCross,
78   NULL,
79   win_WriteString,
80   win_DrawCircle,
81   win_ShowPage,
[9d46af2]82   NULL, /* win_Post */
[55b7334]83   win_Quit
84};
85
[d0ffc05]86static HDC pd; /* printer context */
[55b7334]87
[396b9dd]88static TEXTMETRIC tm; /* font info */
[55b7334]89
[6974a34]90static double scX, scY;
[55b7334]91
[396b9dd]92static int cur_pass;
93
[55b7334]94static border clip;
95
96static long xpPageWidth, ypPageDepth;
97
[396b9dd]98static int
99check_intersection(long x_p, long y_p)
100{
101#define U 1
102#define D 2
103#define L 4
104#define R 8     
105   int mask_p, mask_t;
106   if (x_p < clip.x_min)
107      mask_p = L;
108   else if (x_p > clip.x_max)
109      mask_p = R;
110
111   if (y_p < clip.y_min)
112      mask_p |= D;
113   else if (y_p > clip.y_max)
114      mask_p |= U;
115
116   if (x_t < clip.x_min)
117      mask_t = L;
118   else if (x_t > clip.x_max)
119      mask_t = R;
120
121   if (y_t < clip.y_min)
122      mask_t |= D;
123   else if (y_t > clip.y_max)
124      mask_t |= U;
125
126#if 0
127   /* approximation to correct answer */
128   return !(mask_t & mask_p);
129#e;se
130   /* One end of the line is on the page */
131   if (!mask_t || !mask_p) return 1;
132
133   /* whole line is above, left, right, or below page */
134   if (mask_t & mask_p) return 0;
135
136   if (mask_t == 0) mask_t = mask_p;
137   if (mask_t & U) {
138      double v = (double)(clip.y_max - y_p) / (y_t - y_p);
139      return v >= 0 && v <= 1;
140   }
141   if (mask_t & D) {
142      double v = (double)(clip.y_min - y_p) / (y_t - y_p);
143      return v >= 0 && v <= 1;
144   }
145   if (mask_t & R) {
146      double v = (double)(clip.x_max - x_p) / (x_t - x_p);
147      return v >= 0 && v <= 1;
148   }
149   ASSERT(mask_t & L);
150   {
151      double v = (double)(clip.x_min - x_p) / (x_t - x_p);
152      return v >= 0 && v <= 1;
153   }
154#endif
155#undef U
156#undef D
157#undef L
158#undef R
159}
160
[55b7334]161static const char *
162win_Name(void)
163{
164   return "Win32 Printer";
165}
166
167static long x_t, y_t;
168
169static void
170win_MoveTo(long x, long y)
171{
172   x_t = x - clip.x_min;
173   y_t = clip.y_max - y;
[396b9dd]174   if (cur_pass != -1) MoveToEx(pd, x_t, y_t, NULL);
[55b7334]175}
176
177static void
178win_DrawTo(long x, long y)
179{
[396b9dd]180   long x_p = x_t, y_p = y_t;
[55b7334]181   x_t = x - clip.x_min;
182   y_t = clip.y_max - y;
[396b9dd]183   if (cur_pass != -1) {
184      LineTo(pd, x_t, y_t);
185   } else {
186      if (check_intersection(x_p, y_p)) fBlankPage = fFalse;
187   }
[55b7334]188}
189
190static void
191win_DrawCross(long x, long y)
192{
[396b9dd]193   if (cur_pass != -1) {
194      win_MoveTo(x - WIN_CROSS_SIZE, y);
195      win_DrawTo(x + WIN_CROSS_SIZE, y);
196      win_MoveTo(x, y - WIN_CROSS_SIZE);
197      win_DrawTo(x, y + WIN_CROSS_SIZE);
198      win_MoveTo(x, y);
199   } else {
200      if ((x + PS_CROSS_SIZE > clip.x_min && x - PS_CROSS_SIZE < clip.x_max) ||
201          (y + PS_CROSS_SIZE > clip.y_min && y - PS_CROSS_SIZE < clip.y_max)) {
202         fBlankPage = fFalse;
203      }
204   }
[55b7334]205}
206
207static void
208win_WriteString(const char *s)
209{
[396b9dd]210   if (cur_pass != -1) {
211      TextOut(pd, x_t, y_t - tm.tmAscent, s, strlen(s));
212   } else {
213      if ((y_t + tm.tmDescent > 0 &&
214           y_t - tm.tmAscent < clip.y_max - clip.y_min) ||
215          (x_t < clip.x_max - clip.x_min &&
216           x_t + strlen(s) * tm.tmAveCharWidth > 0)) {
217         fBlankPage = fFalse;
218      }
219   }
[55b7334]220}
221
222static void
223win_DrawCircle(long x, long y, long r)
224{
[396b9dd]225   /* Don't need to check in first-pass - circle is only used in title box */
226   if (cur_pass != -1) {
227      x_t = x - clip.x_min;
228      y_t = clip.y_max - y;
229      Ellipse(pd, x_t - r, y_t - r, x_t + r, y_t + r);
230   }
[55b7334]231}
232
[08e95aa]233static int
234win_Charset(void)
235{
236   return CHARSET_ISO_8859_1;
237}
238
[55b7334]239static int
240win_Pre(int pagesToPrint, const char *title)
241{
[5824d76]242   PRINTDLGA psd;
243   DOCINFO info;
244
245   pagesToPrint = pagesToPrint; /* suppress compiler warning */
[9d46af2]246
[5824d76]247   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]248   psd.lStructSize = 66;
[5824d76]249   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
[8bc2567]250
[5824d76]251   if (!PrintDlgA(&psd)) exit(1);
[d0ffc05]252   pd = psd.hDC;
[5824d76]253
[8bc2567]254   memset(&info, 0, sizeof(DOCINFO));
[d0ffc05]255   info.cbSize = sizeof(DOCINFO);
[5824d76]256   info.lpszDocName = title;
257
[d0ffc05]258   StartDoc(pd, &info);
259   return 1; /* only need 1 pass */
[55b7334]260}
261
262static void
263win_NewPage(int pg, int pass, int pagesX, int pagesY)
264{
265   int x, y;
266
[396b9dd]267   x = (pg - 1) % pagesX;
268   y = pagesY - 1 - ((pg - 1) / pagesX);
269
270   cur_pass = pass;
[55b7334]271   if (pass == -1) {
[396b9dd]272      /* Don't count alignment marks, but do count borders */
273      fBlankPage = fNoBorder
274         || (x > 0 && y > 0 && x < pagesX - 1 && y < pagesY - 1);
[55b7334]275      return;
276   }
277
278   clip.x_min = (long)x * xpPageWidth;
279   clip.y_min = (long)y * ypPageDepth;
280   clip.x_max = clip.x_min + xpPageWidth; /* dm/pcl/ps had -1; */
281   clip.y_max = clip.y_min + ypPageDepth; /* dm/pcl/ps had -1; */
282   StartPage(pd);
283   drawticks(clip, WIN_TS, x, y);
284}
285
286static void
287win_ShowPage(const char *szPageDetails)
288{
[d0ffc05]289   win_MoveTo((long)(6 * scX) + clip.x_min, clip.y_min - (long)(7 * scY));
290   win_WriteString(szPageDetails);
291   EndPage(pd);
[55b7334]292}
293
[9d46af2]294/* Initialise printer routines */
[55b7334]295static void
[e1fb3cb]296win_Init(FILE **fh_list, const char *pth, const char *out_fnm,
[6974a34]297         double *pscX, double *pscY)
[55b7334]298{
299   /* name and size of font to use for text */
[5824d76]300   PRINTDLGA psd;
[9d46af2]301
302   fh_list = fh_list;
303   pth = pth;
[e1fb3cb]304   out_fnm = out_fnm;
[9d46af2]305
[5824d76]306   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]307   psd.lStructSize = 66;
[5824d76]308   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
309
[8bc2567]310   if (!PrintDlgA(&psd)) exit(1);     
[5824d76]311
[d0ffc05]312   fontsize = 12;
[5824d76]313
[d0ffc05]314   PaperWidth = GetDeviceCaps(psd.hDC, HORZSIZE);
315   PaperDepth = GetDeviceCaps(psd.hDC, VERTSIZE);
316   xpPageWidth = GetDeviceCaps(psd.hDC, HORZRES);
317   ypPageDepth = GetDeviceCaps(psd.hDC, VERTRES);
318   MarginLeft = MarginBottom = 0;
319   MarginRight = PaperWidth;
320   MarginTop = PaperDepth;
321   LineWidth = 0;
322   scX = *pscX = xpPageWidth / PaperWidth;
323   scY = *pscY = ypPageDepth / PaperDepth;
324   xpPageWidth--;
325   ypPageDepth = ypPageDepth - (int)(10 * *pscY);
[396b9dd]326   GetTextMetrics(psd.hDC, &tm);
[d0ffc05]327   DeleteDC(psd.hDC);
[55b7334]328 
329   /* name and size of font to use for station labels (default to text font) */
[d0ffc05]330   fontname_labels = fontname;
331   fontsize_labels = fontsize;
[55b7334]332}
333
334static void
335win_Quit(void)
336{
[d0ffc05]337   EndDoc(pd);
338   DeleteDC(pd);
[55b7334]339}
Note: See TracBrowser for help on using the repository browser.