home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / awt / psgraphics.java < prev    next >
Text File  |  1995-08-11  |  17KB  |  571 lines

  1. /*-
  2.  * Copyright (c) 1994 by Sun Microsystems, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * @(#)PSGraphics.java    1.15 95/04/10 1/10/95
  6.  *
  7.  *      Jim Graham, 1/10/95
  8.  */
  9. package awt;
  10.  
  11. import java.io.*;
  12. import java.lang.*;
  13. import java.util.*;
  14.  
  15. /**
  16.  * PSGraphics is an object that encapsulates a graphics context for a
  17.  * particular PostScript file.
  18.  * 
  19.  * @version 1.15 10 Apr 1995
  20.  * @author Jim Graham
  21.  */
  22. public class PSGraphics extends Graphics {
  23.     public static Dimension Letter = new Dimension((72 * 17)/2, 11 * 72);
  24.     public static Dimension Legal = new Dimension((72 * 17)/2, 14 * 72);
  25.     public static Dimension Executive = new Dimension((72 * 15)/2, 10 * 72);
  26.     public static Dimension A4 = new Dimension((int) (72 * 210 / 25.4),
  27.                            (int) (72 * 297 / 25.4));
  28.  
  29.     PrintStream        ps;
  30.     public String    title;
  31.     public Dimension    paperDim;
  32.     public Dimension    layoutDim;
  33.     public Dimension    outputDim;
  34.     public int        marginTop = 72 / 2;
  35.     public int        marginBottom = 72 / 2;
  36.     public int        marginLeft = 72 / 2;
  37.     public int        marginRight = 72 / 2;
  38.     public int        pageNumber = 0;
  39.  
  40.     private PSGraphics    parent;
  41.  
  42.     private Color curColor;
  43.     private Font curFont;
  44.     private FontMetrics curMetrics;
  45.     private float scalefactor;
  46.     private int adjustX;
  47.     private int adjustY;
  48.     private boolean prologSent = false;
  49.  
  50.     static private String SetColorName = "SC";
  51.     static private String SetFontName = "SF";
  52.     static private String RectClipName = "RC";
  53.     static private String InitClipName = "IC";
  54.     static private String RectFillName = "RF";
  55.     static private String RectStrokeName = "RS";
  56.     static private String DrawStringName = "DS";
  57.     static private String DrawLineName = "DL";
  58.     static private String ScaleName = "S";
  59.     static private String StartPageName = "SP";
  60.     static private String EndPageName = "EP";
  61.     static private String GsaveName = "GS";
  62.     static private String GrestoreName = "GR";
  63.     static private String SetColormapName = "CM";
  64.     static private String DrawImageName = "DI";
  65.  
  66.     static private String hexString = "0123456789ABCDEF";
  67.     static private String testString =
  68.     "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890";
  69.  
  70.     /**
  71.      * Create a graphics context.
  72.      */
  73.     public PSGraphics(Window w, OutputStream os, String docTitle,
  74.               Dimension layout, Dimension paper) {
  75.     super(w);
  76.     ps = new PrintStream(os);
  77.     title = docTitle;
  78.     layoutDim = layout;
  79.     setPaper(paper);
  80.     }
  81.  
  82.     public PSGraphics(PSGraphics psg) {
  83.     super(psg.drawSurface);
  84.     parent = psg;
  85.     parent.gsave();
  86.     title = psg.title;
  87.     paperDim = psg.paperDim;
  88.     layoutDim = psg.layoutDim;
  89.     outputDim = psg.outputDim;
  90.     marginTop = psg.marginTop;
  91.     marginBottom = psg.marginBottom;
  92.     marginLeft = psg.marginLeft;
  93.     marginRight = psg.marginRight;
  94.     pageNumber = psg.pageNumber;
  95.     ps = psg.ps;
  96.     curColor = psg.curColor;
  97.     curFont = psg.curFont;
  98.     scalefactor = psg.scalefactor;
  99.     adjustX = psg.adjustX;
  100.     adjustY = psg.adjustY;
  101.     background = psg.background;
  102.     foreground = psg.foreground;
  103.     font = psg.font;
  104.     originX = psg.originX;
  105.     originY = psg.originY;
  106.     scaleX = psg.scaleX;
  107.     scaleY = psg.scaleY;
  108.     }
  109.  
  110.     public Graphics createChild(int oX, int oY, float sX, float sY) {
  111.     PSGraphics child = new PSGraphics(this);
  112.     child.setOrigin(oX, oY);
  113.     child.setScaling(sX, sY);
  114.  
  115.     return (Graphics) child;
  116.     }
  117.  
  118.     public void dispose() {
  119.     if (parent != null) {
  120.         parent.grestore();
  121.     }
  122.     }
  123.  
  124.     private void newAdjust() {
  125.     adjustX = ((int) ((float) marginLeft / scalefactor)
  126.            + originX);
  127.     adjustY = (outputDim.height
  128.            + (int) ((float) marginLeft / scalefactor)
  129.            - originY);
  130.     }
  131.  
  132.     private void newDims() {
  133.     int drawableWidth, drawableHeight;
  134.  
  135.     drawableWidth = paperDim.width - marginLeft - marginRight;
  136.     drawableHeight = paperDim.height - marginTop - marginBottom;
  137.  
  138.     if (drawableWidth >= layoutDim.width)
  139.         scalefactor = 1.0;
  140.     else
  141.         scalefactor = ((float) drawableWidth / (float) layoutDim.width);
  142.  
  143.     outputDim = new Dimension(layoutDim.width,
  144.                   (int) ((float) drawableHeight/scalefactor));
  145.     newAdjust();
  146.     }
  147.  
  148.     public void setPaper(Dimension paper) {
  149.     if (paper == null)
  150.         paper = Letter;
  151.     paperDim = paper;
  152.     newDims();
  153.     }
  154.  
  155.     private void outRect(int X, int Y, int W, int H) {
  156.     ps.print((adjustX + X)+" "+(adjustY - Y)+" "+W+" "+(-H)+" ");
  157.     }
  158.  
  159.     private void outPoint(int X, int Y) {
  160.     ps.print((adjustX + X)+" "+(adjustY - Y)+" ");
  161.     }
  162.  
  163.     private void outPoint(float X, float Y) {
  164.     ps.print(((float) adjustX + X)+" "+((float) adjustY - Y)+" ");
  165.     }
  166.  
  167.     private void outColor(Color color) {
  168.         if (curColor == null || !curColor.equal(color)) {
  169.         ps.println(color.r+" "+color.g+" "+color.b+" "+SetColorName);
  170.         curColor = color;
  171.     }
  172.     }
  173.  
  174.     private void outFont(Font font) {
  175.     // REMIND: all we check is the size and style for now...
  176.     if (font != curFont) {
  177.         curFont = font;
  178.         curMetrics = getFontMetrics(font);
  179.         int desiredWidth = curMetrics.stringWidth(testString);
  180.         int fontIndex = font.style & ~Font.UNDERLINE;
  181.         if (!font.family.substring(0,5).equalsIgnoreCase("times"))
  182.         fontIndex += 4;
  183.         ps.println("% Font["
  184.                +font.family+", "
  185.                +font.style+", "
  186.                +font.size
  187.                +"]");
  188.         ps.println(desiredWidth+" "+font.size+" "+fontIndex+" "
  189.                +SetFontName);
  190.     }
  191.     }
  192.  
  193.     private void outScale(float sx, float sy) {
  194.     ps.println(sx+" "+sy+" "+ScaleName);
  195.     }
  196.  
  197.     private void outStr(String str) {
  198.     StringBuffer outbuf = new StringBuffer();
  199.     outbuf.appendChar('(');
  200.     for (int i = 0; i < str.length(); i++) {
  201.         char ch = str.charAt(i);
  202.         if (ch == '(' || ch == ')' || ch == '\\')
  203.         outbuf.appendChar('\\');
  204.         outbuf.appendChar(ch);
  205.     }
  206.     outbuf.appendChar(')');
  207.     ps.print(outbuf.toString());
  208.     }
  209.  
  210.     public synchronized void gsave() {
  211.     ps.println(GsaveName);
  212.     }
  213.  
  214.     public synchronized void grestore() {
  215.     ps.println(GrestoreName);
  216.     }
  217.  
  218.     /**
  219.      * Sets the font for all subsequent text-drawing operations.
  220.      */
  221.     public void setFont(Font f) {
  222.     font = f;
  223.     }
  224.  
  225.     /**
  226.      * Sets the foreground color.
  227.      */
  228.     public void setForeground(Color c) {
  229.     foreground = c;
  230.     }
  231.  
  232.     /**
  233.      * Sets the background color.
  234.      */
  235.     public void setBackground(Color c) {
  236.     background = c;
  237.     }
  238.  
  239.     /** Sets the clipping rectangle for this Graphics context. */
  240.     public synchronized void clipRect(int X, int Y, int W, int H) {
  241.     outRect(X, Y, W, H);
  242.     ps.println(RectClipName);
  243.     }
  244.  
  245.     /** Clears the clipping region. */
  246.     public synchronized void clearClip() {
  247.     ps.println(InitClipName);
  248.     }
  249.     
  250.     /** Fills the rectangle indicated by x,y,w,h in the given Color. */
  251.     private synchronized void setRect(int X, int Y, int W, int H,
  252.                       Color color) {
  253.     outColor(color);
  254.     outRect(X, Y, W, H);
  255.     ps.println(RectFillName);
  256.     }
  257.     /** Clears the rectangle indicated by x,y,w,h. */
  258.     public void clearRect(int X, int Y, int W, int H) {
  259.     setRect(X, Y, W, H, background);
  260.     }
  261.     /** Fills the given rectangle with the foreground color. */
  262.     public void fillRect(int X, int Y, int W, int H) {
  263.     setRect(X, Y, W, H, foreground);
  264.     }
  265.     /** Draws the given rectangle. */
  266.     public synchronized void drawRect(int X, int Y, int W, int H) {
  267.     outColor(foreground);
  268.     outRect(X, Y, W, H);
  269.     ps.println(RectStrokeName);
  270.     }
  271.     /** Draws the given string. */
  272.     public synchronized void drawString(String str, int x, int y) {
  273.     outFont(font);
  274.     outColor(foreground);
  275.     outStr(str);
  276.     ps.print(" "+curMetrics.stringWidth(str)+" ");
  277.     outPoint(x, y);
  278.     ps.println(DrawStringName);
  279.     }
  280.     /** Draws the given character array. */
  281.     public void drawChars(char chars[], int offset, int length, int x, int y) {
  282.     // REMIND: Check the current font.
  283.     drawString(new String(chars, offset, length), x, y);
  284.     }
  285.     /** Draws the given byte array. */
  286.     public void drawBytes(byte bytes[], int offset, int length, int x, int y) {
  287.     // REMIND: Check the current font.
  288.     drawString(new String(bytes, 0, offset, length), x, y);
  289.     }
  290.     /** Draws the given string and returns the length of the drawn
  291.       string in pixels.  If font isn't set then returns -1. */
  292.     public int drawStringWidth(String str, int x, int y) {
  293.         drawString(str, x, y);
  294.     return curMetrics.stringWidth(str);
  295.     }
  296.     /** Draws the given character array and return the width in
  297.       pixels. If font isn't set then returns -1. */
  298.     public int drawCharsWidth(char chars[], int offset, int length,
  299.                   int x, int y) {
  300.         drawChars(chars, offset, length, x, y);
  301.     return curMetrics.charsWidth(chars, offset, length);
  302.     }
  303.     /** Draws the given byte array and return the width in
  304.       pixels. If font isn't set then returns -1. */
  305.     public int drawBytesWidth(byte bytes[], int offset, int length,
  306.                   int x, int y) {
  307.         drawBytes(bytes, offset, length, x, y);
  308.     return curMetrics.bytesWidth(bytes, offset, length);
  309.     }
  310.     /** Draws the given line. */
  311.     public synchronized void drawLine(int x1, int y1, int x2, int y2) {
  312.     outColor(foreground);
  313.     outPoint(x1, y1);
  314.     outPoint(x2, y2);
  315.     ps.println(DrawLineName);
  316.     }
  317.  
  318.     private int RGBtoGray(int r, int g, int b) {
  319.     // Taken from the RGB to YIQ mapping (Foley & Van Dam, 2nd Ed.)
  320.     float y = .299 * r + .587 * g + .114 * b;
  321.     return (int) y;
  322.     }
  323.  
  324.     /** Draws an image at x,y. */
  325.     public synchronized void drawImage(Image I, int X, int Y) {
  326.     DIBitmap dib = I.getDIBitmap();
  327.     ps.println("%"+dib);
  328.  
  329.     ps.println(dib.num_colors + " " + SetColormapName);
  330.     char outbuf[] = new char[72];
  331.     int linepos = 0;
  332.     for (int i = 0; i < dib.num_colors; i++) {
  333.         outbuf[linepos++] = hexString.charAt((dib.red[i] >>> 4) & 0xf);
  334.         outbuf[linepos++] = hexString.charAt((dib.red[i]) & 0xf);
  335.         outbuf[linepos++] = hexString.charAt((dib.green[i] >>> 4) & 0xf);
  336.         outbuf[linepos++] = hexString.charAt((dib.green[i]) & 0xf);
  337.         outbuf[linepos++] = hexString.charAt((dib.blue[i] >>> 4) & 0xf);
  338.         outbuf[linepos++] = hexString.charAt((dib.blue[i]) & 0xf);
  339.         if (linepos >= 72) {
  340.         ps.println(outbuf);
  341.         linepos = 0;
  342.         }
  343.     }
  344.     if (linepos > 0)
  345.         ps.println(new String(outbuf, 0, linepos));
  346.     if (dib.trans_index < dib.num_colors) {
  347.         int startx = -1;
  348.         int trans_index = dib.trans_index;
  349.         int index = 0;
  350.  
  351.         for (int j = 0; j < dib.height; j++) {
  352.         for (int i = 0; i < dib.width; i++) {
  353.             if (dib.raster[index++] == trans_index) {
  354.             if (startx >= 0) {
  355.                 drawSubImage(dib,
  356.                      X + startx, Y + j,
  357.                      startx, j, i, j + 1);
  358.                 startx = -1;
  359.             }
  360.             } else {
  361.             if (startx < 0)
  362.                 startx = i;
  363.             }
  364.         }
  365.         if (startx >= 0) {
  366.             drawSubImage(dib,
  367.                  X + startx, Y + j,
  368.                  startx, j, dib.width, j + 1);
  369.             startx = -1;
  370.         }
  371.         }
  372.     } else
  373.         drawSubImage(dib, X, Y, 0, 0, dib.width, dib.height);
  374.     }
  375.  
  376.     private void drawSubImage(DIBitmap dib,
  377.                   int X, int Y, int x1, int y1, int x2, int y2) {
  378.     int w = x2 - x1;
  379.     int h = y2 - y1;
  380.     int index = y1 * dib.width + x1;
  381.     int linepos = 0;
  382.     char outbuf[] = new char[72];
  383.  
  384.     outRect(X, Y, w, -h);
  385.     ps.println(DrawImageName);
  386.     for (int j = y1; j < y2; j++) {
  387.         for (int i = x1; i < x2; i++) {
  388.         int pixel = dib.raster[index++] & 0xff;
  389.         outbuf[linepos++] = hexString.charAt((pixel >>> 4) & 0xf);
  390.         outbuf[linepos++] = hexString.charAt(pixel & 0xf);
  391.         if (linepos >= 72) {
  392.             ps.println(outbuf);
  393.             linepos = 0;
  394.         }
  395.         }
  396.         index += dib.width - w;
  397.     }
  398.     if (linepos > 0)
  399.         ps.println(new String(outbuf, 0, linepos));
  400.     }
  401.  
  402.     /**
  403.      * Copies an area of the window that this graphics context paints to.
  404.      * Note that this cannot be done in PostScript so we should throw an error.
  405.      * @param X the x-coordinate of the source.
  406.      * @param Y the y-coordinate of the source.
  407.      * @param W the width.
  408.      * @param H the height.
  409.      * @param dx the x-coordinate of the destination.
  410.      * @param dy the y-coordinate of the destination.
  411.      */
  412.     public void copyArea(int X, int Y, int W, int H, int dx, int dy) {
  413.     // REMIND: Not allowed
  414.     new Exception().printStackTrace();
  415.     }
  416.  
  417.     /**
  418.      * Sets the origin of this Graphics context. All subsequent
  419.      * operations are relative to this origin.
  420.      */
  421.     public void setOrigin(int x, int y) {
  422.     originX = x;
  423.     originY = y;
  424.     newAdjust();
  425.     }
  426.  
  427.     /**
  428.      * Sets the scaling factor for this Graphics context. Currently
  429.      * only used for line and rectangle drawing operations.
  430.      */
  431.     public synchronized void setScaling(float sx, float sy) {
  432.     if (sx == scaleX && sy == scaleY)
  433.         return;
  434.     outScale(sx / scaleX, sy / scaleY);
  435.     scaleX = sx;
  436.     scaleY = sy;
  437.     }
  438.  
  439.     public synchronized void startPage() {
  440.     curFont = null;
  441.     curColor = null;
  442.     if (!prologSent)
  443.         outProlog();
  444.     pageNumber += 1;
  445.     ps.println("\n%%Page:  "+pageNumber+" "+pageNumber);
  446.     ps.println(StartPageName);
  447.     }
  448.  
  449.     public synchronized void endPage() {
  450.     ps.println(EndPageName);
  451.     }
  452.  
  453.     private void outProlog() {
  454.     // Note: NewsPrinters don't reorder the pages if we use PS-Adobe-3.0!
  455.     ps.println("%!PS-Adobe-2.0");
  456.     ps.println("%%Title: " + title);
  457.     ps.println("%%Pages: (atend)");
  458.     ps.println("%%EndComments");
  459.     ps.println("%%BeginProlog");
  460.     ps.println("/D {def} def");
  461.     ps.println("/ISOF {");
  462.     ps.println("    dup findfont dup length 1 add dict begin {");
  463.     ps.println("        1 index /FID eq {pop pop} {D} ifelse");
  464.     ps.println("    } forall /Encoding ISOLatin1Encoding D");
  465.     ps.println("    currentdict end definefont");
  466.     ps.println("} D");
  467.     ps.println("/F [");
  468.     ps.println("    /Times-Roman ISOF");
  469.     ps.println("    /Times-Bold ISOF");
  470.     ps.println("    /Times-Italic ISOF");
  471.     ps.println("    /Times-BoldItalic ISOF");
  472.     ps.println("    /Courier ISOF");
  473.     ps.println("    /Courier-Bold ISOF");
  474.     ps.println("    /Courier-Oblique ISOF");
  475.     ps.println("    /Courier-BoldOblique ISOF");
  476.     ps.println("] D");
  477.     ps.println("/R {4 2 roll moveto 1 index 0 rlineto");
  478.     ps.println("    0 exch rlineto neg 0 rlineto closepath} D");
  479.     ps.println("/"+SetColorName
  480.            +" {3 {255 div 3 1 roll} repeat setrgbcolor} D");
  481.     ps.println("/"+SetFontName +" {");
  482.     ps.println("    F exch get exch scalefont setfont");
  483.     ps.println("    ("+testString+") stringwidth pop div");
  484.     ps.println("    currentfont exch scalefont setfont} D");
  485.     ps.println("/"+RectClipName+" {R clip newpath} D");
  486.     ps.println("/"+InitClipName+" {initclip} D");
  487.     ps.println("/"+RectFillName+" {R fill} D");
  488.     ps.println("/"+RectStrokeName+" {R stroke} D");
  489.     ps.println("/NZ {dup 1 lt {pop 1} if} D");
  490.     ps.println("/"+DrawStringName +" {");
  491.     ps.println("    moveto 1 index stringwidth pop NZ sub");
  492.     ps.println("    1 index length 1 sub NZ div 0");
  493.     ps.println("    3 2 roll ashow} D");
  494.     ps.println("/"+DrawLineName+" {moveto lineto stroke} D");
  495.     ps.println("/"+ScaleName+" {scale} D");
  496.     ps.println("/"+StartPageName+" {/P save D} D");
  497.     ps.println("/"+EndPageName+" {showpage P restore} D");
  498.     ps.println("/"+GsaveName+" {gsave} D");
  499.     ps.println("/"+GrestoreName+" {grestore} D");
  500.     ps.println("/"+SetColormapName+" {");
  501.     ps.println("    /cmapr 1 index array D");
  502.     ps.println("    /cmapg 1 index array D");
  503.     ps.println("    /cmapb 1 index array D");
  504.     ps.println("    /cmapgray null D");
  505.     ps.println("    3 string exch 0 exch 1 exch 1 sub {");
  506.     ps.println("        currentfile 2 index readhexstring pop");
  507.     ps.println("        cmapr 2 index 2 index 0 get put");
  508.     ps.println("        cmapg 2 index 2 index 1 get put");
  509.     ps.println("        cmapb 2 index 2 index 2 get put");
  510.     ps.println("    pop pop } for pop");
  511.     ps.println("} D");
  512.     ps.println("/"+DrawImageName+" {");
  513.     ps.println("    GS");
  514.     ps.println("    /imgsave save D");    // NeWSprint leaves files open!
  515.     ps.println("    /imgh exch D");
  516.     ps.println("    /imgw exch D");
  517.     ps.println("    translate imgw imgh scale");
  518.     ps.println("    /imgstr imgw string D");
  519.     ps.println("    /colorimage where {");
  520.     ps.println("        pop");
  521.     ps.println("        /cimgstr imgw 3 mul string D");
  522.     ps.println("        imgw imgh 8 [imgw 0 0 imgh neg 0 0] {");
  523.     ps.println("            currentfile imgstr readhexstring pop");
  524.     ps.println("            0 1 imgw 1 sub {");
  525.     ps.println("                2 copy get");
  526.     ps.println("                cmapr 1 index get");
  527.     ps.println("                cimgstr exch 3 index");
  528.     ps.println("                3 mul exch put");
  529.     ps.println("                cmapg 1 index get");
  530.     ps.println("                cimgstr exch 3 index");
  531.     ps.println("                3 mul 1 add exch put");
  532.     ps.println("                cmapb 1 index get");
  533.     ps.println("                cimgstr exch 3 index");
  534.     ps.println("                3 mul 2 add exch put");
  535.     ps.println("            pop pop } for pop cimgstr");
  536.     ps.println("        } false 3 colorimage");
  537.     ps.println("    } {");
  538.     ps.println("        cmapgray null eq {");
  539.     ps.println("            /cmapgray cmapr length array D");
  540.     ps.println("            0 1 cmapr length 1 sub {");
  541.     ps.println("                cmapgray exch");
  542.     ps.println("                cmapr 1 index get .299 mul");
  543.     ps.println("                cmapg 2 index get .587 mul");
  544.     ps.println("                cmapb 3 index get .114 mul");
  545.     ps.println("                add add cvi put");
  546.     ps.println("            } for");
  547.     ps.println("        } if");
  548.     ps.println("        imgw imgh 8 [imgw 0 0 imgh neg 0 0] {");
  549.     ps.println("            currentfile imgstr readhexstring pop");
  550.     ps.println("            0 1 imgw 1 sub {");
  551.     ps.println("                imgstr exch 2 copy get");
  552.     ps.println("                cmapgray exch get put");
  553.     ps.println("            } for");
  554.     ps.println("        } image");
  555.     ps.println("    } ifelse");
  556.     ps.println("    imgsave restore");
  557.     ps.println("    GR");
  558.     ps.println("} D");
  559.     ps.println(scalefactor+" dup scale");
  560.     ps.println("%%EndProlog");
  561.     prologSent = true;
  562.     }
  563.  
  564.     public synchronized void close() {
  565.     ps.println("%%Trailer");
  566.     ps.println("%%Pages: "+pageNumber);
  567.     ps.println("%%EOF");
  568.     ps.close();
  569.     }
  570. }
  571.