source: git/src/printwin.c @ 396b9dd

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

Make "skip pages" work with printps/printhpgl/printwin.

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