source: git/src/printwin.c @ cac1865

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

printwin: changed crosses from + to x for consistency with other printer
drivers.

git-svn-id: file:///home/survex-svn/survex/trunk@1721 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 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);
[e1fb3cb]54static void win_Init(FILE **fh_list, const char *pth, const char *outfnm,
[6974a34]55                     double *pscX, double *pscY);
[08e95aa]56static int  win_Charset(void);
[55b7334]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 = {
[bd171e1a]66   PR_FLAG_NOFILEOUTPUT|PR_FLAG_NOINI,
[55b7334]67   win_Name,
68   win_Init,
[08e95aa]69   win_Charset,
[55b7334]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,
[9d46af2]79   NULL, /* win_Post */
[55b7334]80   win_Quit
81};
82
[d0ffc05]83static HDC pd; /* printer context */
[55b7334]84
[396b9dd]85static TEXTMETRIC tm; /* font info */
[55b7334]86
[6974a34]87static double scX, scY;
[55b7334]88
[396b9dd]89static int cur_pass;
90
[55b7334]91static border clip;
92
93static long xpPageWidth, ypPageDepth;
94
[0658e7b]95static long x_t, y_t;
96
[396b9dd]97static int
98check_intersection(long x_p, long y_p)
99{
100#define U 1
101#define D 2
102#define L 4
[421b7d2]103#define R 8
[f7cdeb2]104   int mask_p = 0, mask_t = 0;
[f17dbe2]105   if (x_p < 0)
[396b9dd]106      mask_p = L;
[f17dbe2]107   else if (x_p > xpPageWidth)
[396b9dd]108      mask_p = R;
109
[f17dbe2]110   if (y_p < 0)
[396b9dd]111      mask_p |= D;
[f17dbe2]112   else if (y_p > ypPageDepth)
[396b9dd]113      mask_p |= U;
114
[f17dbe2]115   if (x_t < 0)
[396b9dd]116      mask_t = L;
[f17dbe2]117   else if (x_t > xpPageWidth)
[396b9dd]118      mask_t = R;
119
[f17dbe2]120   if (y_t < 0)
[396b9dd]121      mask_t |= D;
[f17dbe2]122   else if (y_t > ypPageDepth)
[396b9dd]123      mask_t |= U;
124
125#if 0
126   /* approximation to correct answer */
127   return !(mask_t & mask_p);
[69fde77]128#else
[396b9dd]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) {
[f17dbe2]137      double v = (double)(y_p - ypPageDepth) / (y_p - y_t);
[396b9dd]138      return v >= 0 && v <= 1;
139   }
140   if (mask_t & D) {
[f17dbe2]141      double v = (double)y_p / (y_p - y_t);
[396b9dd]142      return v >= 0 && v <= 1;
143   }
144   if (mask_t & R) {
[f17dbe2]145      double v = (double)(x_p - xpPageWidth) / (x_p - x_t);
[396b9dd]146      return v >= 0 && v <= 1;
147   }
148   ASSERT(mask_t & L);
149   {
[f17dbe2]150      double v = (double)x_p / (x_p - x_t);
[396b9dd]151      return v >= 0 && v <= 1;
152   }
153#endif
154#undef U
155#undef D
156#undef L
157#undef R
158}
159
[55b7334]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;
[396b9dd]171   if (cur_pass != -1) MoveToEx(pd, x_t, y_t, NULL);
[55b7334]172}
173
174static void
175win_DrawTo(long x, long y)
176{
[396b9dd]177   long x_p = x_t, y_p = y_t;
[55b7334]178   x_t = x - clip.x_min;
179   y_t = clip.y_max - y;
[396b9dd]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   }
[55b7334]185}
186
[7be0ba8]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
[55b7334]191static void
192win_DrawCross(long x, long y)
193{
[396b9dd]194   if (cur_pass != -1) {
[d3d9230]195      win_MoveTo(x - WIN_CROSS_SIZE, y - WIN_CROSS_SIZE);
196      win_DrawTo(x + WIN_CROSS_SIZE, y + WIN_CROSS_SIZE);
197      win_MoveTo(x + WIN_CROSS_SIZE, y - WIN_CROSS_SIZE);
198      win_DrawTo(x - WIN_CROSS_SIZE, y + WIN_CROSS_SIZE);
[396b9dd]199      win_MoveTo(x, y);
200   } else {
[39e4399a]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)) {
[396b9dd]205         fBlankPage = fFalse;
206      }
207   }
[55b7334]208}
209
210static void
211win_WriteString(const char *s)
212{
[396b9dd]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   }
[55b7334]223}
224
225static void
226win_DrawCircle(long x, long y, long r)
227{
[396b9dd]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   }
[55b7334]234}
235
[08e95aa]236static int
237win_Charset(void)
238{
239   return CHARSET_ISO_8859_1;
240}
241
[55b7334]242static int
243win_Pre(int pagesToPrint, const char *title)
244{
[5824d76]245   PRINTDLGA psd;
246   DOCINFO info;
247
248   pagesToPrint = pagesToPrint; /* suppress compiler warning */
[9d46af2]249
[5824d76]250   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]251   psd.lStructSize = 66;
[5824d76]252   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
[8bc2567]253
[5824d76]254   if (!PrintDlgA(&psd)) exit(1);
[d0ffc05]255   pd = psd.hDC;
[5824d76]256
[8bc2567]257   memset(&info, 0, sizeof(DOCINFO));
[d0ffc05]258   info.cbSize = sizeof(DOCINFO);
[5824d76]259   info.lpszDocName = title;
260
[d0ffc05]261   StartDoc(pd, &info);
262   return 1; /* only need 1 pass */
[55b7334]263}
264
265static void
266win_NewPage(int pg, int pass, int pagesX, int pagesY)
267{
268   int x, y;
269
[396b9dd]270   x = (pg - 1) % pagesX;
271   y = pagesY - 1 - ((pg - 1) / pagesX);
272
[f17dbe2]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
[396b9dd]278   cur_pass = pass;
[55b7334]279   if (pass == -1) {
[396b9dd]280      /* Don't count alignment marks, but do count borders */
281      fBlankPage = fNoBorder
282         || (x > 0 && y > 0 && x < pagesX - 1 && y < pagesY - 1);
[55b7334]283      return;
284   }
285
286   StartPage(pd);
[7be0ba8]287   drawticks(clip, 9 * scX / POINTS_PER_MM, x, y);
[55b7334]288}
289
290static void
291win_ShowPage(const char *szPageDetails)
292{
[d0ffc05]293   win_MoveTo((long)(6 * scX) + clip.x_min, clip.y_min - (long)(7 * scY));
294   win_WriteString(szPageDetails);
295   EndPage(pd);
[55b7334]296}
297
[9d46af2]298/* Initialise printer routines */
[55b7334]299static void
[e1fb3cb]300win_Init(FILE **fh_list, const char *pth, const char *out_fnm,
[6974a34]301         double *pscX, double *pscY)
[55b7334]302{
303   /* name and size of font to use for text */
[5824d76]304   PRINTDLGA psd;
[9d46af2]305
306   fh_list = fh_list;
307   pth = pth;
[e1fb3cb]308   out_fnm = out_fnm;
[9d46af2]309
[5824d76]310   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]311   psd.lStructSize = 66;
[5824d76]312   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
313
[421b7d2]314   if (!PrintDlgA(&psd)) exit(1);
[5824d76]315
[d0ffc05]316   fontsize = 12;
[5824d76]317
[d0ffc05]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);
[396b9dd]330   GetTextMetrics(psd.hDC, &tm);
[d0ffc05]331   DeleteDC(psd.hDC);
[421b7d2]332
[55b7334]333   /* name and size of font to use for station labels (default to text font) */
[d0ffc05]334   fontname_labels = fontname;
335   fontsize_labels = fontsize;
[55b7334]336}
337
338static void
339win_Quit(void)
340{
[d0ffc05]341   EndDoc(pd);
342   DeleteDC(pd);
[55b7334]343}
Note: See TracBrowser for help on using the repository browser.