source: git/src/printwin.c @ fff46e4

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

Support font_size_labels in printwin/printdm/printpcl

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

  • Property mode set to 100644
File size: 8.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
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);
[e1fb3cb]52static void win_Init(FILE **fh_list, const char *pth, const char *outfnm,
[6974a34]53                     double *pscX, double *pscY);
[08e95aa]54static int  win_Charset(void);
[55b7334]55static void win_MoveTo(long x, long y);
56static void win_DrawTo(long x, long y);
57static void win_DrawCross(long x, long y);
[abb82a4]58static void win_SetFont(int fontcode);
[55b7334]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 = {
[bd171e1a]65   PR_FLAG_NOFILEOUTPUT|PR_FLAG_NOINI,
[55b7334]66   win_Name,
67   win_Init,
[08e95aa]68   win_Charset,
[55b7334]69   win_Pre,
70   win_NewPage,
71   win_MoveTo,
72   win_DrawTo,
73   win_DrawCross,
[abb82a4]74   win_SetFont,
[55b7334]75   win_WriteString,
76   win_DrawCircle,
77   win_ShowPage,
[9d46af2]78   NULL, /* win_Post */
[55b7334]79   win_Quit
80};
81
[d0ffc05]82static HDC pd; /* printer context */
[55b7334]83
[abb82a4]84static TEXTMETRIC tm, tm_labels, tm_default; /* font info */
[55b7334]85
[6974a34]86static double scX, scY;
[55b7334]87
[396b9dd]88static int cur_pass;
89
[55b7334]90static border clip;
91
92static long xpPageWidth, ypPageDepth;
93
[0658e7b]94static long x_t, y_t;
95
[396b9dd]96static int
97check_intersection(long x_p, long y_p)
98{
99#define U 1
100#define D 2
101#define L 4
[421b7d2]102#define R 8
[f7cdeb2]103   int mask_p = 0, mask_t = 0;
[f17dbe2]104   if (x_p < 0)
[396b9dd]105      mask_p = L;
[f17dbe2]106   else if (x_p > xpPageWidth)
[396b9dd]107      mask_p = R;
108
[f17dbe2]109   if (y_p < 0)
[396b9dd]110      mask_p |= D;
[f17dbe2]111   else if (y_p > ypPageDepth)
[396b9dd]112      mask_p |= U;
113
[f17dbe2]114   if (x_t < 0)
[396b9dd]115      mask_t = L;
[f17dbe2]116   else if (x_t > xpPageWidth)
[396b9dd]117      mask_t = R;
118
[f17dbe2]119   if (y_t < 0)
[396b9dd]120      mask_t |= D;
[f17dbe2]121   else if (y_t > ypPageDepth)
[396b9dd]122      mask_t |= U;
123
124#if 0
125   /* approximation to correct answer */
126   return !(mask_t & mask_p);
[69fde77]127#else
[396b9dd]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) {
[f17dbe2]136      double v = (double)(y_p - ypPageDepth) / (y_p - y_t);
[396b9dd]137      return v >= 0 && v <= 1;
138   }
139   if (mask_t & D) {
[f17dbe2]140      double v = (double)y_p / (y_p - y_t);
[396b9dd]141      return v >= 0 && v <= 1;
142   }
143   if (mask_t & R) {
[f17dbe2]144      double v = (double)(x_p - xpPageWidth) / (x_p - x_t);
[396b9dd]145      return v >= 0 && v <= 1;
146   }
147   ASSERT(mask_t & L);
148   {
[f17dbe2]149      double v = (double)x_p / (x_p - x_t);
[396b9dd]150      return v >= 0 && v <= 1;
151   }
152#endif
153#undef U
154#undef D
155#undef L
156#undef R
157}
158
[55b7334]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;
[396b9dd]170   if (cur_pass != -1) MoveToEx(pd, x_t, y_t, NULL);
[55b7334]171}
172
173static void
174win_DrawTo(long x, long y)
175{
[396b9dd]176   long x_p = x_t, y_p = y_t;
[55b7334]177   x_t = x - clip.x_min;
178   y_t = clip.y_max - y;
[396b9dd]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   }
[55b7334]184}
185
[7be0ba8]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
[55b7334]190static void
191win_DrawCross(long x, long y)
192{
[396b9dd]193   if (cur_pass != -1) {
[d3d9230]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);
[396b9dd]198      win_MoveTo(x, y);
199   } else {
[39e4399a]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)) {
[396b9dd]204         fBlankPage = fFalse;
205      }
206   }
[55b7334]207}
208
[abb82a4]209static void
210win_SetFont(int fontcode)
211{
212   switch (fontcode) {
213      case PR_FONT_DEFAULT:
214         SelectObject(font_default);
215         tm = tm_default;
216         break;
217      case PR_FONT_LABELS:
218         SelectObject(font_labels);
219         tm = tm_labels;
220         break;
221      default:
222         BUG("unknown font code");
223   }
224}
225
[55b7334]226static void
227win_WriteString(const char *s)
228{
[396b9dd]229   if (cur_pass != -1) {
230      TextOut(pd, x_t, y_t - tm.tmAscent, s, strlen(s));
231   } else {
232      if ((y_t + tm.tmDescent > 0 &&
233           y_t - tm.tmAscent < clip.y_max - clip.y_min) ||
234          (x_t < clip.x_max - clip.x_min &&
235           x_t + strlen(s) * tm.tmAveCharWidth > 0)) {
236         fBlankPage = fFalse;
237      }
238   }
[55b7334]239}
240
241static void
242win_DrawCircle(long x, long y, long r)
243{
[396b9dd]244   /* Don't need to check in first-pass - circle is only used in title box */
245   if (cur_pass != -1) {
246      x_t = x - clip.x_min;
247      y_t = clip.y_max - y;
248      Ellipse(pd, x_t - r, y_t - r, x_t + r, y_t + r);
249   }
[55b7334]250}
251
[08e95aa]252static int
253win_Charset(void)
254{
255   return CHARSET_ISO_8859_1;
256}
257
[abb82a4]258static HFONT font_labels, font_default, font_old;
259
[55b7334]260static int
261win_Pre(int pagesToPrint, const char *title)
262{
[5824d76]263   PRINTDLGA psd;
264   DOCINFO info;
265
266   pagesToPrint = pagesToPrint; /* suppress compiler warning */
[9d46af2]267
[5824d76]268   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]269   psd.lStructSize = 66;
[5824d76]270   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
[8bc2567]271
[5824d76]272   if (!PrintDlgA(&psd)) exit(1);
[d0ffc05]273   pd = psd.hDC;
[5824d76]274
[abb82a4]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   
[8bc2567]288   memset(&info, 0, sizeof(DOCINFO));
[d0ffc05]289   info.cbSize = sizeof(DOCINFO);
[5824d76]290   info.lpszDocName = title;
291
[d0ffc05]292   StartDoc(pd, &info);
293   return 1; /* only need 1 pass */
[55b7334]294}
295
296static void
297win_NewPage(int pg, int pass, int pagesX, int pagesY)
298{
299   int x, y;
300
[396b9dd]301   x = (pg - 1) % pagesX;
302   y = pagesY - 1 - ((pg - 1) / pagesX);
303
[f17dbe2]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
[396b9dd]309   cur_pass = pass;
[55b7334]310   if (pass == -1) {
[396b9dd]311      /* Don't count alignment marks, but do count borders */
312      fBlankPage = fNoBorder
313         || (x > 0 && y > 0 && x < pagesX - 1 && y < pagesY - 1);
[55b7334]314      return;
315   }
316
317   StartPage(pd);
[7be0ba8]318   drawticks(clip, 9 * scX / POINTS_PER_MM, x, y);
[55b7334]319}
320
321static void
322win_ShowPage(const char *szPageDetails)
323{
[d0ffc05]324   win_MoveTo((long)(6 * scX) + clip.x_min, clip.y_min - (long)(7 * scY));
325   win_WriteString(szPageDetails);
326   EndPage(pd);
[55b7334]327}
328
[9d46af2]329/* Initialise printer routines */
[55b7334]330static void
[e1fb3cb]331win_Init(FILE **fh_list, const char *pth, const char *out_fnm,
[6974a34]332         double *pscX, double *pscY)
[55b7334]333{
[5824d76]334   PRINTDLGA psd;
[abb82a4]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 */
[e1fb3cb]343   out_fnm = out_fnm;
[9d46af2]344
[abb82a4]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
[5824d76]350   memset(&psd, 0, sizeof(PRINTDLGA));
[d0ffc05]351   psd.lStructSize = 66;
[5824d76]352   psd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
353
[421b7d2]354   if (!PrintDlgA(&psd)) exit(1);
[5824d76]355
[d0ffc05]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);
[55b7334]369}
370
371static void
372win_Quit(void)
373{
[abb82a4]374   SelectObject(pd, font_old);
375   DeleteObject(font_labels);
376   DeleteObject(font_default);
[d0ffc05]377   EndDoc(pd);
378   DeleteDC(pd);
[55b7334]379}
Note: See TracBrowser for help on using the repository browser.