52 #define stricmp strcasecmp
53 #define strnicmp strncasecmp
63 #define CANVAS_WIDTH ( 50.0 )
64 #define CANVAS_HEIGHT ( 37.5 )
65 #define DEVICE_PIXELS_PER_INCH ( 72 )
68 #define MM_PER_INCH ( 25.4 )
71 #define DEVICE_PIXELS_PER_MM ( DEVICE_PIXELS_PER_INCH / MM_PER_INCH )
74 #define MAX_STRING_LEN 1000
81 HPDF_PageSizes pageSize;
87 int nlookup, if_symbol_font;
91 HPDF_REAL textWidth, textHeight;
93 HPDF_REAL textRed, textGreen, textBlue;
97 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pdf =
"pdf:Portable Document Format PDF:1:pdf:58:pdf\n";
114 void plD_line_pdf(
PLStream *,
short,
short,
short,
short );
115 void plD_polyline_pdf(
PLStream *,
short *,
short *,
PLINT );
121 void error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data );
122 void PSDrawTextToCanvas( pdfdev* dev,
unsigned char* type1_string,
short drawText );
123 void PSSetFont( pdfdev* dev,
PLUNICODE fci );
124 void PSDrawText( pdfdev* dev,
PLUNICODE* ucs4,
int ucs4Len,
short drawText );
137 error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *
PL_UNUSED( user_data ) )
140 printf(
"ERROR: error_no=%04X, detail_no=%d\n", (
unsigned int) error_no, (
int) detail_no );
152 #ifndef ENABLE_DYNDRIVERS
153 pdt->
pl_MenuStr =
"Portable Document Format PDF";
170 static PLINT text = 1;
171 static PLINT compress = 1;
172 static PLINT hrshsym = 1;
173 static PLINT color = 1;
174 static char * pageSize = NULL;
177 {
"text",
DRV_INT, &text,
"Use own text routines (text=0|1)" },
178 {
"color",
DRV_INT, &color,
"Use color (color=0|1)" },
179 {
"compress",
DRV_INT, &compress,
"Compress pdf output (compress=0|1)" },
180 {
"hrshsym",
DRV_INT, &hrshsym,
"Use Hershey symbol set (hrshsym=0|1)" },
181 {
"pagesize",
DRV_STR, &pageSize,
"Set page size (pagesize=A4|letter|A3|A5)" },
196 dev = (pdfdev *) calloc( 1,
sizeof ( pdfdev ) );
198 plexit(
"Insufficient memory\n" );
199 pls->
dev = (
void *) dev;
231 plspage( DEVICE_PIXELS_PER_INCH, DEVICE_PIXELS_PER_INCH,
232 (
PLINT) ( CANVAS_WIDTH * DEVICE_PIXELS_PER_INCH ), (
PLINT) ( CANVAS_HEIGHT * DEVICE_PIXELS_PER_INCH ), 0, 0 );
236 0, (
PLINT) ( CANVAS_HEIGHT * DEVICE_PIXELS_PER_INCH ) );
260 dev->pdf = HPDF_New( error_handler, NULL );
262 plexit(
"ERROR: cannot create pdf object.\n" );
265 HPDF_SetCompressionMode( dev->pdf, HPDF_COMP_ALL );
268 dev->pageSize = HPDF_PAGE_SIZE_EOF;
269 if ( pageSize == NULL )
270 dev->pageSize = HPDF_PAGE_SIZE_A4;
271 else if ( !stricmp( pageSize,
"letter" ) )
272 dev->pageSize = HPDF_PAGE_SIZE_LETTER;
273 else if ( !stricmp( pageSize,
"A3" ) )
274 dev->pageSize = HPDF_PAGE_SIZE_A3;
275 else if ( !stricmp( pageSize,
"A4" ) )
276 dev->pageSize = HPDF_PAGE_SIZE_A4;
277 else if ( !stricmp( pageSize,
"A5" ) )
278 dev->pageSize = HPDF_PAGE_SIZE_A5;
280 if ( dev->pageSize == HPDF_PAGE_SIZE_EOF )
281 plexit(
"ERROR: Unknown page size. Allowed strings are: letter, A3, A4, A5.\n" );
290 fprintf( stderr,
"ERROR in haru library\n" );
302 pdfdev * dev = (pdfdev *) pls->
dev;
303 HPDF_REAL width, height;
308 dev->page = HPDF_AddPage( dev->pdf );
310 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_PORTRAIT );
312 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_LANDSCAPE );
315 width = HPDF_Page_GetWidth( dev->page );
316 height = HPDF_Page_GetHeight( dev->page );
317 dev->scalex = (
PLFLT) ( width / ( CANVAS_WIDTH * DEVICE_PIXELS_PER_INCH ) );
318 dev->scaley = (
PLFLT) ( height / ( CANVAS_HEIGHT * DEVICE_PIXELS_PER_INCH ) );
319 HPDF_Page_Concat( dev->page, (HPDF_REAL) ( dev->scalex ), 0, 0, (HPDF_REAL) ( dev->scaley ), 0, 0 );
323 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
cmap0[0].
r / 255.0 ),
324 (HPDF_REAL) ( pls->
cmap0[0].
g / 255.0 ), (HPDF_REAL) ( pls->
cmap0[0].
b / 255.0 ) );
325 width /= (HPDF_REAL) ( dev->scalex );
326 height /= (HPDF_REAL) ( dev->scaley );
327 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0 );
328 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) 0.0 );
329 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) height );
330 HPDF_Page_LineTo( dev->page, 0.0, (HPDF_REAL) height );
331 HPDF_Page_Fill( dev->page );
340 void plD_line_pdf(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
344 xa[0] = x1a; xa[1] = x2a;
345 ya[0] = y1a; ya[1] = y2a;
356 void plD_polyline_pdf(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
380 pdfdev* dev = (pdfdev *) pls->
dev;
383 HPDF_SaveToStream( dev->pdf );
386 HPDF_ResetStream( dev->pdf );
392 HPDF_UINT32 size = 4096;
394 HPDF_ReadFromStream( dev->pdf, buf, &size );
399 if ( fwrite( buf, size, 1, dev->pdfFile ) != 1 )
400 plexit(
"ERROR: Cannot write to file!" );
406 HPDF_Free( dev->pdf );
437 process_string( pls, (
EscText *) ptr );
450 pdfdev* dev = (pdfdev *) pls->
dev;
453 HPDF_Page_SetLineWidth( dev->page, (HPDF_REAL) ( pls->
width ) );
454 HPDF_Page_SetLineCap( dev->page, HPDF_ROUND_END );
455 HPDF_Page_SetLineJoin( dev->page, HPDF_ROUND_JOIN );
456 HPDF_Page_SetRGBStroke( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
458 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
461 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) xa[0], (HPDF_REAL) ya[0] );
462 for ( i = 1; i < npts; i++ )
463 HPDF_Page_LineTo( dev->page, (HPDF_REAL) xa[i], (HPDF_REAL) ya[i] );
468 HPDF_Page_EofillStroke( dev->page );
470 HPDF_Page_FillStroke( dev->page );
474 HPDF_Page_Stroke( dev->page );
489 static unsigned char plunicode2type1(
const PLUNICODE index,
493 int jlo = -1, jmid, jhi = nlookup;
495 while ( jhi - jlo > 1 )
501 jmid = ( jlo + jhi ) / 2;
502 if ( index > lookup[jmid].Unicode )
504 else if ( index < lookup[jmid].Unicode )
510 return ( lookup[jmid].Type1 );
527 void PSDrawTextToCanvas( pdfdev* dev,
unsigned char* type1_string,
short drawText )
534 HPDF_Page_BeginText( dev->page );
535 HPDF_Page_SetTextRenderingMode( dev->page, HPDF_FILL );
536 HPDF_Page_SetRGBFill( dev->page, dev->textRed, dev->textGreen, dev->textBlue );
537 HPDF_Page_MoveTextPos( dev->page, dev->textWidth, dev->yOffset );
538 HPDF_Page_ShowText( dev->page, (
char *) type1_string );
539 HPDF_Page_EndText( dev->page );
543 dev->textWidth += HPDF_Page_TextWidth( dev->page, (
char *) type1_string );
544 th = (HPDF_REAL) ( (HPDF_REAL) HPDF_Font_GetCapHeight( dev->m_font ) * dev->fontSize * dev->fontScale / 1000.0 );
545 dev->textHeight = dev->textHeight > ( th + dev->yOffset ) ? dev->textHeight : ( th + dev->yOffset );
557 void PSSetFont( pdfdev* dev,
PLUNICODE fci )
569 dev->if_symbol_font = 1;
577 dev->if_symbol_font = 0;
580 if ( !( dev->m_font = HPDF_GetFont( dev->pdf, font, NULL ) ) )
581 plexit(
"ERROR: Couldn't open font\n" );
583 HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
592 # define RISE_FACTOR 0.6
601 void PSDrawText( pdfdev* dev,
PLUNICODE* ucs4,
int ucs4Len,
short drawText )
608 PLFLT old_sscale, sscale, old_soffset, soffset, dup;
617 dev->fontScale = 1.0;
620 PSSetFont( dev, fci );
625 while ( i < ucs4Len )
631 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
632 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
635 if ( !dev->if_symbol_font )
639 type1_string[s] =
'\0';
640 PSDrawTextToCanvas( dev, type1_string, drawText );
646 else if ( !last_chance )
651 type1_string[s] =
'\0';
652 PSDrawTextToCanvas( dev, type1_string, drawText );
655 PSSetFont( dev, fci );
664 PSDrawTextToCanvas( dev, type1_string, drawText );
667 PSSetFont( dev, fci );
684 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
685 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
688 if ( !dev->if_symbol_font )
692 type1_string[s] =
'\0';
693 PSDrawTextToCanvas( dev, type1_string, drawText );
699 else if ( !last_chance )
704 type1_string[s] =
'\0';
705 PSDrawTextToCanvas( dev, type1_string, drawText );
708 PSSetFont( dev, fci );
717 PSDrawTextToCanvas( dev, type1_string, drawText );
720 PSSetFont( dev, fci );
739 PSDrawTextToCanvas( dev, type1_string, drawText );
743 &old_sscale, &sscale, &old_soffset, &soffset );
748 dup = 0.5 * ( 1.0 - sscale );
749 dev->fontScale = (HPDF_REAL) sscale;
750 PSSetFont( dev, fci );
751 dev->yOffset = (HPDF_REAL) ( dev->fontSize * ( soffset *
RISE_FACTOR + dup ) );
756 PSDrawTextToCanvas( dev, type1_string, drawText );
760 &old_sscale, &sscale, &old_soffset, &soffset );
765 dup = -0.5 * ( 1.0 - sscale );
766 dev->fontScale = (HPDF_REAL) sscale;
767 PSSetFont( dev, fci );
768 dev->yOffset = (HPDF_REAL) ( -dev->fontSize * ( soffset *
RISE_FACTOR + dup ) );
772 PSDrawTextToCanvas( dev, type1_string, drawText );
776 PSSetFont( dev, fci );
787 PSDrawTextToCanvas( dev, type1_string, drawText );
792 PSSetFont( dev, fci );
797 PSDrawTextToCanvas( dev, type1_string, drawText );
808 pdfdev * dev = (pdfdev *) pls->
dev;
809 PLFLT rotation, shear, stride;
810 HPDF_REAL cos_rot, sin_rot, cos_shear, sin_shear;
815 printf(
"Non unicode string passed to a pdf driver, ignoring\n" );
822 printf(
"Sorry, the pdf drivers only handles strings of length < %d\n",
MAX_STRING_LEN );
827 dev->fontSize = (HPDF_REAL) ( pls->
chrht * DEVICE_PIXELS_PER_INCH / 25.4 * 1.6 );
830 dev->textRed = (HPDF_REAL) ( pls->
curcolor.
r / 255.0 );
831 dev->textGreen = (HPDF_REAL) ( pls->
curcolor.
g / 255.0 );
832 dev->textBlue = (HPDF_REAL) ( pls->
curcolor.
b / 255.0 );
837 cos_rot = (HPDF_REAL) cos( rotation );
838 sin_rot = (HPDF_REAL) sin( rotation );
839 cos_shear = (HPDF_REAL) cos( shear );
840 sin_shear = (HPDF_REAL) sin( shear );
846 HPDF_Page_GSave( dev->page );
847 HPDF_Page_Concat( dev->page, cos_rot, sin_rot,
848 -cos_rot * sin_shear - sin_rot * cos_shear,
849 -sin_rot * sin_shear + cos_rot * cos_shear,
850 (HPDF_REAL) ( args->
x ), (HPDF_REAL) ( args->
y ) );
851 HPDF_Page_Concat( dev->page, (HPDF_REAL) 1.0, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0, (HPDF_REAL) 1.0,
852 (HPDF_REAL) ( -args->
just * dev->textWidth ), (HPDF_REAL) ( -0.5 * dev->textHeight ) );
854 HPDF_Page_GRestore( dev->page );
int plParseDrvOpts(DrvOpt *acc_opt)
void plP_script_scale(PLBOOL ifupper, PLINT *level, PLFLT *old_scale, PLFLT *scale, PLFLT *old_offset, PLFLT *offset)
void(* plD_line_fp)(struct PLStream_struct *, short, short, short, short)
void plexit(PLCHAR_VECTOR errormsg)
void(* plD_eop_fp)(struct PLStream_struct *)
void(* plD_state_fp)(struct PLStream_struct *, PLINT)
void(* plD_tidy_fp)(struct PLStream_struct *)
static const Unicode_to_Type1_table unicode_to_symbol_lookup_table[194]
void plOpenFile(PLStream *pls)
void plCloseFile(PLStream *pls)
static const int number_of_entries_in_unicode_to_standard_table
void plFamInit(PLStream *pls)
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
static const int number_of_entries_in_unicode_to_symbol_table
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
void(* plD_bop_fp)(struct PLStream_struct *)
static void poly_line(PLStream *, short *, short *, PLINT)
static const FCI_to_FontName_Table Type1Lookup[N_Type1Lookup]
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
PLDLLIMPEXP_DRIVER void plD_dispatch_init_pdf(PLDispatchTable *pdt)
#define PLDLLIMPEXP_DRIVER
static PLStream * pls[PL_NSTREAMS]
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
void plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
unsigned short unicode_array_len
PLCHAR_VECTOR plP_FCI2FontName(PLUNICODE fci, const FCI_to_FontName_Table lookup[], const int nlookup)
static const Unicode_to_Type1_table unicode_to_standard_lookup_table[154]
plD_polyline_fp pl_polyline
PLUNICODE * unicode_array
PLDLLIMPEXP_CXX void fill(PLINT n, const PLFLT *x, const PLFLT *y)
void(* plD_init_fp)(struct PLStream_struct *)