source: git/src/printwin.c @ 5901b62

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 5901b62 was f17dbe2, checked in by Olly Betts <olly@…>, 23 years ago

Sorted out clip box vs --skip-blanks.

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

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