54 #define stricmp strcasecmp
55 #define strnicmp strncasecmp
65 #define CANVAS_WIDTH ( 50.0 )
66 #define CANVAS_HEIGHT ( 37.5 )
67 #define DEVICE_PIXELS_PER_INCH ( 72 )
70 #define MM_PER_INCH ( 25.4 )
73 #define DEVICE_PIXELS_PER_MM ( DEVICE_PIXELS_PER_INCH / MM_PER_INCH )
76 #define MAX_STRING_LEN 1000
83 HPDF_PageSizes pageSize;
89 int nlookup, if_symbol_font;
93 HPDF_REAL textWidth, textHeight;
95 HPDF_REAL textRed, textGreen, textBlue;
99 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pdf =
"pdf:Portable Document Format PDF:1:pdf:58:pdf\n";
116 void plD_line_pdf(
PLStream *,
short,
short,
short,
short );
117 void plD_polyline_pdf(
PLStream *,
short *,
short *,
PLINT );
123 void error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data );
124 void PSDrawTextToCanvas( pdfdev* dev,
unsigned char* type1_string,
short drawText );
125 void PSSetFont( pdfdev* dev,
PLUNICODE fci );
126 void PSDrawText( pdfdev* dev,
PLUNICODE* ucs4,
int ucs4Len,
short drawText );
139 error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *
PL_UNUSED( user_data ) )
142 printf(
"ERROR: error_no=%04X, detail_no=%d\n", (
unsigned int) error_no, (
int) detail_no );
154 #ifndef ENABLE_DYNDRIVERS
155 pdt->
pl_MenuStr =
"Portable Document Format PDF";
173 static PLINT compress = 1;
175 static PLINT color = 1;
176 static char * pageSize = NULL;
179 {
"text",
DRV_INT, &
text,
"Use own text routines (text=0|1)" },
180 {
"color",
DRV_INT, &color,
"Use color (color=0|1)" },
181 {
"compress",
DRV_INT, &compress,
"Compress pdf output (compress=0|1)" },
182 {
"hrshsym",
DRV_INT, &
hrshsym,
"Use Hershey symbol set (hrshsym=0|1)" },
183 {
"pagesize",
DRV_STR, &pageSize,
"Set page size (pagesize=A4|letter|A3|A5)" },
198 dev = (pdfdev *) calloc( 1,
sizeof ( pdfdev ) );
200 plexit(
"Insufficient memory\n" );
201 pls->
dev = (
void *) dev;
233 plspage( DEVICE_PIXELS_PER_INCH, DEVICE_PIXELS_PER_INCH,
262 dev->pdf = HPDF_New( error_handler, NULL );
264 plexit(
"ERROR: cannot create pdf object.\n" );
267 HPDF_SetCompressionMode( dev->pdf, HPDF_COMP_ALL );
270 dev->pageSize = HPDF_PAGE_SIZE_EOF;
271 if ( pageSize == NULL )
272 dev->pageSize = HPDF_PAGE_SIZE_A4;
273 else if ( !stricmp( pageSize,
"letter" ) )
274 dev->pageSize = HPDF_PAGE_SIZE_LETTER;
275 else if ( !stricmp( pageSize,
"A3" ) )
276 dev->pageSize = HPDF_PAGE_SIZE_A3;
277 else if ( !stricmp( pageSize,
"A4" ) )
278 dev->pageSize = HPDF_PAGE_SIZE_A4;
279 else if ( !stricmp( pageSize,
"A5" ) )
280 dev->pageSize = HPDF_PAGE_SIZE_A5;
282 if ( dev->pageSize == HPDF_PAGE_SIZE_EOF )
283 plexit(
"ERROR: Unknown page size. Allowed strings are: letter, A3, A4, A5.\n" );
292 fprintf( stderr,
"ERROR in haru library\n" );
304 pdfdev * dev = (pdfdev *) pls->
dev;
305 HPDF_REAL width, height;
310 dev->page = HPDF_AddPage( dev->pdf );
312 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_PORTRAIT );
314 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_LANDSCAPE );
317 width = HPDF_Page_GetWidth( dev->page );
318 height = HPDF_Page_GetHeight( dev->page );
321 HPDF_Page_Concat( dev->page, (HPDF_REAL) ( dev->scalex ), 0, 0, (HPDF_REAL) ( dev->scaley ), 0, 0 );
325 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
cmap0[0].
r / 255.0 ),
326 (HPDF_REAL) ( pls->
cmap0[0].
g / 255.0 ), (HPDF_REAL) ( pls->
cmap0[0].
b / 255.0 ) );
327 width /= (HPDF_REAL) ( dev->scalex );
328 height /= (HPDF_REAL) ( dev->scaley );
329 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0 );
330 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) 0.0 );
331 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) height );
332 HPDF_Page_LineTo( dev->page, 0.0, (HPDF_REAL) height );
333 HPDF_Page_Fill( dev->page );
342 void plD_line_pdf(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
346 xa[0] = x1a; xa[1] = x2a;
347 ya[0] = y1a; ya[1] = y2a;
358 void plD_polyline_pdf(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
382 pdfdev* dev = (pdfdev *) pls->
dev;
385 HPDF_SaveToStream( dev->pdf );
388 HPDF_ResetStream( dev->pdf );
394 HPDF_UINT32 size = 4096;
396 HPDF_ReadFromStream( dev->pdf, buf, &size );
401 if ( fwrite( buf, size, 1, dev->pdfFile ) != 1 )
402 plexit(
"ERROR: Cannot write to file!" );
408 HPDF_Free( dev->pdf );
439 process_string( pls, (
EscText *) ptr );
452 pdfdev* dev = (pdfdev *) pls->
dev;
455 HPDF_Page_SetLineWidth( dev->page, (HPDF_REAL) ( pls->
width ) );
456 HPDF_Page_SetLineCap( dev->page, HPDF_ROUND_END );
457 HPDF_Page_SetLineJoin( dev->page, HPDF_ROUND_JOIN );
458 HPDF_Page_SetRGBStroke( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
460 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
463 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) xa[0], (HPDF_REAL) ya[0] );
464 for ( i = 1; i < npts; i++ )
465 HPDF_Page_LineTo( dev->page, (HPDF_REAL) xa[i], (HPDF_REAL) ya[i] );
470 HPDF_Page_EofillStroke( dev->page );
472 HPDF_Page_FillStroke( dev->page );
476 HPDF_Page_Stroke( dev->page );
491 static unsigned char plunicode2type1(
const PLUNICODE index,
495 int jlo = -1, jmid, jhi = nlookup;
497 while ( jhi - jlo > 1 )
503 jmid = ( jlo + jhi ) / 2;
504 if ( index > lookup[jmid].Unicode )
506 else if ( index < lookup[jmid].Unicode )
512 return ( lookup[jmid].Type1 );
529 void PSDrawTextToCanvas( pdfdev* dev,
unsigned char* type1_string,
short drawText )
536 HPDF_Page_BeginText( dev->page );
537 HPDF_Page_SetTextRenderingMode( dev->page, HPDF_FILL );
538 HPDF_Page_SetRGBFill( dev->page, dev->textRed, dev->textGreen, dev->textBlue );
539 HPDF_Page_MoveTextPos( dev->page, dev->textWidth, dev->yOffset );
540 HPDF_Page_ShowText( dev->page, (
char *) type1_string );
541 HPDF_Page_EndText( dev->page );
545 dev->textWidth += HPDF_Page_TextWidth( dev->page, (
char *) type1_string );
546 th = (HPDF_REAL) ( (HPDF_REAL) HPDF_Font_GetCapHeight( dev->m_font ) * dev->fontSize * dev->fontScale / 1000.0 );
547 dev->textHeight = dev->textHeight > ( th + dev->yOffset ) ? dev->textHeight : ( th + dev->yOffset );
559 void PSSetFont( pdfdev* dev,
PLUNICODE fci )
571 dev->if_symbol_font = 1;
579 dev->if_symbol_font = 0;
582 if ( !( dev->m_font = HPDF_GetFont( dev->pdf, font, NULL ) ) )
583 plexit(
"ERROR: Couldn't open font\n" );
585 HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
594 # define RISE_FACTOR 0.6
603 void PSDrawText( pdfdev* dev,
PLUNICODE* ucs4,
int ucs4Len,
short drawText )
610 PLFLT old_sscale, sscale, old_soffset, soffset, dup;
619 dev->fontScale = 1.0;
622 PSSetFont( dev, fci );
627 while ( i < ucs4Len )
633 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
634 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
637 if ( !dev->if_symbol_font )
641 type1_string[s] =
'\0';
642 PSDrawTextToCanvas( dev, type1_string, drawText );
648 else if ( !last_chance )
653 type1_string[s] =
'\0';
654 PSDrawTextToCanvas( dev, type1_string, drawText );
657 PSSetFont( dev, fci );
666 PSDrawTextToCanvas( dev, type1_string, drawText );
669 PSSetFont( dev, fci );
686 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
687 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
690 if ( !dev->if_symbol_font )
694 type1_string[s] =
'\0';
695 PSDrawTextToCanvas( dev, type1_string, drawText );
701 else if ( !last_chance )
706 type1_string[s] =
'\0';
707 PSDrawTextToCanvas( dev, type1_string, drawText );
710 PSSetFont( dev, fci );
719 PSDrawTextToCanvas( dev, type1_string, drawText );
722 PSSetFont( dev, fci );
741 PSDrawTextToCanvas( dev, type1_string, drawText );
745 &old_sscale, &sscale, &old_soffset, &soffset );
750 dup = 0.5 * ( 1.0 - sscale );
751 dev->fontScale = (HPDF_REAL) sscale;
752 PSSetFont( dev, fci );
753 dev->yOffset = (HPDF_REAL) ( dev->fontSize * ( soffset *
RISE_FACTOR + dup ) );
758 PSDrawTextToCanvas( dev, type1_string, drawText );
762 &old_sscale, &sscale, &old_soffset, &soffset );
767 dup = -0.5 * ( 1.0 - sscale );
768 dev->fontScale = (HPDF_REAL) sscale;
769 PSSetFont( dev, fci );
770 dev->yOffset = (HPDF_REAL) ( -dev->fontSize * ( soffset *
RISE_FACTOR + dup ) );
774 PSDrawTextToCanvas( dev, type1_string, drawText );
778 PSSetFont( dev, fci );
789 PSDrawTextToCanvas( dev, type1_string, drawText );
794 PSSetFont( dev, fci );
799 PSDrawTextToCanvas( dev, type1_string, drawText );
810 pdfdev * dev = (pdfdev *) pls->
dev;
811 PLFLT rotation, shear, stride;
812 HPDF_REAL cos_rot, sin_rot, cos_shear, sin_shear;
817 printf(
"Non unicode string passed to a pdf driver, ignoring\n" );
824 printf(
"Sorry, the pdf drivers only handles strings of length < %d\n",
MAX_STRING_LEN );
829 dev->fontSize = (HPDF_REAL) ( pls->
chrht * DEVICE_PIXELS_PER_INCH / 25.4 * 1.6 );
832 dev->textRed = (HPDF_REAL) ( pls->
curcolor.
r / 255.0 );
833 dev->textGreen = (HPDF_REAL) ( pls->
curcolor.
g / 255.0 );
834 dev->textBlue = (HPDF_REAL) ( pls->
curcolor.
b / 255.0 );
839 cos_rot = (HPDF_REAL) cos( rotation );
840 sin_rot = (HPDF_REAL) sin( rotation );
841 cos_shear = (HPDF_REAL) cos( shear );
842 sin_shear = (HPDF_REAL) sin( shear );
848 HPDF_Page_GSave( dev->page );
849 HPDF_Page_Concat( dev->page, cos_rot, sin_rot,
850 -cos_rot * sin_shear - sin_rot * cos_shear,
851 -sin_rot * sin_shear + cos_rot * cos_shear,
852 (HPDF_REAL) ( args->
x ), (HPDF_REAL) ( args->
y ) );
853 HPDF_Page_Concat( dev->page, (HPDF_REAL) 1.0, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0, (HPDF_REAL) 1.0,
854 (HPDF_REAL) ( -args->
just * dev->textWidth ), (HPDF_REAL) ( -0.5 * dev->textHeight ) );
856 HPDF_Page_GRestore( dev->page );