home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / xlate / ps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  24.1 KB  |  726 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "xlate_i.h"
  20. #include "isotab.c"
  21. #include "locale.h"
  22.  
  23. #define RED_PART 0.299        /* Constants for converting RGB to greyscale */
  24. #define GREEN_PART 0.587
  25. #define BLUE_PART 0.114
  26.  
  27. #define XL_SET_NUMERIC_LOCALE() char* cur_locale = setlocale(LC_NUMERIC, "C")
  28. #define XL_RESTORE_NUMERIC_LOCALE() setlocale(LC_NUMERIC, cur_locale)
  29.  
  30. /*
  31. ** These two functions swap values around in order to deal with page
  32. ** rotation.
  33. */
  34.  
  35. void xl_initialize_translation(MWContext *cx, PrintSetup* pi)
  36. {
  37.   PrintSetup *dup = XP_NEW(PrintSetup);
  38.   *dup = *pi;
  39.   cx->prSetup = dup;
  40.   dup->width = POINT_TO_PAGE(dup->width);
  41.   dup->height = POINT_TO_PAGE(dup->height);
  42.   dup->top = POINT_TO_PAGE(dup->top);
  43.   dup->left = POINT_TO_PAGE(dup->left);
  44.   dup->bottom = POINT_TO_PAGE(dup->bottom);
  45.   dup->right = POINT_TO_PAGE(dup->right);
  46.   if (pi->landscape)
  47.   {
  48.     dup->height = POINT_TO_PAGE(pi->width);
  49.     dup->width = POINT_TO_PAGE(pi->height);
  50.     /* XXX Should I swap the margins too ??? */
  51.   }    
  52. }
  53.  
  54. void xl_finalize_translation(MWContext *cx)
  55. {
  56.     XP_DELETE(cx->prSetup);
  57.     cx->prSetup = NULL;
  58. }
  59.  
  60. void xl_begin_document(MWContext *cx)
  61. {
  62.     int i;
  63.     XP_File f;
  64.  
  65.     f = cx->prSetup->out;
  66.     XP_FilePrintf(f, "%%!PS-Adobe-3.0\n");
  67.     XP_FilePrintf(f, "%%%%BoundingBox: %d %d %d %d\n",
  68.         PAGE_TO_POINT_I(cx->prSetup->left),
  69.     PAGE_TO_POINT_I(cx->prSetup->bottom),
  70.     PAGE_TO_POINT_I(cx->prSetup->width-cx->prSetup->right),
  71.     PAGE_TO_POINT_I(cx->prSetup->height-cx->prSetup->top));
  72.     XP_FilePrintf(f, "%%%%Creator: Mozilla (NetScape) HTML->PS\n");
  73.     XP_FilePrintf(f, "%%%%DocumentData: Clean7Bit\n");
  74.     XP_FilePrintf(f, "%%%%Orientation: %s\n",
  75.         (cx->prSetup->width < cx->prSetup->height) ? "Portrait" : "Landscape");
  76.     XP_FilePrintf(f, "%%%%Pages: %d\n", (int) cx->prInfo->n_pages);
  77.     if (cx->prSetup->reverse)
  78.     XP_FilePrintf(f, "%%%%PageOrder: Descend\n");
  79.     else
  80.     XP_FilePrintf(f, "%%%%PageOrder: Ascend\n");
  81.     XP_FilePrintf(f, "%%%%Title: %s\n", cx->prInfo->doc_title);
  82. #ifdef NOTYET
  83.     XP_FilePrintf(f, "%%%%For: %n", user_name_stuff);
  84. #endif
  85.     XP_FilePrintf(f, "%%%%EndComments\n");
  86.     
  87.     XP_FilePrintf(f, "%%%%BeginProlog\n");
  88.     XP_FilePrintf(f, "[");
  89.     for (i = 0; i < 256; i++)
  90.       {
  91.     if (*isotab[i] == '\0')
  92.       XP_FilePrintf(f, " /.notdef");
  93.     else
  94.       XP_FilePrintf(f, " /%s", isotab[i]);
  95.     if (( i % 10) == 9)
  96.       XP_FilePrintf(f, "\n");
  97.       }
  98.     XP_FilePrintf(f, "] /isolatin1encoding exch def\n");
  99.     XP_FilePrintf(f, "/c { matrix currentmatrix currentpoint translate\n");
  100.     XP_FilePrintf(f, "     3 1 roll scale newpath 0 0 1 0 360 arc setmatrix } bind def\n");
  101.     for (i = 0; i < N_FONTS; i++)
  102.     XP_FilePrintf(f, 
  103.         "/F%d\n"
  104.         "    /%s findfont\n"
  105.         "    dup length dict begin\n"
  106.         "    {1 index /FID ne {def} {pop pop} ifelse} forall\n"
  107.         "    /Encoding isolatin1encoding def\n"
  108.         "    currentdict end\n"
  109.         "definefont pop\n"
  110.         "/f%d { /F%d findfont exch scalefont setfont } bind def\n",
  111.         i, PSFE_MaskToFI[i]->name, i, i);
  112.     if (cx->prSetup->otherFontName)
  113.       XP_FilePrintf(f, "/of { /%s findfont exch scalefont "
  114.              "setfont } bind def\n", cx->prSetup->otherFontName);
  115.     XP_FilePrintf(f, "/rhc {\n");
  116.     XP_FilePrintf(f, "    {\n");
  117.     XP_FilePrintf(f, "        currentfile read {\n");
  118.     XP_FilePrintf(f, "        dup 97 ge\n");
  119.     XP_FilePrintf(f, "        { 87 sub true exit }\n");
  120.     XP_FilePrintf(f, "        { dup 48 ge { 48 sub true exit } { pop } ifelse }\n");
  121.     XP_FilePrintf(f, "        ifelse\n");
  122.     XP_FilePrintf(f, "    } {\n");
  123.     XP_FilePrintf(f, "        false\n");
  124.     XP_FilePrintf(f, "        exit\n");
  125.     XP_FilePrintf(f, "    } ifelse\n");
  126.     XP_FilePrintf(f, "    } loop\n");
  127.     XP_FilePrintf(f, "} bind def\n");
  128.     XP_FilePrintf(f, "\n");
  129.     XP_FilePrintf(f, "/cvgray { %% xtra_char npix cvgray - (string npix long)\n");
  130.     XP_FilePrintf(f, "    dup string\n");
  131.     XP_FilePrintf(f, "    0\n");
  132.     XP_FilePrintf(f, "    {\n");
  133.     XP_FilePrintf(f, "    rhc { cvr 4.784 mul } { exit } ifelse\n");
  134.     XP_FilePrintf(f, "    rhc { cvr 9.392 mul } { exit } ifelse\n");
  135.     XP_FilePrintf(f, "    rhc { cvr 1.824 mul } { exit } ifelse\n");
  136.     XP_FilePrintf(f, "    add add cvi 3 copy put pop\n");
  137.     XP_FilePrintf(f, "    1 add\n");
  138.     XP_FilePrintf(f, "    dup 3 index ge { exit } if\n");
  139.     XP_FilePrintf(f, "    } loop\n");
  140.     XP_FilePrintf(f, "    pop\n");
  141.     XP_FilePrintf(f, "    3 -1 roll 0 ne { rhc { pop } if } if\n");
  142.     XP_FilePrintf(f, "    exch pop\n");
  143.     XP_FilePrintf(f, "} bind def\n");
  144.     XP_FilePrintf(f, "\n");
  145.     XP_FilePrintf(f, "/smartimage12rgb { %% w h b [matrix] smartimage12rgb -\n");
  146.     XP_FilePrintf(f, "    /colorimage where {\n");
  147.     XP_FilePrintf(f, "    pop\n");
  148.     XP_FilePrintf(f, "    { currentfile rowdata readhexstring pop }\n");
  149.     XP_FilePrintf(f, "    false 3\n");
  150.     XP_FilePrintf(f, "    colorimage\n");
  151.     XP_FilePrintf(f, "    } {\n");
  152.     XP_FilePrintf(f, "    exch pop 8 exch\n");
  153.     XP_FilePrintf(f, "    3 index 12 mul 8 mod 0 ne { 1 } { 0 } ifelse\n");
  154.     XP_FilePrintf(f, "    4 index\n");
  155.     XP_FilePrintf(f, "    6 2 roll\n");
  156.     XP_FilePrintf(f, "    { 2 copy cvgray }\n");
  157.     XP_FilePrintf(f, "    image\n");
  158.     XP_FilePrintf(f, "    pop pop\n");
  159.     XP_FilePrintf(f, "    } ifelse\n");
  160.     XP_FilePrintf(f, "} def\n");
  161.     XP_FilePrintf(f,"/cshow { dup stringwidth pop 2 div neg 0 rmoveto show } bind def\n");  
  162.      XP_FilePrintf(f,"/rshow { dup stringwidth pop neg 0 rmoveto show } bind def\n");
  163.     XP_FilePrintf(f, "/BeginEPSF {\n");
  164.     XP_FilePrintf(f, "  /b4_Inc_state save def\n");
  165.     XP_FilePrintf(f, "  /dict_count countdictstack def\n");
  166.     XP_FilePrintf(f, "  /op_count count 1 sub def\n");
  167.     XP_FilePrintf(f, "  userdict begin\n");
  168.     XP_FilePrintf(f, "  /showpage {} def\n");
  169.     XP_FilePrintf(f, "  0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin\n");
  170.     XP_FilePrintf(f, "  10 setmiterlimit [] 0 setdash newpath\n");
  171.     XP_FilePrintf(f, "  /languagelevel where\n");
  172.     XP_FilePrintf(f, "  { pop languagelevel 1 ne\n");
  173.     XP_FilePrintf(f, "    { false setstrokeadjust false setoverprint } if\n");
  174.     XP_FilePrintf(f, "  } if\n");
  175.     XP_FilePrintf(f, "} bind def\n");
  176.     XP_FilePrintf(f, "/EndEPSF {\n");
  177.     XP_FilePrintf(f, "  count op_count sub {pop} repeat\n");
  178.     XP_FilePrintf(f, "  countdictstack dict_count sub {end} repeat\n");
  179.     XP_FilePrintf(f, "  b4_Inc_state restore\n");
  180.     XP_FilePrintf(f, "} bind def\n");
  181.    XP_FilePrintf(f, "%%%%EndProlog\n");
  182. }
  183.  
  184. void xl_begin_page(MWContext *cx, int pn)
  185. {
  186.   XP_File f;
  187.  
  188.   f = cx->prSetup->out;
  189.   pn++;
  190.   XP_FilePrintf(f, "%%%%Page: %d %d\n", pn, pn);
  191.   XP_FilePrintf(f, "%%%%BeginPageSetup\n/pagelevel save def\n");
  192.   if (cx->prSetup->landscape)
  193.     XP_FilePrintf(f, "%d 0 translate 90 rotate\n",
  194.           PAGE_TO_POINT_I(cx->prSetup->height));
  195.   XP_FilePrintf(f, "%d 0 translate\n", PAGE_TO_POINT_I(cx->prSetup->left));
  196.   XP_FilePrintf(f, "%%%%EndPageSetup\n");
  197. #if 0
  198.   xl_annotate_page(cx, cx->prSetup->header, 0, -1, pn);
  199. #endif
  200.   XP_FilePrintf(f, "newpath 0 %d moveto ", PAGE_TO_POINT_I(cx->prSetup->bottom));
  201.   XP_FilePrintf(f, "%d 0 rlineto 0 %d rlineto -%d 0 rlineto ",
  202.             PAGE_TO_POINT_I(cx->prInfo->page_width),
  203.             PAGE_TO_POINT_I(cx->prInfo->page_height),
  204.             PAGE_TO_POINT_I(cx->prInfo->page_width));
  205.   XP_FilePrintf(f, " closepath clip newpath\n");
  206. }
  207.  
  208. void xl_end_page(MWContext *cx, int pn)
  209. {
  210. #if 0
  211.   xl_annotate_page(cx, cx->prSetup->footer,
  212.            cx->prSetup->height-cx->prSetup->bottom-cx->prSetup->top,
  213.            1, pn);
  214.   XP_FilePrintf(cx->prSetup->out, "pagelevel restore\nshowpage\n");
  215. #endif
  216.  
  217.   XP_FilePrintf(cx->prSetup->out, "pagelevel restore\n");
  218.   xl_annotate_page(cx, cx->prSetup->header, cx->prSetup->top/2, -1, pn);
  219.   xl_annotate_page(cx, cx->prSetup->footer,
  220.                    cx->prSetup->height - cx->prSetup->bottom/2,
  221.                    1, pn);
  222.   XP_FilePrintf(cx->prSetup->out, "showpage\n");
  223. }
  224.  
  225. void xl_end_document(MWContext *cx)
  226. {
  227.     XP_FilePrintf(cx->prSetup->out, "%%%%EOF\n");
  228. }
  229.  
  230. void xl_moveto(MWContext* cx, int x, int y)
  231. {
  232.   XL_SET_NUMERIC_LOCALE();
  233.   y -= cx->prInfo->page_topy;
  234.   /*
  235.   ** Agh! Y inversion again !!
  236.   */
  237.   y = (cx->prInfo->page_height - y - 1) + cx->prSetup->bottom;
  238.  
  239.   XP_FilePrintf(cx->prSetup->out, "%g %g moveto\n",
  240.         PAGE_TO_POINT_F(x), PAGE_TO_POINT_F(y));
  241.   XL_RESTORE_NUMERIC_LOCALE();
  242. }
  243.  
  244. void xl_moveto_loc(MWContext* cx, int x, int y)
  245. {
  246.   /* This routine doesn't care about the clip region in the page */
  247.  
  248.   XL_SET_NUMERIC_LOCALE();
  249.  
  250.   /*
  251.   ** Agh! Y inversion again !!
  252.   */
  253.   y = (cx->prSetup->height - y - 1);
  254.  
  255.   XP_FilePrintf(cx->prSetup->out, "%g %g moveto\n",
  256.         PAGE_TO_POINT_F(x), PAGE_TO_POINT_F(y));
  257.   XL_RESTORE_NUMERIC_LOCALE();
  258. }
  259.  
  260. void xl_translate(MWContext* cx, int x, int y)
  261. {
  262.     XL_SET_NUMERIC_LOCALE();
  263.     y -= cx->prInfo->page_topy;
  264.     /*
  265.     ** Agh! Y inversion again !!
  266.     */
  267.     y = (cx->prInfo->page_height - y - 1) + cx->prSetup->bottom;
  268.  
  269.     XP_FilePrintf(cx->prSetup->out, "%g %g translate\n", PAGE_TO_POINT_F(x), PAGE_TO_POINT_F(y));
  270.     XL_RESTORE_NUMERIC_LOCALE();
  271. }
  272.  
  273. void xl_show(MWContext *cx, char* txt, int len, char *align)
  274. {
  275.     XP_File f;
  276.  
  277.     f = cx->prSetup->out;
  278.     XP_FilePrintf(f, "(");
  279.     while (len-- > 0) {
  280.     switch (*txt) {
  281.         case '(':
  282.         case ')':
  283.         case '\\':
  284.         XP_FilePrintf(f, "\\%c", *txt);
  285.         break;
  286.         default:
  287.         if (*txt < ' ' || (*txt & 0x80))
  288.           XP_FilePrintf(f, "\\%o", *txt & 0xff);
  289.         else
  290.           XP_FilePrintf(f, "%c", *txt);
  291.         break;
  292.     }
  293.     txt++;
  294.     }
  295.     XP_FilePrintf(f, ") %sshow\n", align);
  296. }
  297.  
  298. void xl_circle(MWContext* cx, int w, int h)
  299. {
  300.   XL_SET_NUMERIC_LOCALE();
  301.   XP_FilePrintf(cx->prSetup->out, "%g %g c ", PAGE_TO_POINT_F(w)/2.0, PAGE_TO_POINT_F(h)/2.0);
  302.   XL_RESTORE_NUMERIC_LOCALE();
  303. }
  304.  
  305. void xl_box(MWContext* cx, int w, int h)
  306. {
  307.   XL_SET_NUMERIC_LOCALE();
  308.   XP_FilePrintf(cx->prSetup->out, "%g 0 rlineto 0 %g rlineto %g 0 rlineto closepath ",
  309.       PAGE_TO_POINT_F(w), -PAGE_TO_POINT_F(h), -PAGE_TO_POINT_F(w));
  310.   XL_RESTORE_NUMERIC_LOCALE();
  311. }
  312.  
  313. MODULE_PRIVATE void
  314. xl_draw_border(MWContext *cx, int x, int y, int w, int h, int thick)
  315. {
  316.   XL_SET_NUMERIC_LOCALE();
  317.   XP_FilePrintf(cx->prSetup->out, "gsave %g setlinewidth\n ",
  318.           PAGE_TO_POINT_F(thick));
  319.   xl_moveto(cx, x, y);
  320.   xl_box(cx, w, h);
  321.   xl_stroke(cx);
  322.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  323.   XL_RESTORE_NUMERIC_LOCALE();
  324. }
  325.  
  326. MODULE_PRIVATE void
  327. xl_draw_3d_border(MWContext *cx, int x, int y, int w, int h, int thick, int tl, int br)
  328. {
  329.   int llx, lly;
  330.  
  331.   XL_SET_NUMERIC_LOCALE();
  332.   XP_FilePrintf(cx->prSetup->out, "gsave\n ");
  333.  
  334.   /* lower left */
  335.   llx = x;
  336.   lly = y + h;
  337.  
  338.   /* top left */
  339.   xl_moveto(cx, llx, lly);
  340.   XP_FilePrintf(cx->prSetup->out, 
  341.                 "%g %g rlineto 0 %g rlineto %g 0 rlineto %g %g rlineto %g 0 rlineto closepath\n",
  342.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  343.                 PAGE_TO_POINT_F(h-2*thick),
  344.                 PAGE_TO_POINT_F(w-2*thick),
  345.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  346.                 -PAGE_TO_POINT_F(w));
  347.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", tl);
  348.  
  349.   /* bottom right */
  350.   xl_moveto(cx, llx, lly);
  351.   XP_FilePrintf(cx->prSetup->out, 
  352.                 "%g %g rlineto %g 0 rlineto 0 %g rlineto %g %g rlineto 0 %g rlineto closepath\n",
  353.                 PAGE_TO_POINT_F(thick),    PAGE_TO_POINT_F(thick),
  354.                 PAGE_TO_POINT_F(w-2*thick),
  355.                 PAGE_TO_POINT_F(h-2*thick),
  356.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  357.                 -PAGE_TO_POINT_F(h));
  358.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", br);
  359.  
  360.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  361.   XL_RESTORE_NUMERIC_LOCALE();
  362. }
  363.  
  364. MODULE_PRIVATE void
  365. xl_draw_3d_radiobox(MWContext *cx, int x, int y, int w, int h, int thick,
  366.                     int top, int bottom, int center)
  367. {
  368.   int lx, ly;
  369.  
  370.   XL_SET_NUMERIC_LOCALE();
  371.   XP_FilePrintf(cx->prSetup->out, "gsave\n ");
  372.  
  373.   /* left */
  374.   lx = x;
  375.   ly = y + h/2;
  376.  
  377.   /* bottom */
  378.   xl_moveto(cx, lx, ly);
  379.   XP_FilePrintf(cx->prSetup->out, 
  380.                 "%g %g rlineto %g %g rlineto %g 0 rlineto %g %g rlineto %g %g rlineto closepath\n",
  381.                 PAGE_TO_POINT_F(w/2), -PAGE_TO_POINT_F(h/2),
  382.                 PAGE_TO_POINT_F(w/2), PAGE_TO_POINT_F(h/2),
  383.                 -PAGE_TO_POINT_F(thick),
  384.                 -PAGE_TO_POINT_F(w/2-thick),-PAGE_TO_POINT_F(h/2-thick),
  385.                 -PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h/2-thick));
  386.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", bottom);
  387.  
  388.   /* top  */
  389.   xl_moveto(cx, lx, ly);
  390.   XP_FilePrintf(cx->prSetup->out, 
  391.                 "%g %g rlineto %g %g rlineto %g 0 rlineto %g %g rlineto %g %g rlineto closepath\n",
  392.                 PAGE_TO_POINT_F(w/2), PAGE_TO_POINT_F(h/2),
  393.                 PAGE_TO_POINT_F(w/2), -PAGE_TO_POINT_F(h/2),
  394.                 -PAGE_TO_POINT_F(thick),
  395.                 -PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h/2-thick),
  396.                 -PAGE_TO_POINT_F(w/2-thick), -PAGE_TO_POINT_F(h/2-thick));
  397.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", top);
  398.  
  399.   /* center */
  400.   if (center != 10) {
  401.       xl_moveto(cx, lx+thick, ly);
  402.       XP_FilePrintf(cx->prSetup->out, 
  403.                     "%g %g rlineto %g %g rlineto %g %g rlineto closepath\n",
  404.                     PAGE_TO_POINT_F(w/2-thick), -PAGE_TO_POINT_F(h/2-thick),
  405.                     PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h/2-thick),
  406.                     -PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h/2-thick));
  407.       XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", center);
  408.   }
  409.  
  410.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  411.   XL_RESTORE_NUMERIC_LOCALE();
  412. }
  413.  
  414. MODULE_PRIVATE void
  415. xl_draw_3d_checkbox(MWContext *cx, int x, int y, int w, int h, int thick,
  416.                     int tl, int br, int center)
  417. {
  418.   int llx, lly;
  419.  
  420.   XL_SET_NUMERIC_LOCALE();
  421.   XP_FilePrintf(cx->prSetup->out, "gsave\n ");
  422.  
  423.   /* lower left */
  424.   llx = x;
  425.   lly = y + h;
  426.  
  427.   /* top left */
  428.   xl_moveto(cx, llx, lly);
  429.   XP_FilePrintf(cx->prSetup->out, 
  430.                 "%g %g rlineto 0 %g rlineto %g 0 rlineto %g %g rlineto %g 0 rlineto closepath\n",
  431.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  432.                 PAGE_TO_POINT_F(h-2*thick),
  433.                 PAGE_TO_POINT_F(w-2*thick),
  434.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  435.                 -PAGE_TO_POINT_F(w));
  436.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", tl);
  437.  
  438.   /* bottom right */
  439.   xl_moveto(cx, llx, lly);
  440.   XP_FilePrintf(cx->prSetup->out, 
  441.                 "%g %g rlineto %g 0 rlineto 0 %g rlineto %g %g rlineto 0 %g rlineto closepath\n",
  442.                 PAGE_TO_POINT_F(thick),    PAGE_TO_POINT_F(thick),
  443.                 PAGE_TO_POINT_F(w-2*thick),
  444.                 PAGE_TO_POINT_F(h-2*thick),
  445.                 PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  446.                 -PAGE_TO_POINT_F(h));
  447.   XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", br);
  448.  
  449.   /* center */
  450.   if (center != 10) {
  451.       xl_moveto(cx, llx+thick, lly-thick);
  452.       XP_FilePrintf(cx->prSetup->out, 
  453.                     "0 %g rlineto %g 0 rlineto 0 %g rlineto closepath\n",
  454.                     PAGE_TO_POINT_F(h-2*thick),
  455.                     PAGE_TO_POINT_F(w-2*thick),
  456.                     -PAGE_TO_POINT_F(h-2*thick));
  457.       XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", center);
  458.   }
  459.  
  460.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  461.   XL_RESTORE_NUMERIC_LOCALE();
  462. }
  463.  
  464. extern void xl_draw_3d_arrow(MWContext *cx, int x , int y, int thick, int w,
  465.                              int h, XP_Bool up, int left, int right, int base)
  466. {
  467.     int tx, ty;
  468.  
  469.     XL_SET_NUMERIC_LOCALE();
  470.     XP_FilePrintf(cx->prSetup->out, "gsave\n ");
  471.  
  472.     if (up) {
  473.         tx = x + w/2;
  474.         ty = y;
  475.  
  476.         /* left */
  477.  
  478.         xl_moveto(cx, tx, ty);
  479.         XP_FilePrintf(cx->prSetup->out, 
  480.                       "%g %g rlineto %g %g rlineto %g %g rlineto closepath\n",
  481.                       -PAGE_TO_POINT_F(w/2), -PAGE_TO_POINT_F(h),
  482.                       PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  483.                       PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h-2*thick));
  484.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", left);
  485.  
  486.         /* right */
  487.  
  488.         xl_moveto(cx, tx, ty);
  489.         XP_FilePrintf(cx->prSetup->out, 
  490.                       "%g %g rlineto %g %g rlineto %g %g rlineto closepath\n",
  491.                       PAGE_TO_POINT_F(w/2), -PAGE_TO_POINT_F(h),
  492.                       -PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  493.                       -PAGE_TO_POINT_F(w/2-thick), PAGE_TO_POINT_F(h-2*thick));
  494.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", right);
  495.  
  496.         /* base */
  497.  
  498.         xl_moveto(cx, tx-w/2, ty+h);
  499.         XP_FilePrintf(cx->prSetup->out, 
  500.                       "%g %g rlineto %g 0 rlineto %g %g rlineto closepath\n",
  501.                       PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick),
  502.                       PAGE_TO_POINT_F(w-2*thick),
  503.                       PAGE_TO_POINT_F(thick), -PAGE_TO_POINT_F(thick));
  504.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", base);
  505.     }
  506.     else {
  507.         tx = x + w/2;
  508.         ty = y + h;
  509.  
  510.         /* left */
  511.  
  512.         xl_moveto(cx, tx, ty);
  513.         XP_FilePrintf(cx->prSetup->out, 
  514.                       "%g %g rlineto %g %g rlineto %g %g rlineto closepath\n",
  515.                       -PAGE_TO_POINT_F(w/2), PAGE_TO_POINT_F(h),
  516.                       PAGE_TO_POINT_F(thick), -PAGE_TO_POINT_F(thick),
  517.                       PAGE_TO_POINT_F(w/2-thick), -PAGE_TO_POINT_F(h-2*thick));
  518.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", left);
  519.  
  520.         /* right */
  521.  
  522.         xl_moveto(cx, tx, ty);
  523.         XP_FilePrintf(cx->prSetup->out, 
  524.                       "%g %g rlineto %g %g rlineto %g %g rlineto closepath\n",
  525.                       PAGE_TO_POINT_F(w/2), PAGE_TO_POINT_F(h),
  526.                       -PAGE_TO_POINT_F(thick), -PAGE_TO_POINT_F(thick),
  527.                       -PAGE_TO_POINT_F(w/2-thick), -PAGE_TO_POINT_F(h-2*thick));
  528.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", right);
  529.  
  530.         /* base */
  531.  
  532.         xl_moveto(cx, x, y);
  533.         XP_FilePrintf(cx->prSetup->out, 
  534.                       "%g %g rlineto %g 0 rlineto %g %g rlineto closepath\n",
  535.                       PAGE_TO_POINT_F(thick), -PAGE_TO_POINT_F(thick),
  536.                       PAGE_TO_POINT_F(w-2*thick),
  537.                       PAGE_TO_POINT_F(thick), PAGE_TO_POINT_F(thick));
  538.         XP_FilePrintf(cx->prSetup->out, ".%d setgray fill\n", base);
  539.     }
  540.  
  541.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  542.   XL_RESTORE_NUMERIC_LOCALE();
  543. }
  544.  
  545. void xl_line(MWContext* cx, int x1, int y1, int x2, int y2, int thick)
  546. {
  547.   XL_SET_NUMERIC_LOCALE();
  548.   XP_FilePrintf(cx->prSetup->out, "gsave %g setlinewidth\n ",
  549.                 PAGE_TO_POINT_F(thick));
  550.  
  551.   y1 -= cx->prInfo->page_topy;
  552.   y1 = (cx->prInfo->page_height - y1 - 1) + cx->prSetup->bottom;
  553.   y2 -= cx->prInfo->page_topy;
  554.   y2 = (cx->prInfo->page_height - y2 - 1) + cx->prSetup->bottom;
  555.  
  556.   XP_FilePrintf(cx->prSetup->out, "%g %g moveto %g %g lineto\n",
  557.         PAGE_TO_POINT_F(x1), PAGE_TO_POINT_F(y1),
  558.         PAGE_TO_POINT_F(x2), PAGE_TO_POINT_F(y2));
  559.   xl_stroke(cx);
  560.  
  561.   XP_FilePrintf(cx->prSetup->out, "grestore\n");
  562.   XL_RESTORE_NUMERIC_LOCALE();
  563. }
  564.  
  565. void xl_stroke(MWContext *cx)
  566. {
  567.     XP_FilePrintf(cx->prSetup->out, " stroke \n");
  568. }
  569.  
  570. void xl_fill(MWContext *cx)
  571. {
  572.     XP_FilePrintf(cx->prSetup->out, " fill \n");
  573. }
  574.  
  575. /*
  576. ** This function works, but is starting to show it's age, as the list
  577. ** of known problems grows:
  578. **
  579. ** +  The images are completely uncompressed, which tends to generate
  580. **    huge output files.  The university prototype browser uses RLE
  581. **    compression on the images, which causes them to print slowly,
  582. **    but is a huge win on some class of images.
  583. ** +  12 bit files can be constructed which print on any printer, but
  584. **    not 24 bit files.
  585. ** +  The 12 bit code is careful not to create a string-per-row, unless
  586. **    it is going through the compatibility conversion routine.
  587. ** +  The 1-bit code is completely unused and untested.
  588. ** +  It should squish the image if squishing is currently in effect.
  589. */
  590.  
  591. void xl_colorimage(MWContext *cx, int x, int y, int w, int h, IL_Pixmap *image,
  592.                    IL_Pixmap *mask)
  593. {
  594.     uint8 pixmap_depth;
  595.     int row, col, pps;
  596.     int n;
  597.     int16 *p12;
  598.     int32 *p24;
  599.     unsigned char *p8;
  600.     int cbits;
  601.     int rowdata, rowextra, row_ends_within_byte;
  602.     XP_File f;
  603.     NI_PixmapHeader *img_header = &image->header;
  604.  
  605.     XL_SET_NUMERIC_LOCALE();
  606.     f = cx->prSetup->out;
  607.     pps = 1;
  608.     row_ends_within_byte = 0;
  609.     pixmap_depth = img_header->color_space->pixmap_depth;
  610.  
  611.     /* Imagelib row data is aligned to 32-bit boundaries */
  612.     if (pixmap_depth == 1) {
  613.         rowdata = (img_header->width + 7)/8;
  614.         rowextra = img_header->widthBytes - rowdata;
  615.         cbits = 1;
  616.         pps = 8;
  617.     }
  618.     else if (pixmap_depth == 16) {
  619.         if (cx->prSetup->color) {
  620.             rowdata = (img_header->width*12)/8;
  621.             row_ends_within_byte = (img_header->width*12)%8 ? 1 : 0;
  622.             cbits = 4;
  623.         } else {
  624.             cbits = 8;
  625.             rowdata = img_header->width;
  626.         }
  627.         rowextra = img_header->widthBytes - img_header->width * 2;
  628.     }
  629.     else { /* depth assumed to be 32 */
  630.         rowdata = 3 * img_header->width;
  631.         rowextra = 0;
  632.         cbits = 8;
  633.     }
  634.  
  635.     assert(pixmap_depth == 16 || pixmap_depth == 32 || pixmap_depth == 1);
  636.     XP_FilePrintf(f, "gsave\n");
  637.     XP_FilePrintf(f, "/rowdata %d string def\n",
  638.                   rowdata + row_ends_within_byte);
  639.     xl_translate(cx, x, y + h);
  640.     XP_FilePrintf(f, "%g %g scale\n", PAGE_TO_POINT_F(w), PAGE_TO_POINT_F(h));
  641.     XP_FilePrintf(f, "%d %d ", img_header->width, img_header->height);
  642.     XP_FilePrintf(f, "%d ", cbits);
  643.     XP_FilePrintf(f, "[%d 0 0 %d 0 %d]\n", img_header->width,
  644.                   -img_header->height, img_header->height);
  645.     if (cx->prSetup->color && pixmap_depth == 16)
  646.         XP_FilePrintf(f, " smartimage12rgb\n");
  647.     else if (pixmap_depth == 32) {
  648.         XP_FilePrintf(f, " { currentfile rowdata readhexstring pop }\n");
  649.         XP_FilePrintf(f, " false 3 colorimage\n");
  650.     } else {
  651.         XP_FilePrintf(f, " { currentfile rowdata readhexstring pop }\n");
  652.         XP_FilePrintf(f, " image\n");
  653.     }
  654.  
  655.     n = 0;
  656.     p8 = (unsigned char*) image->bits;
  657.     p12 = (int16*) image->bits;
  658.     p24 = (int32*) image->bits;
  659.     for (row = 0; row < img_header->height; row++) {
  660.         for (col = 0; col < img_header->width; col += pps) {
  661.             switch ( pixmap_depth ) {
  662.             case 16:
  663.                 if (cx->prSetup->color) {
  664.                     if (n > 76) {
  665.                         XP_FilePrintf(f, "\n");
  666.                         n = 0;
  667.                     }
  668.                     XP_FilePrintf(f, "%03x", 0xfff & *p12++);
  669.                     n += 3;
  670.                 } else {
  671.                     unsigned char value;
  672.                     value = (*p12 & 0x00f)/15.0 * GREEN_PART * 255.0
  673.                         + ((((*p12 & 0x0f0)>>4)/15.0) * BLUE_PART * 255.0)
  674.                         + ((((*p12 & 0xf00)>>8)/15.0) * RED_PART * 255.0);
  675.                     p12++;
  676.                     if (n > 76) {
  677.                         XP_FilePrintf(f, "\n");
  678.                         n = 0;
  679.                     }
  680.                     XP_FilePrintf(f, "%02X", value);
  681.                     n += 2;
  682.                 }
  683.                 break;
  684.             case 32:
  685.                 if (n > 71) {
  686.                     XP_FilePrintf(f, "\n");
  687.                     n = 0;
  688.                 }
  689.                 XP_FilePrintf(f, "%06x", (int) (0xffffff & *p24++));
  690.                 n += 6;
  691.                 break;
  692.             case 1:
  693.                 if (n > 78) {
  694.                     XP_FilePrintf(f, "\n");
  695.                     n = 0;
  696.                 }
  697.                 XP_FilePrintf(f, "%02x", 0xff ^ *p8++);
  698.                 n += 2;
  699.                 break;
  700.             }
  701.         }
  702.         if (row_ends_within_byte) {
  703.             XP_FilePrintf(f, "0");
  704.             n += 1;
  705.         }
  706.         p8 += rowextra;
  707.         p12 = (int16*)((char*)p12 + rowextra);
  708.     }
  709.     XP_FilePrintf(f, "\ngrestore\n");
  710.     XL_RESTORE_NUMERIC_LOCALE();
  711. }
  712.  
  713. MODULE_PRIVATE void
  714. xl_begin_squished_text(MWContext *cx, float scale)
  715. {
  716.     XL_SET_NUMERIC_LOCALE();
  717.     XP_FilePrintf(cx->prSetup->out, "gsave %g 1 scale\n", scale);
  718.     XL_RESTORE_NUMERIC_LOCALE();
  719. }
  720.  
  721. MODULE_PRIVATE void
  722. xl_end_squished_text(MWContext *cx)
  723. {
  724.     XP_FilePrintf(cx->prSetup->out, "grestore\n");
  725. }
  726.