1 //
2 // FXDCNativePrinter.cpp
3 //
4 // cf FXDCPrint but this version can use a native WIN32 printer
5 //    and also provides richer scaling capabilities. It also
6 //    uses FXPostscriptFont when printing Postscript so that it gets
7 //    metrics right (at least for the standard 35 fonts).
8 //
9 // Contributed to FOX project by Manuel (address@te...) who
10 // made a deliberate choice not to add a copyright notice, so that
11 // the code could be added to FOX (and hence released under the FOX
12 // relaxed version of the LGPL).
13 //
14 
15 
16 // Here is a message that he sent in October 2002, and point (c) explains
17 // that it can be used for any purpose... which includes use within a
18 // larger body of code that is subject to LGPL.
19 
20 /*
21  *I will try to address some of the problems you have (I am the author of the
22  *code, btw).
23  *
24  *a) Portrait/landscape: This is controlled by the FXPrinter you use to
25  *initialize printing. You can either let the user choose on the Printing
26  *Dialog or just set it with the methods provided by FXPrinter. If you are
27  *already doing it and fails, let me know so I can have a deeper look at the
28  *problem. There are some examples on the zip file. I suppose you are using
29  *printing-release2.zip from the download area at http://www.fox-toolkit.org (just
30  *to make sure).
31  *
32  *b) Local vs Remote printing: I have no access to remote printers, so I
33  *couldnt test that. Since you can print, it seems a glitch on the safety
34  *checks.
35  *
36  *c) Including it in FOX: I havent put any copyright notice on the code so it
37  *could be used for any purpose. If Jeroen wants to incorporate it or a
38  *derivative work, it is fine with me.
39  *
40  *d) Printing in Linux: On UNIX the class is just a wrapper that provides unit
41  *scaling around FXDCPrint. If you never use any scaling other than the
42  *default 72x72 ppi, you would have the same effect if you decided using
43  *directly FXDCPrint. Look at FOX source code if you want to know how printing
44  *is handled by FXDCPrint.
45  *
46  *Thanks for the feedback,
47  *Manuel
48  *
49  */
50 
51 // This version worked on by Arthur Norman mainly to make the
52 // behaviour under Linux more robust, but also to clean up some
53 // oddities etc. and add bits of functionality. I view this as a derived
54 // work of FOX and I had intended to explicitly include the FOX addendum
55 // in the license terms that apply, but the copyright holders of FOX
56 // have clarified that only they may do that, hence this code has to fall
57 // under just LGPL, and any changes I have made I release under LGPL 2.1.
58 
59 /* $Id: FXDCNativePrinter.cpp 4189 2017-09-08 08:05:40Z arthurcnorman $ */
60 
61 
62 #ifdef HAVE_CONFIG_H
63 #include "config.h"
64 #endif
65 
66 #include <string.h>
67 #include <ctype.h>
68 #include <fx.h>
69 #include <FXDC.h>
70 #include <FXDCPrint.h>
71 #include <FXDCWindow.h>
72 
73 #include "FXPostscriptFont.h"
74 
75 //////////////////////////////////////////////////////////////////////////////
76 
77 
78 #include "FXDCNativePrinter.h"
79 #include "FXPostscriptFont.h"
80 
81 namespace FX {
82 
83 //
84 // When generating Postscript I need font metrics. These can be extracted
85 // from "afm" files that Adobe supply. I have a program "get-adobe-metrics.c"
86 // that can be run on a typical Linux system to extract the (minimal) metric
87 // information that I need here and build a file "font-info.c". By including
88 // that file here I collect info about all the standard Postscript Fonts.
89 // I will not support use any other fonts than these!
90 //
91 
92 
93 #ifdef WIN32
94 //
95 // The WIN32 version here works by mapping the printer much as if it
96 // was a window. A Postscript version will generate Postscript directly
97 // from the print requests that the user makes.
98 //
99 class FXAPI FXPrinterVisual : public FXVisual
100 {
101 public:
102     FXPrinterVisual();
create()103     void create() { xid=(void *)1; }
detach()104     void detach() { xid=(void *)0; }
destroy()105     void destroy() { xid=(void *)0; }
getPixel(FXColor clr)106     FXPixel getPixel(FXColor clr)
107     { return RGB( FXREDVAL(clr), FXGREENVAL(clr), FXBLUEVAL(clr) ); }
getColor(FXPixel pix)108     FXColor getColor(FXPixel pix)
109     { return FXRGB( GetRValue(pix), GetGValue(pix), GetBValue(pix) ); }
110 };
111 
FXPrinterVisual()112 FXPrinterVisual::FXPrinterVisual():FXVisual()
113 {
114     depth=24;
115     numred=numgreen=numblue=256;
116     numcolors=256*256*256;
117     type=(FXVisualType)VISUALTYPE_TRUE;
118     xid=(void *)0;
119 //  hPalette = NULL;  // not available in FOX 1.1.49 and unclear whether needed here anyway!
120 };
121 
122 class FXAPI FXPrinterDrawable : public FXDrawable
123 {
124 protected:
125     FXID dc;
126 public:
127     FXPrinterDrawable(FXID gc);
128     FXPrinterDrawable();
129     ~FXPrinterDrawable();
130     void SetDC(FXID gc);
GetDC() const131     virtual FXID GetDC() const { return (FXID)dc; }
ReleaseDC(FXID) const132     virtual int ReleaseDC(FXID) const { return 0; }
133 };
134 
~FXPrinterDrawable()135 FXPrinterDrawable::~FXPrinterDrawable()
136 {
137     delete visual;
138 }
139 
FXPrinterDrawable()140 FXPrinterDrawable::FXPrinterDrawable()
141 {
142     FXPrinterDrawable(0);
143 }
144 
FXPrinterDrawable(FXID gc)145 FXPrinterDrawable::FXPrinterDrawable(FXID gc) : FXDrawable()
146 {
147     dc = gc;
148     visual=new FXPrinterVisual();
149     xid=(FXID)1;
150 }
151 
SetDC(FXID gc)152 void FXPrinterDrawable::SetDC(FXID gc)
153 {
154     dc = (HDC)gc;
155 }
156 
157 #endif // end of WIN32-specific stuff
158 
159 // Construct
160 
FXDCNativePrinter(FXApp * a)161 FXDCNativePrinter::FXDCNativePrinter(FXApp *a):FXDC(a)
162 {
163 #ifdef WIN32
164     opaque = (FXObject *)NULL;
165     dctype=TYPE_WIN32;
166 #else
167     dctype=TYPE_PS;
168 #endif
169 #ifdef FONT_NOT_VIRTUAL
170     postscriptFont = NULL;
171 #endif
172     pageheight = 0.0;   // report this until the print job starts
173     pagewidth = 0.0;
174     fontoffset = 0;     // Baseline of font
175     fontScaleBack = 1.0;
176     fontScale = 1.0;
177     PSscale = 1.0;
178     logpixelsx = 72;
179     logpixelsy = 72;
180     scalex = 1.0;
181     scaley = 1.0;
182     unitsx = 72.0;
183     unitsy = 72.0;
184     pdc = (FXDC *)NULL;
185     pagecount=0;
186 }
187 
188 
189 // Destruct
190 
~FXDCNativePrinter()191 FXDCNativePrinter::~FXDCNativePrinter()
192 {
193 }
194 
195 // Generate print job prolog, return TRUE if all is OK
196 
beginPrint(FXPrinter & job)197 FXbool FXDCNativePrinter::beginPrint(FXPrinter &job)
198 {
199     pagecount=0;
200 
201 #ifdef WIN32
202 // on Windows printing to file uses Postscript but anything direct to
203 // a printer goes via the Windows drivers.
204     if (job.flags&PRINT_DEST_FILE) dctype = TYPE_PS;
205     else dctype=TYPE_WIN32;
206 #else
207 // On other than WIN32 the only print mode supported is Postscript
208     dctype=TYPE_PS;
209 #endif
210 
211     switch (dctype)
212     {
213 #ifdef WIN32
214 case TYPE_WIN32:
215         devmode_handle=0;
216         FXPrinterDrawable *prn;
217 // TODO: Paper size
218         memset(&devmode, 0, sizeof(devmode));
219         devmode.dmFields = DM_ORIENTATION | DM_COLOR;
220         devmode.dmSize = sizeof(devmode);
221         devmode.dmOrientation = (job.flags&PRINT_LANDSCAPE) ?
222                                 DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
223         devmode.dmColor = (job.flags&PRINT_COLOR) ?
224                           DMCOLOR_COLOR : DMCOLOR_MONOCHROME;
225         char devicename[256];
226 // Note: Under Win 9x/ME   "WINSPOOL" should be replaced by NULL,
227 //       but this seems to work anyway!
228         strcpy(devicename, job.name.text());
229         dc = CreateDC("WINSPOOL", devicename, NULL, &devmode);
230         if (dc==(HANDLE)NULL) return FALSE;
231 
232 // Initialize the members of a DOCINFO structure.
233         memset((void *)&di, 0, sizeof(di));
234         di.cbSize = sizeof(DOCINFO);
235         di.lpszDocName = "Document";  // FIXME: API to support document name?
236         di.lpszOutput = (LPTSTR) NULL;
237         di.fwType = 0;
238 
239 // Start document
240         if (::StartDoc(dc, &di)==SP_ERROR)
241         {   ::DeleteDC(dc);
242             dc=0;
243             return FALSE;
244         }
245 
246         SetMapMode(dc, MM_TEXT);
247 
248 // get pixels per inch, usually 600x600 or 300x300
249         logpixelsy = ::GetDeviceCaps(dc, LOGPIXELSY);
250         logpixelsx = ::GetDeviceCaps(dc, LOGPIXELSX);
251 #ifdef OLD
252         fontScale = logpixelsy / 96.0;
253         fontScaleBack = 96.0 / logpixelsy;
254 #else
255 // The font size I need to create under Windows will be related to the
256 // pixel-pitch on my output device. My reading of the Windows documentation
257 // is that the scaling shown here is what is wanted, but the alternative
258 // scaling by 96 not 72 was present in the original code so I leave it as
259 // a comment for now in case there is something I do not understand.
260         fontScale = logpixelsy / 72.0;
261         fontScaleBack = 72.0 / logpixelsy;
262 #endif
263         setHorzUnitsInch(72.0);
264         setVertUnitsInch(72.0);
265 
266 // Create drawable
267         prn = new FXPrinterDrawable((FXID)dc);
268         opaque= (FXObject *)prn;
269         FXdouble dx, dy;
270         dx = (FXdouble)job.mediawidth;
271         dy = (FXdouble)job.mediaheight;
272         if (job.flags&PRINT_LANDSCAPE)
273         {   FXdouble kk=dx;
274             dx=dy;
275             dy=kk;
276         }
277         pageheight = dy * scaley;   /* Store size in pixels */
278         pagewidth = dx * scalex;
279         prn->resize( (FXint)(scalex * dx) , (FXint)(scaley * dy) );
280 // Create a WIN32 FXDC from our drawable
281         pdc = (FXDC *)new FXDCWindow(prn);
282         SetTextAlign(dc, TA_TOP|TA_LEFT); // TA_BASLINE fails in some printers
283         pdc->setForeground(FXRGB(0,0,0));
284         pdc->setBackground(FXRGB(255,255,255));
285         return TRUE;
286 #endif
287 
288 default:      // case TYPE_PS:
289 // Postscript printing delegates to the existing FXDCPrint class.
290 //  But note that until metric-returning things in FXFont are virtual
291 //  I have a HACK whenever I extract measurements here.
292         pdc = (FXDC *)new FXDCPrint(getApp());
293         if (((FXDCPrint *)pdc)->beginPrint(job) == 0) return FALSE;
294         logpixelsx = 72;
295         logpixelsy = 72;
296         scalex = 1.0;
297         scaley = 1.0;
298         PSscale = 0.001;  // see usage later on for explanation
299 // There is an uncertainty here about who is supposed to be
300 // responsible for margins. The FXPrinter that I was passed has
301 // given me some suggestions but I ignore them here! What is done here
302 // is at least compatible with what is done in the WIN32 case.
303         pagewidth = (FXfloat)job.mediawidth;
304         pageheight = (FXfloat)job.mediaheight;
305         if (job.flags&PRINT_LANDSCAPE)
306         {   FXdouble kk=pagewidth;
307             pagewidth=pageheight;
308             pageheight=kk;
309         }
310 // The following 2 lines may not be needed for Postscript printing but
311 // are harmless anyway.
312         pdc->setForeground(FXRGB(0,0,0));
313         pdc->setBackground(FXRGB(255,255,255));
314         return TRUE;
315     }
316 }
317 
318 // Generate print job epilog
319 
endPrint()320 FXbool FXDCNativePrinter::endPrint()
321 {
322     switch (dctype)
323     {
324 #ifdef WIN32
325 case TYPE_WIN32:      // End of Document
326         if (dc!=0)
327         {   ::EndDoc(dc);
328             FXDCWindow *pd=(FXDCWindow *)pdc;
329             delete pd;
330             FXPrinterDrawable *prn=(FXPrinterDrawable *)opaque;
331             delete prn;
332             ::DeleteDC(dc);
333             dc=0;
334             opaque=(FXObject *)NULL;
335             pdc=(FXDC*)NULL;
336         }
337         return 1;
338 #endif
339 default:              // case TYPE_PS:
340         FXDCPrint *pd=(FXDCPrint *)pdc;
341         FXbool v=pd->endPrint();
342         delete pd;
343         pdc=(FXDC *)NULL;
344         return v;
345     }
346 }
347 
348 // Generate begin of page
349 
beginPage(FXuint page)350 FXbool FXDCNativePrinter::beginPage(FXuint page)
351 {
352     switch (dctype)
353     {
354 #ifdef WIN32
355 case TYPE_WIN32:
356         if (::StartPage(dc)<=0)
357         {   endPrint();
358             return 0;
359         }
360         return 1;
361 #endif
362 default:                  // case TYPE_PS:
363 // Note that if I had to apply my patch then it gets activated here.
364         FXDCPrint *pd=(FXDCPrint *)pdc;
365         return pd->beginPage(page);
366     }
367 }
368 
369 // Generate end of page
370 
endPage()371 FXbool FXDCNativePrinter::endPage()
372 {
373     switch (dctype)
374     {
375 #ifdef WIN32
376 case TYPE_WIN32:
377         ::EndPage(dc);
378         pagecount++;
379         return TRUE;
380 #endif
381 default:                  // case TYPE_PS:
382         FXDCPrint *pd=(FXDCPrint *)pdc;
383         return pd->endPage();
384     }
385 }
386 
387 // Draw a point in the current pen color
388 
drawPoint(FXint x,FXint y)389 void FXDCNativePrinter::drawPoint(FXint x, FXint y)
390 {
391     pdc->drawPoint(ScaleX(x), ScaleY(y));
392 }
393 
394 // I need an array of points, arcs, rectangles into which I can scale things.
395 // By keeping a single array here I can extend it by need in a reasonably
396 // tidy way.
397 
398 static void *dst = NULL;
399 static int dst_buffer_size = 0;
400 #define DST_BUFFER_INCREMENT 128
401 
check_dst_buffer(int n,int sz)402 static void check_dst_buffer(int n, int sz)
403 {
404     int len = n*sz;
405     if (dst_buffer_size >= len) return;
406     if (dst_buffer_size!=0) free((void *)dst);
407 // I keep the buffer size a multiple of 128 bytes, and any time I have to
408 // extend it I round up the needed size to a multiple of that.
409     dst_buffer_size = len + (DST_BUFFER_INCREMENT - len%DST_BUFFER_INCREMENT);
410     void *p = (void *)malloc(len);
411 // my treatment of failure here is somewhat abrupt, and perhaps I should
412 // just do less drawing. But for now I intend to be fierce on this count.
413     if (p == NULL)
414     {   fprintf(stderr, "Fatal error: ran out of memory\n");
415         exit(1);
416     }
417     dst = p;
418 }
419 
420 // Draw points in the current pen color.
421 // Each point's position is relative to the drawable's origin (as usual).
422 
drawPoints(const FXPoint * points,FXuint npoints)423 void FXDCNativePrinter::drawPoints(const FXPoint* points,FXuint npoints)
424 {
425     check_dst_buffer(npoints, sizeof(FXPoint));
426     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
427     pdc->drawPoints((FXPoint *)dst, npoints);
428 }
429 
430 // Draw points in the current pen color. The first point's position is
431 // relative to the drawable's origin, but each subsequent point's position
432 // is relative to the previous point's position; each FXPoint defines
433 // the relative coordinates. Think LOGO.
434 
drawPointsRel(const FXPoint * points,FXuint npoints)435 void FXDCNativePrinter::drawPointsRel(const FXPoint*points,FXuint npoints)
436 {
437     check_dst_buffer(npoints, sizeof(FXPoint));
438     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
439     pdc->drawPointsRel((FXPoint *)dst, npoints);
440 }
441 
442 // Draw a line
443 
drawLine(FXint x1,FXint y1,FXint x2,FXint y2)444 void FXDCNativePrinter::drawLine(FXint x1, FXint y1, FXint x2, FXint y2)
445 {
446     pdc->drawLine(ScaleX(x1), ScaleY(y1), ScaleX(x2), ScaleY(y2));
447 }
448 
449 // Draw multiple lines. All points are drawn connected.
450 // Each point is specified relative to Drawable's origin.
451 
drawLines(const FXPoint * points,FXuint npoints)452 void FXDCNativePrinter::drawLines(const FXPoint* points, FXuint npoints)
453 {
454     check_dst_buffer(npoints, sizeof(FXPoint));
455     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
456     pdc->drawLines((FXPoint *)dst, npoints);
457 }
458 
459 // Draw multiple lines. All points are drawn connected.
460 // First point's coordinate is relative to drawable's origin, but
461 // subsequent points' coordinates are relative to previous point.
462 
drawLinesRel(const FXPoint * points,FXuint npoints)463 void FXDCNativePrinter::drawLinesRel(const FXPoint* points, FXuint npoints)
464 {
465     check_dst_buffer(npoints, sizeof(FXPoint));
466     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
467     pdc->drawLinesRel((FXPoint *)dst, npoints);
468 }
469 
470 // Draw unconnected line segments
471 
drawLineSegments(const FXSegment * segments,FXuint nsegments)472 void FXDCNativePrinter::drawLineSegments(const FXSegment* segments, FXuint nsegments)
473 {
474     check_dst_buffer(nsegments, sizeof(FXSegment));
475     scaleSegments((FXSegment *)dst, (FXSegment *)segments, nsegments);
476     pdc->drawLineSegments((FXSegment *)dst, nsegments);
477 }
478 
479 // Draw unfilled rectangle
480 
drawRectangle(FXint x,FXint y,FXint w,FXint h)481 void FXDCNativePrinter::drawRectangle(FXint x, FXint y, FXint w, FXint h)
482 {
483     pdc->drawRectangle(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h));
484 }
485 
486 // Draw unfilled rectangles
487 
drawRectangles(const FXRectangle * rectangles,FXuint nrectangles)488 void FXDCNativePrinter::drawRectangles(const FXRectangle* rectangles,FXuint nrectangles)
489 {
490     check_dst_buffer(nrectangles, sizeof(FXRectangle));
491     scaleRectangles((FXRectangle *)dst, (FXRectangle *)rectangles, nrectangles);
492     pdc->drawRectangles((FXRectangle *)dst, nrectangles);
493 }
494 
495 // Draw arc
496 
drawArc(FXint x,FXint y,FXint w,FXint h,FXint ang1,FXint ang2)497 void FXDCNativePrinter::drawArc(FXint x, FXint y, FXint w,
498                                 FXint h, FXint ang1, FXint ang2)
499 {
500     pdc->drawArc(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h), ang1, ang2);
501 }
502 
503 // Draw arcs
504 
drawArcs(const FXArc * arcs,FXuint narcs)505 void FXDCNativePrinter::drawArcs(const FXArc* arcs,FXuint narcs)
506 {
507     check_dst_buffer(narcs, sizeof(FXArc));
508     scaleArcs((FXArc *)dst, (FXArc *)arcs, narcs);
509     pdc->drawArcs((FXArc *)dst, narcs);
510 }
511 
512 // Filled rectangle
513 
fillRectangle(FXint x,FXint y,FXint w,FXint h)514 void FXDCNativePrinter::fillRectangle(FXint x, FXint y, FXint w, FXint h)
515 {
516     pdc->fillRectangle(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h));
517 }
518 
519 // Filled rectangles
520 
fillRectangles(const FXRectangle * rectangles,FXuint nrectangles)521 void FXDCNativePrinter::fillRectangles(const FXRectangle* rectangles,
522                                        FXuint nrectangles)
523 {
524     check_dst_buffer(nrectangles, sizeof(FXRectangle));
525     scaleRectangles((FXRectangle *)dst, (FXRectangle *)rectangles, nrectangles);
526     pdc->fillRectangles((FXRectangle *)dst, nrectangles);
527 }
528 
529 // Fill arc
530 
fillArc(FXint x,FXint y,FXint w,FXint h,FXint ang1,FXint ang2)531 void FXDCNativePrinter::fillArc(FXint x, FXint y, FXint w,
532                                 FXint h, FXint ang1, FXint ang2)
533 {
534     pdc->fillArc(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h), ang1, ang2);
535 }
536 
537 
538 // Fill arcs
539 
fillArcs(const FXArc * arcs,FXuint narcs)540 void FXDCNativePrinter::fillArcs(const FXArc *arcs, FXuint narcs)
541 {
542     check_dst_buffer(narcs, sizeof(FXArc));
543     scaleArcs((FXArc *)dst, (FXArc *)arcs, narcs);
544     pdc->fillArcs((FXArc *)dst, narcs);
545 }
546 
547 // Filled simple polygon
548 
fillPolygon(const FXPoint * points,FXuint npoints)549 void FXDCNativePrinter::fillPolygon(const FXPoint* points, FXuint npoints)
550 {
551     check_dst_buffer(npoints, sizeof(FXPoint));
552     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
553     pdc->fillPolygon((FXPoint *)dst, npoints);
554 }
555 
556 // Fill concave polygon
557 
fillConcavePolygon(const FXPoint * points,FXuint npoints)558 void FXDCNativePrinter::fillConcavePolygon(const FXPoint *points, FXuint npoints)
559 {
560     check_dst_buffer(npoints, sizeof(FXPoint));
561     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
562     pdc->fillConcavePolygon((FXPoint *)dst, npoints);
563 }
564 
565 // Fill complex (self-intersecting) polygon
566 
fillComplexPolygon(const FXPoint * points,FXuint npoints)567 void FXDCNativePrinter::fillComplexPolygon(const FXPoint *points, FXuint npoints)
568 {
569     check_dst_buffer(npoints, sizeof(FXPoint));
570     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
571     pdc->fillComplexPolygon((FXPoint *)dst, npoints);
572 }
573 
574 
575 // Filled simple polygon with relative points
576 
fillPolygonRel(const FXPoint * points,FXuint npoints)577 void FXDCNativePrinter::fillPolygonRel(const FXPoint *points, FXuint npoints)
578 {
579     check_dst_buffer(npoints, sizeof(FXPoint));
580     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
581     pdc->fillPolygonRel((FXPoint *)dst, npoints);
582 }
583 
584 // Fill concave polygon
585 
fillConcavePolygonRel(const FXPoint * points,FXuint npoints)586 void FXDCNativePrinter::fillConcavePolygonRel(const FXPoint *points, FXuint npoints)
587 {
588     check_dst_buffer(npoints, sizeof(FXPoint));
589     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
590     pdc->fillConcavePolygonRel((FXPoint *)dst, npoints);
591 }
592 
593 // Fill complex (self-intersecting) polygon
594 
fillComplexPolygonRel(const FXPoint * points,FXuint npoints)595 void FXDCNativePrinter::fillComplexPolygonRel(const FXPoint *points, FXuint npoints)
596 {
597     check_dst_buffer(npoints, sizeof(FXPoint));
598     scalePoints((FXPoint *)dst, (FXPoint *)points, npoints);
599     pdc->fillComplexPolygonRel((FXPoint *)dst, npoints);
600 }
601 
602 // Draw string (only foreground bits)
603 
drawText(FXint x,FXint y,const FXchar * string,FXuint len)604 void FXDCNativePrinter::drawText(FXint x, FXint y,
605                                  const FXchar *string, FXuint len)
606 {
607 /* TA_BASELINE does not work reliably with printers, so we need to adjust by hand */
608     pdc->drawText(ScaleX(x), ScaleY(y)-fontoffset, string, len);
609 }
610 
611 // Draw string (both foreground and background bits)
612 
drawImageText(FXint x,FXint y,const FXchar * string,FXuint len)613 void FXDCNativePrinter::drawImageText(FXint x, FXint y,
614                                       const FXchar*string,FXuint len)
615 {
616     pdc->drawImageText(ScaleX(x), ScaleY(y)-fontoffset, string, len);
617 }
618 
619 // Draw area from source
620 
drawArea(const FXDrawable * source,FXint sx,FXint sy,FXint sw,FXint sh,FXint dx,FXint dy)621 void FXDCNativePrinter::drawArea(const FXDrawable *source,
622                                  FXint sx, FXint sy, FXint sw, FXint sh,
623                                  FXint dx, FXint dy)
624 {
625     pdc->drawArea(source, sx, sy, sw, sh, ScaleX(dx), ScaleY(dy));
626 }
627 
628 // Draw image
629 
drawImage(const FXImage * img,FXint dx,FXint dy)630 void FXDCNativePrinter::drawImage(const FXImage *img, FXint dx, FXint dy)
631 {
632     pdc->drawImage(img, ScaleX(dx), ScaleY(dy));
633 }
634 
635 // Draw bitmap
636 
drawBitmap(const FXBitmap * bitmap,FXint dx,FXint dy)637 void FXDCNativePrinter::drawBitmap(const FXBitmap *bitmap, FXint dx, FXint dy)
638 {
639     pdc->drawBitmap(bitmap, ScaleX(dx), ScaleY(dy));
640 }
641 
642 
643 // Draw icon
644 
drawIcon(const FXIcon * icon,FXint dx,FXint dy)645 void FXDCNativePrinter::drawIcon(const FXIcon *icon, FXint dx, FXint dy)
646 {
647     pdc->drawIcon(icon, ScaleX(dx), ScaleY(dy));
648 }
649 
650 // Draw icon shaded
651 
drawIconShaded(const FXIcon * icon,FXint dx,FXint dy)652 void FXDCNativePrinter::drawIconShaded(const FXIcon *icon, FXint dx, FXint dy)
653 {
654     pdc->drawIconShaded(icon, ScaleX(dx), ScaleY(dy));
655 }
656 
657 // Draw icon sunken
658 
drawIconSunken(const FXIcon * icon,FXint dx,FXint dy)659 void FXDCNativePrinter::drawIconSunken(const FXIcon *icon, FXint dx, FXint dy)
660 {
661     pdc->drawIconSunken(icon, ScaleX(dx), ScaleY(dy));
662 }
663 
664 // Draw hashed box
665 
drawHashBox(FXint x,FXint y,FXint w,FXint h,FXint b)666 void FXDCNativePrinter::drawHashBox(FXint x, FXint y, FXint w, FXint h,
667                                     FXint b)
668 {
669   // FIXME: Scaling border by horizontal resolution,
670   // what when logpixelsx != logpixelsy ?
671     pdc->drawHashBox(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h), ScaleX(b));
672 }
673 
674 // Set foreground drawing color (brush)
675 
setForeground(FXColor clr)676 void FXDCNativePrinter::setForeground(FXColor clr)
677 {
678     pdc->setForeground(clr);
679 }
680 
681 // Set background drawing color (brush)
682 
setBackground(FXColor clr)683 void FXDCNativePrinter::setBackground(FXColor clr)
684 {
685     pdc->setBackground(clr);
686 }
687 
688 // Set dash pattern
689 
setDashes(FXuint dashoffset,const FXchar * dashpattern,FXuint dashlength)690 void FXDCNativePrinter::setDashes(FXuint dashoffset, const FXchar *dashpattern, FXuint dashlength)
691 {
692     pdc->setDashes(dashoffset, dashpattern, dashlength);
693 }
694 
695 // Set line width
696 
setLineWidth(FXuint linewidth)697 void FXDCNativePrinter::setLineWidth(FXuint linewidth)
698 {
699     // FIXME: Scaling by X resolution, what if Xdpi != Ydpi ?
700     pdc->setLineWidth(ScaleX(linewidth));
701 }
702 
703 // Set line cap style
704 
setLineCap(FXCapStyle capstyle)705 void FXDCNativePrinter::setLineCap(FXCapStyle capstyle)
706 {
707     pdc->setLineCap(capstyle);
708 }
709 
710 // Set line join style
711 
setLineJoin(FXJoinStyle joinstyle)712 void FXDCNativePrinter::setLineJoin(FXJoinStyle joinstyle)
713 {
714     pdc->setLineJoin(joinstyle);
715 }
716 
717 // Set line style
718 
setLineStyle(FXLineStyle linestyle)719 void FXDCNativePrinter::setLineStyle(FXLineStyle linestyle)
720 {
721     pdc->setLineStyle(linestyle);
722 }
723 
724 // Set fill style
725 
setFillStyle(FXFillStyle fillstyle)726 void FXDCNativePrinter::setFillStyle(FXFillStyle fillstyle)
727 {
728     pdc->setFillStyle(fillstyle);
729 }
730 
731 // Set fill rule
732 
setFillRule(FXFillRule fillrule)733 void FXDCNativePrinter::setFillRule(FXFillRule fillrule)
734 {
735     pdc->setFillRule(fillrule);
736 }
737 
738 // Set blit function
739 
setFunction(FXFunction func)740 void FXDCNativePrinter::setFunction(FXFunction func)
741 {
742     pdc->setFunction(func);
743 }
744 
745 // Set tile image
746 
setTile(FXImage * image,FXint dx,FXint dy)747 void FXDCNativePrinter::setTile(FXImage *image, FXint dx, FXint dy)
748 {
749     pdc->setTile(image, dx, dy);  // TODO: Check if dx,dy should be scaled
750 }
751 
752 // Set stipple pattern
753 
setStipple(FXBitmap * bitmap,FXint dx,FXint dy)754 void FXDCNativePrinter::setStipple(FXBitmap *bitmap, FXint dx, FXint dy)
755 {
756     pdc->setStipple(bitmap, dx, dy); // TODO: Check if dx,dy should be scaled
757 }
758 
759 // Set stipple pattern
760 
setStipple(FXStipplePattern pat,FXint dx,FXint dy)761 void FXDCNativePrinter::setStipple(FXStipplePattern pat, FXint dx, FXint dy)
762 {
763     pdc->setStipple(pat, dx, dy); // TODO: Check if dx,dy should be scaled
764 }
765 
766 // Set clip rectangle
767 
setClipRectangle(FXint x,FXint y,FXint w,FXint h)768 void FXDCNativePrinter::setClipRectangle(FXint x, FXint y, FXint w, FXint h)
769 {
770     pdc->setClipRectangle(ScaleX(x), ScaleY(y), ScaleX(w), ScaleY(h));
771 }
772 
773 // Set clip rectangle
774 
setClipRectangle(const FXRectangle & rectangle)775 void FXDCNativePrinter::setClipRectangle(const FXRectangle &rectangle)
776 {
777     pdc->setClipRectangle(ScaleX(rectangle.x), ScaleY(rectangle.y),
778                           ScaleX(rectangle.w), ScaleY(rectangle.h));
779 }
780 
781 // Clear clipping
782 
clearClipRectangle()783 void FXDCNativePrinter::clearClipRectangle()
784 {
785     pdc->clearClipRectangle();
786 }
787 
788 // Set clip mask
789 
setClipMask(FXBitmap * bitmap,FXint dx,FXint dy)790 void FXDCNativePrinter::setClipMask(FXBitmap *bitmap, FXint dx, FXint dy)
791 {
792     pdc->setClipMask(bitmap, dx, dy);  // TODO: Check if dx,dy should be scaled
793 }
794 
795 // Clear clip mask
796 
clearClipMask()797 void FXDCNativePrinter::clearClipMask()
798 {
799     pdc->clearClipMask();
800 }
801 
802 // Set font to draw text with
803 
setFont(FXFont * fnt)804 void FXDCNativePrinter::setFont(FXFont *fnt)
805 {
806     font=fnt;
807     pdc->setFont(fnt);
808     fontoffset=0;
809 #ifdef FONT_NOT_VIRTUAL
810     if (dctype==TYPE_PS) postscriptFont = (FX::FXPostscriptFont *)font;
811 #endif
812     if (dctype==TYPE_WIN32) fontoffset = font->getFontAscent();
813 }
814 
815 // Change clip-against-child windows mode
816 
clipChildren(FXbool yes)817 void FXDCNativePrinter::clipChildren(FXbool yes)
818 {
819    // Do nothing
820 }
821 
822 //
823 // Now the helper code that scales vectors of stuff for me.
824 //
825 
scalePoints(FXPoint * dst1,FXPoint * src,FXuint npoints)826 void FXDCNativePrinter::scalePoints(FXPoint *dst1, FXPoint *src, FXuint npoints)
827 {
828     for (;npoints>0;npoints--,dst1++,src++)
829     {   dst1->x = ScaleX(src->x);
830         dst1->y = ScaleY(src->y);
831     }
832 }
833 
scaleRectangles(FXRectangle * dst1,FXRectangle * src,FXuint nrectangles)834 void FXDCNativePrinter::scaleRectangles(FXRectangle *dst1, FXRectangle *src, FXuint nrectangles)
835 {
836     for (;nrectangles>0;nrectangles--,dst1++,src++)
837     {   dst1->x = ScaleX(src->x);
838         dst1->y = ScaleY(src->y);
839         dst1->w = ScaleX(src->w);
840         dst1->h = ScaleY(src->h);
841     }
842 }
843 
scaleSegments(FXSegment * dst1,FXSegment * src,FXuint nsegments)844 void FXDCNativePrinter::scaleSegments(FXSegment *dst1, FXSegment *src, FXuint nsegments)
845 {
846     for (;nsegments>0;nsegments--,dst1++,src++)
847     {   dst1->x1 = ScaleX(src->x1);
848         dst1->y1 = ScaleY(src->y1);
849         dst1->x2 = ScaleX(src->x2);
850         dst1->y2 = ScaleY(src->y2);
851     }
852 }
853 
scaleArcs(FXArc * dst1,FXArc * src,FXuint narcs)854 void FXDCNativePrinter::scaleArcs(FXArc *dst1, FXArc *src, FXuint narcs)
855 {
856     for (;narcs>0;narcs--,dst1++,src++)
857     {   dst1->x = ScaleX(src->x);
858         dst1->y = ScaleY(src->y);
859         dst1->w = ScaleX(src->w);
860         dst1->h = ScaleY(src->h);
861         dst1->a = src->a;
862         dst1->b = src->b;
863     }
864 }
865 
866 
setHorzUnitsInch(FXfloat sx)867 void FXDCNativePrinter::setHorzUnitsInch(FXfloat sx)
868 {
869     scalex = logpixelsx / sx;
870     unitsx = sx;
871 }
872 
setVertUnitsInch(FXfloat sy)873 void FXDCNativePrinter::setVertUnitsInch(FXfloat sy)
874 {
875     scaley = logpixelsy / sy;
876     unitsx = sy;
877 }
878 
879 // Create a font, paying attention to the scaling currently in force.
880 
fntGenerateFont(const FXString & face,FXuint sz,FXuint wt,FXuint sl,FXuint enc,FXuint setw,FXuint h)881 FXFont *FXDCNativePrinter::fntGenerateFont(const FXString &face,
882     FXuint sz, FXuint wt, FXuint sl, FXuint enc, FXuint setw, FXuint h)
883 {
884     return fntDoubleGenerateFont(face, (double)sz, wt, sl, enc, setw, h);
885 }
886 
887 // The next version takes the desired point size as a double not an
888 // int. Because windows printer fonts actually exist at pixel-size based on
889 // printer resolution they can exist in visible sizes that vary much
890 // more finely than integer point sizes would allow one to express. And
891 // both with Postscript and Truetype fonts utterly arbitrary scaling
892 // can be applied. With Postscript my font's size will be specified
893 // internally in decipoints so at least we can have sizes 5.1, 5.2, 5.3 etc.
894 
fntDoubleGenerateFont(const FXString & face,double sz,FXuint wt,FXuint sl,FXuint enc,FXuint setw,FXuint h)895 FXFont *FXDCNativePrinter::fntDoubleGenerateFont(const FXString &face,
896     double sz, FXuint wt, FXuint sl, FXuint enc, FXuint setw, FXuint h)
897 {
898     if (dctype == TYPE_WIN32)
899         return new FXFont(getApp(), face, (int)(sz * fontScale), wt,
900                           sl, enc, setw, h);
901     else  // otherwise I am to generate Postscript
902     {   FXFontDesc fdd;
903         memset((void *)&fdd, 0, sizeof(fdd));
904         strcpy(fdd.face, face.text());
905 // The whole purpose of constructing via FXFontDesc is to give size in
906 // decipoints not points. I can not use the fontScale trick here without
907 // re-working how FXDCPrint prints things...
908         fdd.size = (int)(10.0*sz + 0.5);
909         fdd.weight = wt;
910         fdd.slant = sl;
911         fdd.encoding = enc;
912         fdd.setwidth = setw;
913         fdd.flags = h;
914 // the explicit FX:: on the next line is needed to allow this code to
915 // compile using both FOX 1.0 and FOX 1.1!!!
916         return new FX::FXPostscriptFont(getApp(), fdd);
917     }
918 }
919 
920 //
921 // Most of the stuff that follows is just delegating actions to an
922 // underlying DC, possibly applying scaling. The scaling is so that the
923 // user can select the (integer-based) unit of measurement... in some cases
924 // the default unit of 1pt (= 1/72in here) would be too coarse. It is
925 // STRONGLY suggested that anybody changing units should use the same
926 // ones for both X and Y, since otherwise indicating sizes for values
927 // not keyed to axis direction (eg line width) gets very questionable indeed.
928 // I think maybe the API would be safer with just a single scaling option
929 // not two.  Note also that font sizes are always specified in points
930 // regardless of other options being set.
931 
fntGetName()932 FXString FXDCNativePrinter::fntGetName()
933 {
934 // the font-name returned will be the full Postscript font name. Handing it
935 // back to try to create a new font will NOT be a good idea, since it has
936 // Bold and Italic/Oblique info muddled up in it.
937     return font->getName();
938 }
939 
fntGetSize()940 FXuint FXDCNativePrinter::fntGetSize()
941 {
942 // NOTE that this returns the size in decipoints not points.
943     return (FXuint)(fontScaleBack * (FXfloat)font->getSize());
944 }
945 
946 // return font size (in points) as a double not an integer, so that
947 // fractional point sizes can be handled better.
948 
fntDoubleSize()949 double FXDCNativePrinter::fntDoubleSize()
950 {
951 // NOTE that this returns the size in decipoints not points.
952     return (double)(fontScaleBack * (FXfloat)font->getSize());
953 }
954 
fntGetWeight()955 FXuint FXDCNativePrinter::fntGetWeight()
956 {
957     return font->getWeight();
958 }
959 
fntGetSlant()960 FXuint FXDCNativePrinter::fntGetSlant()
961 {
962     return font->getSlant();
963 }
964 
fntGetEncoding()965 FXuint FXDCNativePrinter::fntGetEncoding()
966 {
967     return font->getEncoding();
968 }
969 
fntGetSetWidth()970 FXuint FXDCNativePrinter::fntGetSetWidth()
971 {
972     return font->getSetWidth();
973 }
974 
fntGetHints()975 FXuint FXDCNativePrinter::fntGetHints()
976 {
977     return font->getHints();
978 }
979 
fntGetFontDesc(FXFontDesc & fontdesc) const980 void FXDCNativePrinter::fntGetFontDesc(FXFontDesc &fontdesc) const
981 {
982     font->getFontDesc(fontdesc);
983 }
984 
fntSetFontDesc(const FXFontDesc & fontdesc)985 void FXDCNativePrinter::fntSetFontDesc(const FXFontDesc &fontdesc)
986 {
987     font->setFontDesc(fontdesc);
988 }
989 
fntIsFontMono() const990 FXbool FXDCNativePrinter::fntIsFontMono() const
991 {
992 #ifdef FONT_NOT_VIRTUAL
993     if (dctype==TYPE_PS) return postscriptFont->isFontMono();
994 #endif
995     return font->isFontMono();
996 }
997 
fntHasChar(FXint ch) const998 FXbool FXDCNativePrinter::fntHasChar(FXint ch) const
999 {
1000 #ifdef FONT_NOT_VIRTUAL
1001     if (dctype==TYPE_PS) return postscriptFont->hasChar(ch);
1002 #endif
1003     return font->hasChar(ch);
1004 }
1005 
fntGetMinChar() const1006 FXint FXDCNativePrinter::fntGetMinChar() const
1007 {
1008 #ifdef FONT_NOT_VIRTUAL
1009     if (dctype==TYPE_PS) return postscriptFont->getMinChar();
1010 #endif
1011     return (FXint)font->getMinChar();
1012 }
1013 
fntGetMaxChar() const1014 FXint FXDCNativePrinter::fntGetMaxChar() const
1015 {
1016 #ifdef FONT_NOT_VIRTUAL
1017     if (dctype==TYPE_PS) return postscriptFont->getMaxChar();
1018 #endif
1019     return (FXint)font->getMaxChar();
1020 }
1021 
1022 //
1023 // There is a big ugly issue about fonts and measurements here. For Windows
1024 // fonts will have been created internally at some huge point size based
1025 // on the actual resolution of the printer. The factor scalex includes
1026 // allowance for that and so enough precision is kept.
1027 // For Postscript generation the font thinks (at an internal level) that
1028 // it is the point size you actually want it to appear at. The effect is
1029 // that character heights and widths are often quite small values (eg
1030 // for a 10pt pont they are comparable with 10. Returning measurements as
1031 // integers in such a case would give severe truncation effects.
1032 // To work around this I arrange that the FXPostScriptFont class returns
1033 // font measurements scaled by 1000. I have to undo this here. The
1034 // multiplication by PSscale is to do that.
1035 //
1036 
1037 // For Postscript generation (and on X) the bearings that I return will be
1038 // the maximum values across the font.
1039 
fntLeftBearing(FXchar ch) const1040 FXint FXDCNativePrinter::fntLeftBearing(FXchar ch) const
1041 {
1042 #ifdef FONT_NOT_VIRTUAL
1043     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->leftBearing(ch) / scalex);
1044 #endif
1045     return (FXint)(PSscale * font->leftBearing(ch) / scalex);
1046 }
1047 
fntDoubleLeftBearing(FXchar ch) const1048 double FXDCNativePrinter::fntDoubleLeftBearing(FXchar ch) const
1049 {
1050 #ifdef FONT_NOT_VIRTUAL
1051     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->leftBearing(ch) / scalex);
1052 #endif
1053     return (double)(PSscale * font->leftBearing(ch) / scalex);
1054 }
1055 
fntRightBearing(FXchar ch) const1056 FXint FXDCNativePrinter::fntRightBearing(FXchar ch) const
1057 {
1058 #ifdef FONT_NOT_VIRTUAL
1059     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->rightBearing(ch) / scalex);
1060 #endif
1061     return (FXint)(PSscale * font->rightBearing(ch) / scalex);
1062 }
1063 
fntDoubleRightBearing(FXchar ch) const1064 double FXDCNativePrinter::fntDoubleRightBearing(FXchar ch) const
1065 {
1066 #ifdef FONT_NOT_VIRTUAL
1067     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->rightBearing(ch) / scalex);
1068 #endif
1069     return (double)(PSscale * font->rightBearing(ch) / scalex);
1070 }
1071 
1072 //
1073 // If one has left the UnitsInch at its default of 72 then
1074 // measurements are only precise to 1pt. This is generally not good
1075 // enough when laying out a line. To get better accuracy you can either
1076 // reset your units to say 1/3600in or use floating point values here.
1077 //
1078 
fntGetFontWidth() const1079 FXint FXDCNativePrinter::fntGetFontWidth() const
1080 {
1081 #ifdef FONT_NOT_VIRTUAL
1082     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontWidth() / scalex);
1083 #endif
1084     return (FXint)(PSscale * font->getFontWidth() / scalex);
1085 }
1086 
fntDoubleFontWidth() const1087 double FXDCNativePrinter::fntDoubleFontWidth() const
1088 {
1089 #ifdef FONT_NOT_VIRTUAL
1090     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontWidth() / scalex);
1091 #endif
1092     return (double)(PSscale * font->getFontWidth() / scalex);
1093 }
1094 
fntGetFontHeight() const1095 FXint FXDCNativePrinter::fntGetFontHeight() const
1096 {
1097 #ifdef FONT_NOT_VIRTUAL
1098     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontHeight() / scaley);
1099 #endif
1100     return (FXint)(PSscale * font->getFontHeight() / scaley);
1101 }
1102 
fntDoubleFontHeight() const1103 double FXDCNativePrinter::fntDoubleFontHeight() const
1104 {
1105 #ifdef FONT_NOT_VIRTUAL
1106     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontHeight() / scaley);
1107 #endif
1108     return (double)(PSscale * font->getFontHeight() / scaley);
1109 }
1110 
fntGetFontAscent() const1111 FXint FXDCNativePrinter::fntGetFontAscent() const
1112 {
1113 #ifdef FONT_NOT_VIRTUAL
1114     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontAscent() / scaley);
1115 #endif
1116     return (FXint)(PSscale * font->getFontAscent() / scaley);
1117 }
1118 
fntDoubleFontAscent() const1119 double FXDCNativePrinter::fntDoubleFontAscent() const
1120 {
1121 #ifdef FONT_NOT_VIRTUAL
1122     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontAscent() / scaley);
1123 #endif
1124     return (double)(PSscale * font->getFontAscent() / scaley);
1125 }
1126 
fntGetFontDescent() const1127 FXint FXDCNativePrinter::fntGetFontDescent() const
1128 {
1129 #ifdef FONT_NOT_VIRTUAL
1130     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontDescent() / scaley);
1131 #endif
1132     return (FXint)(PSscale * font->getFontDescent() / scaley);
1133 }
1134 
fntDoubleFontDescent() const1135 double FXDCNativePrinter::fntDoubleFontDescent() const
1136 {
1137 #ifdef FONT_NOT_VIRTUAL
1138     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontDescent() / scaley);
1139 #endif
1140     return (double)(PSscale * font->getFontDescent() / scaley);
1141 }
1142 
fntGetFontLeading() const1143 FXint FXDCNativePrinter::fntGetFontLeading() const
1144 {
1145 #ifdef FONT_NOT_VIRTUAL
1146     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontLeading() / scaley);
1147 #endif
1148     return (FXint)(PSscale * font->getFontLeading() / scaley);
1149 }
1150 
fntDoubleFontLeading() const1151 double FXDCNativePrinter::fntDoubleFontLeading() const
1152 {
1153 #ifdef FONT_NOT_VIRTUAL
1154     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontLeading() / scaley);
1155 #endif
1156     return (FXint)(PSscale * font->getFontLeading() / scaley);
1157 }
1158 
fntGetFontSpacing() const1159 FXint FXDCNativePrinter::fntGetFontSpacing() const
1160 {
1161 #ifdef FONT_NOT_VIRTUAL
1162     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getFontSpacing() / scaley);
1163 #endif
1164     return (FXint)(PSscale * font->getFontSpacing() / scaley);
1165 }
1166 
fntDoubleFontSpacing() const1167 double FXDCNativePrinter::fntDoubleFontSpacing() const
1168 {
1169 #ifdef FONT_NOT_VIRTUAL
1170     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getFontSpacing() / scaley);
1171 #endif
1172     return (double)(PSscale * font->getFontSpacing() / scaley);
1173 }
1174 
fntGetTextWidth(const FXchar * text,FXuint n) const1175 FXint FXDCNativePrinter::fntGetTextWidth(const FXchar *text, FXuint n) const
1176 {
1177 #ifdef FONT_NOT_VIRTUAL
1178     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getTextWidth(text, n) / scalex);
1179 #endif
1180     return (FXint)(PSscale * font->getTextWidth(text, n) / scalex);
1181 }
1182 
fntDoubleTextWidth(const FXchar * text,FXuint n) const1183 double FXDCNativePrinter::fntDoubleTextWidth(const FXchar *text, FXuint n) const
1184 {
1185 #ifdef FONT_NOT_VIRTUAL
1186     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getTextWidth(text, n) / scalex);
1187 #endif
1188     return (double)(PSscale * font->getTextWidth(text, n) / scalex);
1189 }
1190 
fntGetTextHeight(const FXchar * text,FXuint n) const1191 FXint FXDCNativePrinter::fntGetTextHeight(const FXchar *text, FXuint n) const
1192 {
1193 #ifdef FONT_NOT_VIRTUAL
1194     if (dctype==TYPE_PS) return (FXint)(PSscale * postscriptFont->getTextHeight(text, n) / scaley);
1195 #endif
1196     return (FXint)(PSscale * font->getTextHeight(text, n) / scaley);
1197 }
1198 
fntDoubleTextHeight(const FXchar * text,FXuint n) const1199 double FXDCNativePrinter::fntDoubleTextHeight(const FXchar *text, FXuint n) const
1200 {
1201 #ifdef FONT_NOT_VIRTUAL
1202     if (dctype==TYPE_PS) return (double)(PSscale * postscriptFont->getTextHeight(text, n) / scaley);
1203 #endif
1204     return (double)(PSscale * font->getTextHeight(text, n) / scaley);
1205 }
1206 
getPageWidth(void)1207 FXint FXDCNativePrinter::getPageWidth(void)
1208 {
1209     return (FXint)(pagewidth / scalex);
1210 }
1211 
doublePageWidth(void)1212 double FXDCNativePrinter::doublePageWidth(void)
1213 {
1214     return (double)(pagewidth / scalex);
1215 }
1216 
getPageHeight(void)1217 FXint FXDCNativePrinter::getPageHeight(void)
1218 {
1219     return (FXint)(pageheight / scaley);
1220 }
1221 
doublePageHeight(void)1222 double FXDCNativePrinter::doublePageHeight(void)
1223 {
1224     return (double)(pageheight / scaley);
1225 }
1226 
1227 }
1228 
1229 // end of FXDCNativePrinter.cpp
1230