Uploaded image for project: 'FOP'
  1. FOP
  2. FOP-1070

ESC POS Renderer

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Resolution: Won't Fix
    • 2.5
    • None
    • renderer/awt
    • None
    • Operating System: other
      Platform: Other
    • 37116

    Description

      Hi all,
      i would like to submit this ugly but functional implementation of a renderer
      for ESCPOS printers. With correct scale factor it can render against any ESCPOS
      printer directly (output stream to the device):

      ...

      Driver driver = new Driver();
      OutputStream out= new FileOutputStream("/dev/usb/usbtm0"); // the
      printer device
      OutputStream debug= new FileOutputStream("/tmp/escpos.txt");
      driver.setRenderer(new EscPosRenderer(284,new PrintWriter(debug)));
      driver.setOutputStream(out);
      driver.render(...);
      out.close();

      ...

      Please let me know if you need more docs or info.

      Andrea.

      --------------Renderer Code---------------------
      package eforce.fop.renderer;
      /**

      • @Author Andrea A. A. Gariboldi
      • */
        import java.awt.image.Raster;

      import java.io.OutputStream;
      import java.io.IOException;
      import java.io.PrintWriter;

      import org.apache.fop.render.awt.AWTRenderer;

      /**

      • EscPosRenderer converts AWTRenderer output
      • to an escpos raster bit image command.
        */
        public class EscPosRenderer extends AWTRenderer
        {
        /**
      • Very usefull debug of 0 1 bit maps for
      • human beings. Expecially if you put in in
      • a file and look at without wrap.
        */
        private PrintWriter debug;

      public EscPosRenderer()

      { super(null); this.debug= null; }

      /**

      • You will need scale factor to meet your printer
      • resolution, example:
      • EPSON TM-L90 (scaleFactor 284):
      • max printable horizontal line = 71mm = 568 dots
      • so make a FO document to print a table with solid
      • borthers 71mm wide, and find that your scale factor
      • is 284. Is not so simple to explain why, you better test
      • it, playing with scaleFactor and trying to have your
      • table printed as 71mm wide, or better looking at
      • debug file, have your table printed as 568 dots wide.
      • */
        public EscPosRenderer(double scaleFactor)

        { super(null); this.setScaleFactor(scaleFactor); this.debug= null; }

      public EscPosRenderer(double scaleFactor, PrintWriter debug)

      { super(null); this.setScaleFactor(scaleFactor); this.debug= debug; }

      public void stopRenderer(OutputStream out)
      throws IOException
      {
      super.stopRenderer(out);

      Raster r= getLastRenderedPage().getData();
      double maxY= r.getBounds().getMaxY();
      double maxX= r.getBounds().getMaxX();
      int h= new Double(r.getBounds().getHeight()).intValue();
      int w= new Double(r.getBounds().getWidth()).intValue();

      /* convert to black & white image (very ugly) */
      char[][] imagePixels= new char[h][w];

      for (int y=(int)Math.round(r.getBounds().getMinY());y<maxY;y++)
      {
      for (int x=(int)Math.round(r.getBounds().getMinX());x<maxX;x++)

      { /* rgb values to 0 1 */ if (r.getSample(x,y,0)==255&&r.getSample(x,y,1)==255&&r.getSample (x,y,2)==255) imagePixels[y][x]= '0'; else imagePixels[y][x]= '1'; d(imagePixels[y][x]); }

      dln();
      }

      dln("----------------------");

      /* Escpos raster bit image is formed like this x=n*byte(8 bit) y=n*dots

      • so we need to convert w from dots to bytes, each byte represents 8
        horizontal
      • dots, next we fill the end of the line whit nulls (xcorrection).
      • The result is an array on bytes to send to the printer.
      • */
        int paperw= new Double(Math.ceil(new Double(w).doubleValue()/8.0)).intValue
        ();
        int xcorrection= (paperw*8)-w;
        byte[] image= new byte[paperw*h];
        int cnt= 0,idx=0;
        StringBuffer sb= new StringBuffer(8);

      // so ugly
      for (int y=0;y<h;y++)
      {
      for (int x=0;x<w;x++)
      {
      if (++cnt==8)

      { sb.append(imagePixels[y][x]); String strb= sb.toString(); d(strb); int intb= Integer.parseInt(strb,2); image[idx++]= (byte)chr(intb); //binary string to byte sb.delete(0,8); cnt=0; }

      else
      sb.append(imagePixels[y][x]);
      }
      d("|");
      for (int c=0;c<xcorrection;c++)
      if (++cnt==8)

      { sb.append('0'); String strb= sb.toString(); d(strb); int intb= Integer.parseInt(strb,2); image[idx++]= (byte)chr(intb); //binary string to byte sb.delete(0,8); cnt=0; }

      else
      sb.append('0'); //fill end of line with nulls

      dln();
      }

      printImage(0, paperw, h, image, out);

      if (debug!=null)

      { debug.flush(); }


      }

      /**

      • Adpter for escpos raster bit image printing
        */
        private static void printImage(int m, int w, int h, byte[] data, OutputStream
        out)
        throws IOException
        {
        int s=w*h,xH=1,xL=0,yH=1,yL=0,fix=255;

      if (data.length!=s) // if something strange stream!!
      throw new RuntimeException("wrong data count: data.length-
      > "data.length" w*h: "+s);

      if (w > fix)

      { xH= new Double(Math.floor((double)w/(double)fix)).intValue(); if (xH==0) xH=1; xL= w-(xH*fix); }

      else
      if (w < fix)

      { xH= 0; xL= w; }

      if (h > fix)

      { yH= new Double(Math.floor((double)h/(double)fix)).intValue(); if (yH==0) yH=1; yL= h-yH*fix; }

      else
      if (h < fix)

      { yH= 0; yL= new Double(Math.ceil(h)).intValue(); }

      int H= yL + yH * (fix+1),W= xL + xH * (fix+1),S= W*H;

      out.write(new byte[]

      {'\35','v','0',(byte)chr(m)}

      ); //cmd1
      out.flush();
      out.write(new byte[]

      {(byte)chr(xL),(byte)chr(xH),(byte)chr(yL),(byte)chr (yH)}

      ); //cmd2
      out.flush();
      out.write(data); //data
      out.flush();

      byte[] surplus= new byte[S-data.length]; // data from strange escpos
      conversion functions
      // actually useless
      for (int i=0;i<surplus.length;i++) surplus[i]= (byte)chr(0);

      out.write(surplus); // actually useless data, that printer want!
      out.flush();
      }

      /**

      • Stupid function to meet escpos samples,
      • and to try make code more readable
        */
        private static char chr(int i) { return (char)i; }

      private void d(char c)

      { if (debug!=null) debug.print(c); }

      private void d(String s)

      { if (debug!=null) debug.print(s); }

      private void dln()

      { if (debug!=null) debug.println(); }

      private void dln(String s)

      { if (debug!=null) debug.println(s); }

      }
      ----------------------------------------------------------------

      Attachments

        1. EscPosRenderer.java
          6 kB
          Andrea Amerigo Aristodemo Gariboldi
        2. EscPosRenderer.java
          10 kB
          Andrea Amerigo Aristodemo Gariboldi
        3. EscPosRenderer.java
          8 kB
          Andrea Amerigo Aristodemo Gariboldi

        Activity

          People

            fop-dev@xmlgraphics.apache.org fop-dev
            andrea.gariboldi@e-force.org Andrea Amerigo Aristodemo Gariboldi
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: