ApoPantou - Print on windows printer from everywhere

What is it
ApoPantou lets you, the developer, print to a Windows™ attached printer from everywhere:
  • Print to Windows printer from iPad or iPhone
  • Print to Windows printer from Android tablet
  • Print to Windows printer from Windows mobile/ Windows CE
  • Print to Windows printer from BlackBerry
  • Print to Windows printer from Symbian
  • Print to Windows printer from any Linux PC
  • Print to Windows printer from AS/400
  • Print to Windows printer from any mobile phone
  • Print to Windows printer from another Windows PC
  • Print to Windows printer from any other operating system
Capabilities
  • Use any Windows™ printer
  • Draw text of any language, any font
  • Draw lines and shapes
  • Draw images
How does it work
  • Printer is attached to a Windows workstation, whether serial, parallel, USB, network or...
  • Quick setup: Windows workstation must be running a WEB server with PHP 5 installed. Tested with PHP 5.2.14.
  • You need a network connection to the WEB server workstation, whether it is LAN, WiFi, internet over GPRS, or what else...
  • PHP language:
    You need only include a class definition file and call its methods.
    No special dll is needed. WEB server operating system must be Windows (whether Apache or IIS or...).
  • All other languages:
    You need prepare an XML file like that below and post it to WEB server, where above PHP class has been installed.
    <?xml version="1.0" encoding="utf-8" ?>
    <ApoPantou creator="www.incahellas.com">
       <Printer>Epson 480-J</Printer>
       <page>
          <DrawString x="1" y="1">Hello world</DrawString>
       </page>
    </ApoPantou>
    

All languages need save data in UTF-8. This is about the same as plain ascii, if you are writing in English only.

Requirements on printing workstation
  • Operating system Windows XP (Home/Pro) or newer.
  • Installed Windows printer.
  • Available fonts for the language of your choise. I.e. If you want print Greek, you need have some Greek fonts, like Arial Greek, etc.
  • Always use dot (.) as decimal separator when specifying floating point numbers in parameters.
License

Program is released under the MIT license, which means you can use it for free for either personal or commercial use. Copyright is held by INCA Hellas Ltd.

Download

Download ApoPantou here

Installation
  1. Have installed .NET framework 4.0 (or newer).
  2. Have a running web server with PHP 5 installed. Tested with PHP 5.2.14.
  3. Download and install INCA Hellas ApoPantou.
    This will install ApoPantou service controller in your services, supposed to run under Local System Account. You may have to adjust appropriate security settings for your printers, or change Logon info. for the service.
  4. Copy php files into an appropriate directory, under your WEB server DocumentRoot.
  5. If you are developing in PHP, include apopantou.inc.php in your php files and follow directions below.
  6. If you are developing in other languages, you need prepare an XML file, according to directions below, and post it to apopantou.proxy.php.
    XML data should be sent via field XMLDATA.
Registry keys
HKLM\Software\INCA Hellas\ApoPantou\CommonDir
Working directory
HKLM\Software\INCA Hellas\ApoPantou\Timer
Integer value in milliseconds, for timer, to check working dir. for incoming files.
Default value is 300 milliseconds.
HKLM\Software\INCA Hellas\ApoPantou\MaxPendingJobs
Integer. If set greater than 0 (should be at least 2), will clear spooler pending jobs list and reboot the PC.
Default value is 0 (no spool check - no reboot).
Syntax help
string cPRINTJOB::version()
Get php code version number.
No object instantiation is needed.
cPRINTJOB()

Object constructor.

XML:
  • Tag: ApoPantou
  • Position: root tag
  • Parameter creator: string, 'www.incahellas.com', required!
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
    echo "cPRINTJOB error: ".htmlentities($pj->err);
    return;
}
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   ...
   ...
   ...
</ApoPantou>
bool set_printer($printer_name, $ar1=false)
Parameters:
  • printer_name: string, name of printer in windows, i.e. "Epson 760" or "\\myserver\printer1"
  • ar1: array of named properties.
Supported named properties:
Name Value type Meaning
color bool Print in color if true.
unit_mm bool Measurement units are in millimeter if true, otherwise in inches. Default is inches.
landscape bool Print in landscape if true.
filename string Output filename, if specified. This allows you i.e. to create an XPS file using Microsoft XPS Document Writer.
Attention if you are thinking to create a PDF file using a free PDF printer driver: most of free PDF printer drivers, when used with the filename option, do actually create a Postscript file, not a PDF one.
filetype string If filename is defined but left empty, filetype is used to create a random filename in
%CommonDatapath%/INCA Hellas/ApoPantouOut
papersize string You must know which sizes your printer supports and set one of them, i.e. A4.
paperheight int Units of 1/100 of inch, for custom paper size.
paperwidth int Units of 1/100 of inch, for custom paper size.
margins comma separated list of 4 integers Left, Top & Right, Bottom points in 1/100 of inch
XML:
  • Tag: Printer
  • Position: inside root
  • Parameter color: int, 1/0 for yes/no
  • Parameter unit_mm: int, 1/0 for yes/no
  • Parameter landscape: int, 1/0 for yes/no
  • Parameter filename: string, output filename (if set) instead of printing
  • Parameter papersize: string
  • Parameter paperheight: int, units of 1/100 of inch
  • Parameter paperwidth: int, units of 1/100 of inch
  • Parameter margins: comma separated list of 4 integers: Left, Top & Right, Bottom points in 1/100 of inch
  • Text: printer name
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   ...
   ...
   ...
</ApoPantou>
$fontRC create_font($fontname, $sz, $attr=false)
Parameters:
  • fontname: font face name, i.e. Arial.
  • sz: font size in printer points (1/72 of inch), i.e. 10.
  • attr: optional string that contains a comma separated list of the following words: bold, italic, strikeout, underline.
Returns:

Font resource.

XML:
  • Tag: Font
  • Position: inside root or Page
  • Parameter id: int, numerical id (1,2,3,...)
  • Parameter size: int, printer points
  • Parameter style: comma separated list of 'bold', 'italic', 'strikeout', 'underline'
  • Text: face name
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );

$f_id=$pj->create_font('Arial', 10, 'bold');
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Font id="1" size="10" style="bold">Arial</Font>
   ...
   ...
   ...
</ApoPantou>
$penRC create_pen($color, $sz)
Parameters:
  • color: string as aarrggbb. aa=alpha value (FF=no transparency), rr, gg, bb are hex values for red, green, blue, i.e. FF0000FF for blue.
  • sz: float number, size (width) of pen, in measurement units.
Returns:

Pen resource.

XML:
  • Tag: Pen
  • Position: inside root or Page
  • Parameter id: int, numerical id (1,2,3,...)
  • Parameter size: float
  • Text: color as aarrggbb
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );

$p_id=$pj->create_pen('ff000000', 0.01); // create black pen of 0.01 inches width
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Pen id="1" size="0.01">ff000000</Pen>
   ...
   ...
   ...
</ApoPantou>
$brushRC create_brush($type='solid', $color)
$brushRC create_brush($type='texture', $image, $wrapmode=false)
$brushRC create_brush($type='gradient', $color1, $color2, $spec)
Parameters:
  • color, color1, color2: string as aarrggbb. aa=alpha value (FF=no transparency), rr, gg, bb are hex values for red, green, blue, i.e. FF0000FF for blue.
  • image: fullpath name of image file (relative to printing server).
    If you want to use network path, use UNC syntax, i.e. \\some_machine\c\mypath\image1.bmp
  • wrapmode: optional string, one of the following: Tile, TileFlipX, TileFlipY, TileFlipXY, Clamp. Check WrpaMode enumeration in .NET.
  • spec: array with following values: float x, float y, float width, float height (rectangle), string LinearGradientMode.
    LinearGradientMode is one of the following words: Horizontal, Vertical, ForwardDiagonal, BackwardDiagonal. Check .NET for these values.
Returns:

Brush resource.

XML:
  • Tag: Brush
  • Position: inside root or Page
  • Parameter id: int, numerical id (1,2,3,...)
  • Parameters color, color1, color2: strings as aarrggbb.
  • Parameter image: image file fullpath name.
  • Parameter wrapmode: 'Tile', 'TileFlipX', 'TileFlipY', 'TileFlipXY' or 'Clamp'.
  • Parameters x, y, width, height: floats for RectangleF definition.
  • Parameter mode: 'Horizontal', 'Vertical', 'ForwardDiagonal' or 'BackwardDiagonal'.
  • Text: 'solid', 'texture' or 'gradient'
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );

$b_id=$pj->create_brush('solid', 'ffff0000' ); // create solid red brush
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Brush id="1" color="ffff0000">solid</Brush>
   ...
   ...
   ...
</ApoPantou>
bool draw_string($str, $fontRC, $brushRC, $x, $y)
Parameters:
  • str: string to print; may contain one or more \r\n sequences to specify multiple lines of text at once.
  • fontRC: font resource or null.
  • brushRC: brush resource or null.
  • x: float, x position fot printing, in measurement units.
  • y: float, y position fot printing, in measurement units.
XML:
  • Tag: DrawString
  • Position: inside Page
  • Parameter font: int, Id
  • Parameter brush: int, Id
  • Parameter x: float
  • Parameter y: float
  • Text: string to be print
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );
$f_id=$pj->create_font('Arial', 12, 'bold' );
$b_id=$pj->create_brush('solid', 'ffff0000'); // red brush

$pj->draw_string('Hello world', null, null, 1, 1); // print in default (Arial,10)
$pj->draw_string('Hello world', $f_id, $b_id, 1, 1.5); // print with Arial,12,bold,red
$pj->draw_string('One line\r\nAnother line', null, null, 1, 2); // print 2 lines at once
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Font id="1" size="12" style="bold">Arial</Font>
   <Brush id="1" color="ffff0000">solid</Brush>
   <Page>
      <DrawString x="1" y="1">Hello world</DrawString>
      <DrawString font="1" brush="1" x="1" y="1.5">Hello world</DrawString>
      <DrawString x="1" y="2">One line
Another line</DrawString>
   </Page>
</ApoPantou>
bool draw_next($s1, $fontRC=false, $brushRC=false, $dx=0, $dy=0)
Parameters:
  • str: string to print; may contain one or more \r\n sequences to specify multiple lines of text at once.
  • fontRC: font resource or null.
  • brushRC: brush resource or null.
  • dx: delta x (move from previous one) position fot printing, in measurement units.
  • dy: delta y (move from previous one) position fot printing, in measurement units.
XML:
  • Tag: DrawNext
  • Position: inside Page
  • Parameter font: int, Id
  • Parameter brush: int, Id
  • Parameter x: float
  • Parameter y: float
  • Text: string to be print
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );
$b_id=$pj->create_brush('solid', 'ffff0000'); // red brush

$pj->draw_string('Hello ', null, null, 1, 1); // print in default (Arial,10)
$pj->draw_next('world', null, $b_id, 1, 1.5); // print next in red
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Brush id="1" color="ffff0000">solid</Brush>
   <Page>
      <DrawString x="1" y="1">Hello </DrawString>
      <DrawNext brush="1">world</DrawNext>
   </Page>
</ApoPantou>
bool draw_rectangle($penRC, $x, $y, $width, $height)
Parameters:
  • penRC: pen resource or null.v
  • x: float, left position of rectangle, in measurement units.
  • y: float, top position of rectangle, in measurement units.
  • width: float, width of rectangle, in measurement units.
  • height: float, height of rectangle, in measurement units.
XML:
  • Tag: DrawRectangle
  • Position: inside Page
  • Parameter pen: int, Id
  • Text: comma separated list of 4 floats: top left x,y position of rectangle, width, height
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );
$p_id=$pj->create_pen('ff000000', 0.01); // create black pen of 0.01 inches width

$pj->draw_rectangle($p_id, 1, 1, 5, 3); // draw rectangle 5 inches in width, 3 in height
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Pen id="1" size="0.01">ff000000</Pen>
   <Page>
      <DrawRectangle pen="1">1,1,5,3</DrawRectangle>
   </Page>
</ApoPantou>
bool draw_lines($penRC, $points)
Parameters:
  • penRC: pen resource or null.
  • points: array of floats, pairs of x,y for points to be connected. Must contain at least 4 floats.
XML:
  • Tag: DrawLines
  • Position: inside Page
  • Parameter pen: int, Id
  • Text: comma separated list of points: pairs of x,y floats.
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );
$p_id=$pj->create_pen('ff000000', 0.01); // create black pen of 0.01 inches width

$pj->draw_lines($p_id,  array(1,0.9, 7,0.9, 1,9, 7,9) ); // draw a Z
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Pen id="1" size="0.01">ff000000</Pen>
   <Page>
      <DrawLines pen="1">1,0.9, 7,0.9, 1,9, 7,9</DrawLines>
   </Page>
</ApoPantou>
bool draw_image($image, $up_left_x, $up_left_y, $up_right_x, $up_right_y, $lo_left_x, $lo_left_y)

Print an image file into parallelogram defined area.

Parameters:
  • image: fullpath name of image file (relative to printing server).
    File types supported: .BMP, .JPEG, .GIF, .PNG, .TIFF
    If you want to use network path, use UNC syntax, i.e. \\some_machine\c\mypath\image1.bmp
  • up_left_x: float, upper left corner (x) of printing area parallelogram, in measurement units.
  • up_left_y: float, upper left corner (y) of printing area parallelogram.
  • up_right_x: float, upper right corner (x) of printing area parallelogram.
  • up_right_y: float, upper right corner (y) of printing area parallelogram.
  • lo_left_x: float, lower left corner (x) of printing area parallelogram.
  • lo_left_y: float, lower left corner (y) of printing area parallelogram.
XML:
  • Tag: DrawImage
  • Position: inside Page
  • Parameter image: string, image fullpath filename.
  • Text: comma separated list of the 6 floats: up_left_x, up_left_y, up_right_x,....
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );

$img="C:\\Users\\Bill\\Pictures\\sony ericsson\\DSC00013.JPG";
// draw image 8-1=7 inches in width, 8.25-3=5.25 inches in height:
$pj->draw_image($img, 1, 3, 8, 3, 1, 8.25);
// draw the same image with 45 degrees rotation
$pj->draw_image($img, 1, 4.5, 4.5, 1, 3.62, 7.12);
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Page>
      <!-- draw image 8-1=7 inches in width, 8.25-3=5.25 inches in height -->
      <DrawImage image="C:\Users\Bill\Pictures\sony ericsson\DSC00013.JPG">1, 3, 8, 3, 1, 8.25</DrawImage>
      <!-- draw the same image with 45 degrees rotation -->
      <DrawImage image="C:\Users\Bill\Pictures\sony ericsson\DSC00013.JPG">1, 4.5, 4.5, 1, 3.62, 7.12</DrawImage>
   </Page>
</ApoPantou>
bool new_page()
Change page. XML:
  • Tag: Page
  • Position: inside root
  • Contents: drawing commands
| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
$pj->set_printer('Epson 760', array('color'=>true, 'landscape'=>false, 'papersize'=>'A4' ) );

$pj->draw_string('Hello', null, null, 1, 1); // print in 1st page

$pj->new_page();
$pj->draw_string('world', null, null, 1, 1); // print in 2nd page
<?xml version="1.0" encoding="utf-8" ?>
<ApoPantou creator="www.incahellas.com">
   <Printer color="1" landscape="0" papersize="A4" >Epson 760</Printer>
   <Page>
      <!-- print in 1st page -->
      <DrawString x="1" y="1">Hello</DrawString>
   </Page>
   <Page>
      <!-- print in 2nd page -->
      <DrawString x="1" y="1">world</DrawString>
   </Page>
</ApoPantou>
bool finalize()

Finalize printing. Optional: it will be called anyway upon object destruction.
However, by calling the function you have the option to get printing (job submission) result.

| |
$pj = new cPRINTJOB();
if ($pj->err!==false) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
   return;
}
...
...
...
if (!$pj->finalize()) {
   echo "cPRINTJOB error: ".htmlentities($pj->err);
}
No XML counterpart.
Comment:

Printing will take place after object destruction, i.e. script termination, or when you call optional function finalize(). Actually, the php script will just initiate the printing procedure and quit. It is the ApoPantou Windows service, that will do the printout.
This allows for the php script, or other language you choose, to disengage very quickly from the printout completion, even for very big printouts.