41 #include "hpdf/hpdf.h"
53 #define stricmp strcasecmp
54 #define strnicmp strncasecmp
64 #define CANVAS_WIDTH ( 50.0 )
65 #define CANVAS_HEIGHT ( 37.5 )
66 #define DEVICE_PIXELS_PER_INCH ( 72 )
69 #define MM_PER_INCH ( 25.4 )
72 #define DEVICE_PIXELS_PER_MM ( DEVICE_PIXELS_PER_INCH / MM_PER_INCH )
75 #define MAX_STRING_LEN 1000
82 HPDF_PageSizes pageSize;
88 int nlookup, if_symbol_font;
92 HPDF_REAL textWidth, textHeight;
94 HPDF_REAL textRed, textGreen, textBlue;
98 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pdf =
"pdf:Portable Document Format PDF:1:pdf:58:pdf\n";
106 static short desired_offset(
short,
double );
115 void plD_line_pdf(
PLStream *,
short,
short,
short,
short );
116 void plD_polyline_pdf(
PLStream *,
short *,
short *,
PLINT );
134 error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
void *user_data )
137 printf(
"ERROR: error_no=%04X, detail_no=%d\n", (
unsigned int) error_no, (
int) detail_no );
149 #ifndef ENABLE_DYNDRIVERS
150 pdt->
pl_MenuStr =
"Portable Document Format PDF";
168 static PLINT compress = 1;
170 static PLINT color = 1;
171 static char * pageSize = NULL;
174 {
"text",
DRV_INT, &
text,
"Use own text routines (text=0|1)" },
175 {
"color",
DRV_INT, &color,
"Use color (color=0|1)" },
176 {
"compress",
DRV_INT, &compress,
"Compress pdf output (compress=0|1)" },
177 {
"hrshsym",
DRV_INT, &
hrshsym,
"Use Hershey symbol set (hrshsym=0|1)" },
178 {
"pagesize",
DRV_STR, &pageSize,
"Set page size (pagesize=A4|letter|A3|A5)" },
193 dev = (pdfdev *) calloc( 1,
sizeof ( pdfdev ) );
195 plexit(
"Insufficient memory\n" );
196 pls->
dev = (
void *) dev;
228 plspage( DEVICE_PIXELS_PER_INCH, DEVICE_PIXELS_PER_INCH,
257 dev->pdf = HPDF_New( error_handler, NULL );
259 plexit(
"ERROR: cannot create pdf object.\n" );
262 HPDF_SetCompressionMode( dev->pdf, HPDF_COMP_ALL );
265 dev->pageSize = HPDF_PAGE_SIZE_EOF;
266 if ( pageSize == NULL )
267 dev->pageSize = HPDF_PAGE_SIZE_A4;
268 else if ( !stricmp( pageSize,
"letter" ) )
269 dev->pageSize = HPDF_PAGE_SIZE_LETTER;
270 else if ( !stricmp( pageSize,
"A3" ) )
271 dev->pageSize = HPDF_PAGE_SIZE_A3;
272 else if ( !stricmp( pageSize,
"A4" ) )
273 dev->pageSize = HPDF_PAGE_SIZE_A4;
274 else if ( !stricmp( pageSize,
"A5" ) )
275 dev->pageSize = HPDF_PAGE_SIZE_A5;
277 if ( dev->pageSize == HPDF_PAGE_SIZE_EOF )
278 plexit(
"ERROR: Unknown page size. Allowed strings are: letter, A3, A4, A5.\n" );
287 fprintf( stderr,
"ERROR in haru library\n" );
299 pdfdev * dev = (pdfdev *) pls->
dev;
300 HPDF_REAL width, height;
305 dev->page = HPDF_AddPage( dev->pdf );
307 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_PORTRAIT );
309 HPDF_Page_SetSize( dev->page, dev->pageSize, HPDF_PAGE_LANDSCAPE );
312 width = HPDF_Page_GetWidth( dev->page );
313 height = HPDF_Page_GetHeight( dev->page );
316 HPDF_Page_Concat( dev->page, (HPDF_REAL) ( dev->scalex ), 0, 0, (HPDF_REAL) ( dev->scaley ), 0, 0 );
320 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
cmap0[0].
r / 255.0 ),
321 (HPDF_REAL) ( pls->
cmap0[0].
g / 255.0 ), (HPDF_REAL) ( pls->
cmap0[0].
b / 255.0 ) );
322 width /= (HPDF_REAL) ( dev->scalex );
323 height /= (HPDF_REAL) ( dev->scaley );
324 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0 );
325 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) 0.0 );
326 HPDF_Page_LineTo( dev->page, width, (HPDF_REAL) height );
327 HPDF_Page_LineTo( dev->page, 0.0, (HPDF_REAL) height );
328 HPDF_Page_Fill( dev->page );
337 void plD_line_pdf(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
341 xa[0] = x1a; xa[1] = x2a;
342 ya[0] = y1a; ya[1] = y2a;
353 void plD_polyline_pdf(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
377 pdfdev* dev = (pdfdev *) pls->
dev;
380 HPDF_SaveToStream( dev->pdf );
383 HPDF_ResetStream( dev->pdf );
389 HPDF_UINT32 size = 4096;
390 HPDF_STATUS ret = HPDF_ReadFromStream( dev->pdf, buf, &size );
395 if ( fwrite( buf, size, 1, dev->pdfFile ) != 1 )
396 plexit(
"ERROR: Cannot write to file!" );
402 HPDF_Free( dev->pdf );
433 process_string( pls, (
EscText *) ptr );
446 pdfdev* dev = (pdfdev *) pls->
dev;
449 HPDF_Page_SetLineWidth( dev->page, (HPDF_REAL) ( pls->
width ) );
450 HPDF_Page_SetLineCap( dev->page, HPDF_ROUND_END );
451 HPDF_Page_SetLineJoin( dev->page, HPDF_ROUND_JOIN );
452 HPDF_Page_SetRGBStroke( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
454 HPDF_Page_SetRGBFill( dev->page, (HPDF_REAL) ( pls->
curcolor.
r / 255.0 ),
457 HPDF_Page_MoveTo( dev->page, (HPDF_REAL) xa[0], (HPDF_REAL) ya[0] );
458 for ( i = 1; i < npts; i++ )
459 HPDF_Page_LineTo( dev->page, (HPDF_REAL) xa[i], (HPDF_REAL) ya[i] );
464 HPDF_Page_EofillStroke( dev->page );
466 HPDF_Page_FillStroke( dev->page );
470 HPDF_Page_Stroke( dev->page );
485 static unsigned char plunicode2type1(
const PLUNICODE index,
489 int jlo = -1, jmid, jhi = nlookup;
491 while ( jhi - jlo > 1 )
497 jmid = ( jlo + jhi ) / 2;
498 if ( index > lookup[jmid].Unicode )
500 else if ( index < lookup[jmid].Unicode )
506 return ( lookup[jmid].Type1 );
523 void PSDrawTextToCanvas( pdfdev* dev,
unsigned char* type1_string,
short drawText )
530 HPDF_Page_BeginText( dev->page );
531 HPDF_Page_SetTextRenderingMode( dev->page, HPDF_FILL );
532 HPDF_Page_SetRGBFill( dev->page, dev->textRed, dev->textGreen, dev->textBlue );
533 HPDF_Page_MoveTextPos( dev->page, dev->textWidth, dev->yOffset );
534 HPDF_Page_ShowText( dev->page, (
char *) type1_string );
535 HPDF_Page_EndText( dev->page );
539 dev->textWidth += HPDF_Page_TextWidth( dev->page, (
char *) type1_string );
540 th = (HPDF_REAL) ( HPDF_Font_GetCapHeight( dev->m_font ) * dev->fontSize * dev->fontScale / 1000.0 );
541 dev->textHeight = dev->textHeight > ( th + dev->yOffset ) ? dev->textHeight : ( th + dev->yOffset );
553 void PSSetFont( pdfdev* dev,
PLUNICODE fci )
565 dev->if_symbol_font = 1;
573 dev->if_symbol_font = 0;
576 if ( !( dev->m_font = HPDF_GetFont( dev->pdf, font, NULL ) ) )
577 plexit(
"ERROR: Couldn't open font\n" );
579 HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
588 # define RISE_FACTOR 0.6
597 void PSDrawText( pdfdev* dev,
PLUNICODE* ucs4,
int ucs4Len,
short drawText )
604 PLFLT old_sscale, sscale, old_soffset, soffset, dup;
613 dev->fontScale = 1.0;
616 PSSetFont( dev, fci );
621 while ( i < ucs4Len )
627 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
628 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
631 if ( !dev->if_symbol_font )
635 type1_string[s] =
'\0';
636 PSDrawTextToCanvas( dev, type1_string, drawText );
642 else if ( !last_chance )
647 type1_string[s] =
'\0';
648 PSDrawTextToCanvas( dev, type1_string, drawText );
651 PSSetFont( dev, fci );
660 PSDrawTextToCanvas( dev, type1_string, drawText );
663 PSSetFont( dev, fci );
680 type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
681 if ( ucs4[i] !=
' ' && type1_string[s] ==
' ' )
684 if ( !dev->if_symbol_font )
688 type1_string[s] =
'\0';
689 PSDrawTextToCanvas( dev, type1_string, drawText );
695 else if ( !last_chance )
700 type1_string[s] =
'\0';
701 PSDrawTextToCanvas( dev, type1_string, drawText );
704 PSSetFont( dev, fci );
713 PSDrawTextToCanvas( dev, type1_string, drawText );
716 PSSetFont( dev, fci );
735 PSDrawTextToCanvas( dev, type1_string, drawText );
739 &old_sscale, &sscale, &old_soffset, &soffset );
744 dup = 0.5 * ( 1.0 - sscale );
745 dev->fontScale = sscale;
746 PSSetFont( dev, fci );
747 dev->yOffset = dev->fontSize * ( soffset *
RISE_FACTOR + dup );
752 PSDrawTextToCanvas( dev, type1_string, drawText );
756 &old_sscale, &sscale, &old_soffset, &soffset );
761 dup = -0.5 * ( 1.0 - sscale );
762 dev->fontScale = sscale;
763 PSSetFont( dev, fci );
764 dev->yOffset = -dev->fontSize * ( soffset *
RISE_FACTOR + dup );
768 PSDrawTextToCanvas( dev, type1_string, drawText );
772 PSSetFont( dev, fci );
783 PSDrawTextToCanvas( dev, type1_string, drawText );
788 PSSetFont( dev, fci );
793 PSDrawTextToCanvas( dev, type1_string, drawText );
804 pdfdev * dev = (pdfdev *) pls->
dev;
805 PLFLT rotation, shear, stride;
806 HPDF_REAL cos_rot, sin_rot, cos_shear, sin_shear;
811 printf(
"Non unicode string passed to a pdf driver, ignoring\n" );
818 printf(
"Sorry, the pdf drivers only handles strings of length < %d\n",
MAX_STRING_LEN );
823 dev->fontSize = (HPDF_REAL) ( pls->
chrht * DEVICE_PIXELS_PER_INCH / 25.4 * 1.6 );
826 dev->textRed = (HPDF_REAL) ( pls->
curcolor.
r / 255.0 );
827 dev->textGreen = (HPDF_REAL) ( pls->
curcolor.
g / 255.0 );
828 dev->textBlue = (HPDF_REAL) ( pls->
curcolor.
b / 255.0 );
833 cos_rot = (HPDF_REAL) cos( rotation );
834 sin_rot = (HPDF_REAL) sin( rotation );
835 cos_shear = (HPDF_REAL) cos( shear );
836 sin_shear = (HPDF_REAL) sin( shear );
842 HPDF_Page_GSave( dev->page );
843 HPDF_Page_Concat( dev->page, cos_rot, sin_rot,
844 -cos_rot * sin_shear - sin_rot * cos_shear,
845 -sin_rot * sin_shear + cos_rot * cos_shear,
846 (HPDF_REAL) ( args->
x ), (HPDF_REAL) ( args->
y ) );
847 HPDF_Page_Concat( dev->page, (HPDF_REAL) 1.0, (HPDF_REAL) 0.0, (HPDF_REAL) 0.0, (HPDF_REAL) 1.0,
848 (HPDF_REAL) ( -args->
just * dev->textWidth ), (HPDF_REAL) ( -0.5 * dev->textHeight ) );
850 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(* 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 *)
const char * plP_FCI2FontName(PLUNICODE fci, const FCI_to_FontName_Table lookup[], const int nlookup)
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
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
static const Unicode_to_Type1_table unicode_to_standard_lookup_table[154]
plD_polyline_fp pl_polyline
PLUNICODE * unicode_array
void(* plD_init_fp)(struct PLStream_struct *)
void plexit(const char *errormsg)