source: git/src/printwin.c @ ac01973

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

printwin: fixed sizes of cross and page alignment ticks

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