source: git/src/printwin.c @ 2d82f2a

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

Fixed to compile.

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

  • Property mode set to 100644
File size: 9.0 KB
Line 
1/* printwin.c */
2/* Device dependent part of Survex Win32 driver */
3/* Copyright (C) 1993-2002 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
49static const char *win_Name(void);
50static int win_Pre(int pagesToPrint, const char *title);
51static void win_NewPage(int pg, int pass, int pagesX, int pagesY);
52static void win_Init(FILE **fh_list, const char *pth, const char *outfnm,
53                     double *pscX, double *pscY, bool fCalibrate);
54static int  win_Charset(void);
55static void win_MoveTo(long x, long y);
56static void win_DrawTo(long x, long y);
57static void win_DrawCross(long x, long y);
58static void win_SetFont(int fontcode);
59static void win_WriteString(const char *s);
60static void win_DrawCircle(long x, long y, long r);
61static void win_ShowPage(const char *szPageDetails);
62static void win_Quit(void);
63
64device printer = {
65   PR_FLAG_NOFILEOUTPUT|PR_FLAG_NOINI,
66   win_Name,
67   win_Init,
68   win_Charset,
69   win_Pre,
70   win_NewPage,
71   win_MoveTo,
72   win_DrawTo,
73   win_DrawCross,
74   win_SetFont,
75   win_WriteString,
76   win_DrawCircle,
77   win_ShowPage,
78   NULL, /* win_Post */
79   win_Quit
80};
81
82static HDC pd; /* printer context */
83
84static TEXTMETRIC tm, tm_labels, tm_default; /* font info */
85
86static double scX, scY;
87
88static int cur_pass;
89
90static border clip;
91
92static long xpPageWidth, ypPageDepth;
93
94static long x_t, y_t;
95
96static int
97check_intersection(long x_p, long y_p)
98{
99#define U 1
100#define D 2
101#define L 4
102#define R 8
103   int mask_p = 0, mask_t = 0;
104   if (x_p < 0)
105      mask_p = L;
106   else if (x_p > xpPageWidth)
107      mask_p = R;
108
109   if (y_p < 0)
110      mask_p |= D;
111   else if (y_p > ypPageDepth)
112      mask_p |= U;
113
114   if (x_t < 0)
115      mask_t = L;
116   else if (x_t > xpPageWidth)
117      mask_t = R;
118
119   if (y_t < 0)
120      mask_t |= D;
121   else if (y_t > ypPageDepth)
122      mask_t |= U;
123
124#if 0
125   /* approximation to correct answer */
126   return !(mask_t & mask_p);
127#else
128   /* One end of the line is on the page */
129   if (!mask_t || !mask_p) return 1;
130
131   /* whole line is above, left, right, or below page */
132   if (mask_t & mask_p) return 0;
133
134   if (mask_t == 0) mask_t = mask_p;
135   if (mask_t & U) {
136      double v = (double)(y_p - ypPageDepth) / (y_p - y_t);
137      return v >= 0 && v <= 1;
138   }
139   if (mask_t & D) {
140      double v = (double)y_p / (y_p - y_t);
141      return v >= 0 && v <= 1;
142   }
143   if (mask_t & R) {
144      double v = (double)(x_p - xpPageWidth) / (x_p - x_t);
145      return v >= 0 && v <= 1;
146   }
147   ASSERT(mask_t & L);
148   {
149      double v = (double)x_p / (x_p - x_t);
150      return v >= 0 && v <= 1;
151   }
152#endif
153#undef U
154#undef D
155#undef L
156#undef R
157}
158
159static const char *
160win_Name(void)
161{
162   return "Win32 Printer";
163}
164
165static void
166win_MoveTo(long x, long y)
167{
168   x_t = x - clip.x_min;
169   y_t = clip.y_max - y;
170   if (cur_pass != -1) MoveToEx(pd, x_t, y_t, NULL);
171}
172
173static void
174win_DrawTo(long x, long y)
175{
176   long x_p = x_t, y_p = y_t;
177   x_t = x - clip.x_min;
178   y_t = clip.y_max - y;
179   if (cur_pass != -1) {
180      LineTo(pd, x_t, y_t);
181   } else {
182      if (check_intersection(x_p, y_p)) fBlankPage = fFalse;
183   }
184}
185
186#define POINTS_PER_INCH 72.0
187#define POINTS_PER_MM (POINTS_PER_INCH / MM_PER_INCH)
188#define WIN_CROSS_SIZE (2 * scX / POINTS_PER_MM)
189
190static void
191win_DrawCross(long x, long y)
192{
193   if (cur_pass != -1) {
194      win_MoveTo(x - WIN_CROSS_SIZE, y - WIN_CROSS_SIZE);
195      win_DrawTo(x + WIN_CROSS_SIZE, y + WIN_CROSS_SIZE);
196      win_MoveTo(x + WIN_CROSS_SIZE, y - WIN_CROSS_SIZE);
197      win_DrawTo(x - WIN_CROSS_SIZE, 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 HFONT font_labels, font_default, font_old;
210
211static void
212win_SetFont(int fontcode)
213{
214   switch (fontcode) {
215      case PR_FONT_DEFAULT:
216         SelectObject(pd, font_default);
217         tm = tm_default;
218         break;
219      case PR_FONT_LABELS:
220         SelectObject(pd, font_labels);
221         tm = tm_labels;
222         break;
223      default:
224         BUG("unknown font code");
225   }
226}
227
228static void
229win_WriteString(const char *s)
230{
231   if (cur_pass != -1) {
232      TextOut(pd, x_t, y_t - tm.tmAscent, s, strlen(s));
233   } else {
234      if ((y_t + tm.tmDescent > 0 &&
235           y_t - tm.tmAscent < clip.y_max - clip.y_min) ||
236          (x_t < clip.x_max - clip.x_min &&
237           x_t + strlen(s) * tm.tmAveCharWidth > 0)) {
238         fBlankPage = fFalse;
239      }
240   }
241}
242
243static void
244win_DrawCircle(long x, long y, long r)
245{
246   /* Don't need to check in first-pass - circle is only used in title box */
247   if (cur_pass != -1) {
248      x_t = x - clip.x_min;
249      y_t = clip.y_max - y;
250      Ellipse(pd, x_t - r, y_t - r, x_t + r, y_t + r);
251   }
252}
253
254static int
255win_Charset(void)
256{
257   return CHARSET_ISO_8859_1;
258}
259
260static int
261win_Pre(int pagesToPrint, const char *title)
262{
263   PRINTDLGA psd;
264   DOCINFO info;
265
266   pagesToPrint = pagesToPrint; /* suppress compiler warning */
267
268   memset(&psd, 0, sizeof(PRINTDLGA));
269   psd.lStructSize = 66;
270   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
271
272   if (!PrintDlgA(&psd)) exit(1);
273   pd = psd.hDC;
274
275   font_labels = CreateFont(fontsize_labels, 0, 0, 0, FW_NORMAL, 0, 0, 0,
276                            ANSI_CHARSET, OUT_DEFAULT_PRECIS,
277                            CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
278                            FF_DONTCARE | DEFAULT_PITCH, "Arial");   
279   font_default = CreateFont(fontsize, 0, 0, 0, FW_NORMAL, 0, 0, 0,
280                          ANSI_CHARSET, OUT_DEFAULT_PRECIS,
281                          CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
282                          FF_DONTCARE | DEFAULT_PITCH, "Arial");   
283   font_old = SelectObject(pd, font_labels);
284   GetTextMetrics(pd, &tm_labels);
285   SelectObject(pd, font_default);
286   GetTextMetrics(pd, &tm_default);
287   
288   memset(&info, 0, sizeof(DOCINFO));
289   info.cbSize = sizeof(DOCINFO);
290   info.lpszDocName = title;
291
292   StartDoc(pd, &info);
293   return 1; /* only need 1 pass */
294}
295
296static void
297win_NewPage(int pg, int pass, int pagesX, int pagesY)
298{
299   int x, y;
300
301   x = (pg - 1) % pagesX;
302   y = pagesY - 1 - ((pg - 1) / pagesX);
303
304   clip.x_min = (long)x * xpPageWidth;
305   clip.y_min = (long)y * ypPageDepth;
306   clip.x_max = clip.x_min + xpPageWidth; /* dm/pcl/ps had -1; */
307   clip.y_max = clip.y_min + ypPageDepth; /* dm/pcl/ps had -1; */
308
309   cur_pass = pass;
310   if (pass == -1) {
311      /* Don't count alignment marks, but do count borders */
312      fBlankPage = fNoBorder
313         || (x > 0 && y > 0 && x < pagesX - 1 && y < pagesY - 1);
314      return;
315   }
316
317   StartPage(pd);
318   drawticks(clip, 9 * scX / POINTS_PER_MM, x, y);
319}
320
321static void
322win_ShowPage(const char *szPageDetails)
323{
324   win_MoveTo((long)(6 * scX) + clip.x_min, clip.y_min - (long)(7 * scY));
325   win_WriteString(szPageDetails);
326   EndPage(pd);
327}
328
329/* Initialise printer routines */
330static void
331win_Init(FILE **fh_list, const char *pth, const char *out_fnm,
332         double *pscX, double *pscY, bool fCalibrate)
333{
334   PRINTDLGA psd;
335   static const char *vars[] = {
336      "like",
337      "font_size_labels",
338      NULL
339   };
340   char **vals;
341
342   fCalibrate = fCalibrate; /* suppress unused argument warning */
343   out_fnm = out_fnm;
344
345   vals = ini_read_hier(fh_list, "win", vars);
346
347   fontsize_labels = as_int(vars[2], vals[2], 1, INT_MAX);
348   fontsize = 10;
349
350   memset(&psd, 0, sizeof(PRINTDLGA));
351   psd.lStructSize = 66;
352   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
353
354   if (!PrintDlgA(&psd)) exit(1);
355
356   PaperWidth = GetDeviceCaps(psd.hDC, HORZSIZE);
357   PaperDepth = GetDeviceCaps(psd.hDC, VERTSIZE);
358   xpPageWidth = GetDeviceCaps(psd.hDC, HORZRES);
359   ypPageDepth = GetDeviceCaps(psd.hDC, VERTRES);
360   MarginLeft = MarginBottom = 0;
361   MarginRight = PaperWidth;
362   MarginTop = PaperDepth;
363   LineWidth = 0;
364   scX = *pscX = xpPageWidth / PaperWidth;
365   scY = *pscY = ypPageDepth / PaperDepth;
366   xpPageWidth--;
367   ypPageDepth = ypPageDepth - (int)(10 * *pscY);
368   DeleteDC(psd.hDC);
369}
370
371static void
372win_Quit(void)
373{
374   SelectObject(pd, font_old);
375   DeleteObject(font_labels);
376   DeleteObject(font_default);
377   EndDoc(pd);
378   DeleteDC(pd);
379}
Note: See TracBrowser for help on using the repository browser.