39 #define SVG_Default_X 720
40 #define SVG_Default_Y 540
42 #define POINTS_PER_INCH 72
44 #define MAX_STRING_LEN 1000
49 #define FONT_SIZE_RATIO 1.34
50 #define FONT_SHIFT_RATIO 0.705
51 #define FONT_SHIFT_OFFSET 0.5
103 static void write_hex( FILE *,
unsigned char );
131 #ifndef ENABLE_DYNDRIVERS
132 pdt->
pl_MenuStr =
"Scalable Vector Graphics (SVG 1.1)";
182 if ( pls->
dev != NULL )
183 free( (
void *) pls->
dev );
185 pls->
dev = calloc( 1, (
size_t)
sizeof (
SVG ) );
186 if ( pls->
dev == NULL )
187 plexit(
"plD_init_svg: Out of memory." );
189 aStream = (
SVG *) pls->
dev;
227 svg_general( aStream,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
228 svg_general( aStream,
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n" );
229 svg_general( aStream,
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n" );
260 svg_attr_value( aStream,
"xmlns:xlink",
"http://www.w3.org/1999/xlink" );
309 svg_attr_values( aStream,
"points",
"%r,%r %r,%r", (
double) x1a / aStream->
scale, (
double) y1a / aStream->
scale, (
double) x2a / aStream->
scale, (
double) y2a / aStream->
scale );
453 fprintf( aStream->
svgFile,
"points=\"" );
454 for ( i = 0; i < npts; i++ )
456 fprintf( aStream->
svgFile,
"%.2f,%.2f ", (
double) xa[i] / aStream->
scale, (
double) ya[i] / aStream->
scale );
457 if ( ( ( i + 1 ) % 10 ) == 0 )
459 fprintf( aStream->
svgFile,
"\n" );
463 fprintf( aStream->
svgFile,
"\"/>\n" );
484 svg_open( aStream,
"linearGradient" );
499 for ( i = 0; i < pls->
ncol1; i++ )
502 fprintf( aStream->
svgFile,
"<stop offset=\"%.3f\" ",
503 (
double) i / (
double) ( pls->
ncol1 - 1 ) );
504 fprintf( aStream->
svgFile,
"stop-color=\"#" );
508 fprintf( aStream->
svgFile,
"\" " );
509 fprintf( aStream->
svgFile,
"stop-opacity=\"%.3f\"/>\n", pls->
cmap1[i].
a );
515 sprintf( buffer,
"url(#MyGradient%010d)", aStream->
gradient_index++ );
518 fprintf( aStream->
svgFile,
"points=\"" );
519 for ( i = 0; i < npts; i++ )
521 fprintf( aStream->
svgFile,
"%.2f,%.2f ", (
double) xa[i] / aStream->
scale, (
double) ya[i] / aStream->
scale );
522 if ( ( ( i + 1 ) % 10 ) == 0 )
524 fprintf( aStream->
svgFile,
"\n" );
528 fprintf( aStream->
svgFile,
"\"/>\n" );
568 double ftHt, scaled_offset, scaled_ftHt;
570 PLINT rcx[4], rcy[4];
571 static PLINT prev_rcx[4], prev_rcy[4];
572 PLFLT rotation, shear, stride, cos_rot, sin_rot, sin_shear, cos_shear;
574 int glyph_size, sum_glyph_size;
579 PLFLT old_sscale, sscale, old_soffset, soffset, old_dup, ddup;
586 printf(
"Non unicode string passed to SVG driver, ignoring\n" );
598 aStream = (
SVG *) pls->
dev;
599 if ( aStream->textClipping )
605 if ( aStream->which_clip == 0 )
611 for ( i = 0; i < 4; i++ )
613 if ( rcx[i] != prev_rcx[i] ||
614 rcy[i] != prev_rcy[i] )
621 svg_attr_values( aStream,
"id",
"text-clipping%d", aStream->which_clip );
628 "%f,%f %f,%f %f,%f %f,%f",
629 ( (
PLFLT) rcx[0] ) / aStream->scale,
630 ( (
PLFLT) rcy[0] ) / aStream->scale,
631 ( (
PLFLT) rcx[1] ) / aStream->scale,
632 ( (
PLFLT) rcy[1] ) / aStream->scale,
633 ( (
PLFLT) rcx[2] ) / aStream->scale,
634 ( (
PLFLT) rcy[2] ) / aStream->scale,
635 ( (
PLFLT) rcx[3] ) / aStream->scale,
636 ( (
PLFLT) rcy[3] ) / aStream->scale );
640 for ( i = 0; i < 4; i++ )
642 prev_rcx[i] = rcx[i];
643 prev_rcy[i] = rcy[i];
645 aStream->which_clip++;
649 "url(#text-clipping%d)", aStream->which_clip - 1 );
682 cos_rot = cos( rotation );
683 sin_rot = -sin( rotation );
684 sin_shear = sin( shear );
685 cos_shear = -cos( shear );
686 t[0] = cos_rot * stride;
687 t[1] = -sin_rot * stride;
688 t[2] = cos_rot * sin_shear + sin_rot * cos_shear;
689 t[3] = -sin_rot * sin_shear + cos_rot * cos_shear;
711 t[0], t[1], t[2], t[3],
712 (
double) ( args->
x / aStream->scale ),
713 (
double) ( args->
y / aStream->scale ) );
727 glyph_size = (int) ftHt;
730 while ( if_write < 2 )
744 if ( args->
just < 0.33 )
749 else if ( args->
just > 0.66 )
766 fprintf( aStream->svgFile,
">" );
775 while ( i < ucs4Len )
787 sum_glyph_size += glyph_size;
801 sum_glyph_size += glyph_size;
814 &old_sscale, &sscale, &old_soffset, &soffset );
820 ddup = 0.5 * ( 1.0 - sscale );
823 scaled_offset =
FONT_SHIFT_RATIO * ftHt * ( 0.80 * ( soffset - old_soffset ) - ( ddup - old_dup ) );
827 scaled_offset = -
FONT_SHIFT_RATIO * ftHt * ( 0.80 * ( soffset - old_soffset ) + ( ddup - old_dup ) );
829 scaled_ftHt = sscale * ftHt;
833 fprintf( aStream->svgFile,
"<tspan dy=\"%f\" font-size=\"%d\">", scaled_offset, (
int) scaled_ftHt );
837 glyph_size = (int) scaled_ftHt;
843 &old_sscale, &sscale, &old_soffset, &soffset );
849 ddup = 0.5 * ( 1.0 - sscale );
852 scaled_offset =
FONT_SHIFT_RATIO * ftHt * ( 0.80 * ( soffset - old_soffset ) - ( ddup - old_dup ) );
856 scaled_offset = -
FONT_SHIFT_RATIO * ftHt * ( 0.80 * ( soffset - old_soffset ) + ( ddup - old_dup ) );
858 scaled_ftHt = sscale * ftHt;
862 fprintf( aStream->svgFile,
"<tspan dy=\"%f\" font-size=\"%d\">", scaled_offset, (
int) scaled_ftHt );
866 glyph_size = (int) scaled_ftHt;
889 for ( i = 0; i < totalTags; i++ )
891 fprintf( aStream->svgFile,
"</tspan>" );
901 fprintf( aStream->svgFile,
"</text>\n" );
902 aStream->svgIndent -= 2;
903 if ( aStream->textClipping )
918 fprintf( aStream->
svgFile,
"<%s\n", tag );
932 fprintf( aStream->
svgFile,
"/>\n" );
946 fprintf( aStream->
svgFile,
"%s=\"%s\"\n", attribute, value );
963 const char *p, *sval;
968 fprintf( aStream->
svgFile,
"%s=\"", attribute );
969 va_start( ap, format );
970 for ( p = format; *p; p++ )
974 fprintf( aStream->
svgFile,
"%c", *p );
980 ival = va_arg( ap,
int );
981 fprintf( aStream->
svgFile,
"%d", ival );
984 dval = va_arg( ap,
double );
985 fprintf( aStream->
svgFile,
"%f", dval );
989 dval = va_arg( ap,
double );
990 fprintf( aStream->
svgFile,
"%.2f", dval );
993 sval = va_arg( ap,
char * );
994 fprintf( aStream->
svgFile,
"%s", sval );
997 fprintf( aStream->
svgFile,
"%c", *p );
1001 fprintf( aStream->
svgFile,
"\"\n" );
1015 if ( strlen( tag ) > 0 )
1017 fprintf( aStream->
svgFile,
"</%s>\n", tag );
1021 fprintf( aStream->
svgFile,
"/>\n" );
1034 fprintf( aStream->
svgFile,
"%s", text );
1046 for ( i = 0; i < aStream->
svgIndent; i++ )
1048 fprintf( aStream->
svgFile,
" " );
1064 fprintf( aStream->
svgFile,
"stroke-width=\"%e\"\n", pls->
width );
1079 fprintf( aStream->
svgFile,
"stroke=\"#" );
1083 fprintf( aStream->
svgFile,
"\"\n" );
1100 fprintf( aStream->
svgFile,
"fill=\"#" );
1104 fprintf( aStream->
svgFile,
"\"\n" );
1121 fprintf( aStream->
svgFile,
"fill=\"#" );
1125 fprintf( aStream->
svgFile,
"\"\n" );
1127 fprintf( aStream->
svgFile,
"fill-opacity=\"%f\"\n", pls->
cmap0[0].
a );
1148 plwarn(
"All pages after the first skipped because family file output not specified.\n" );
1164 fprintf( svgFile,
"0%X", val );
1168 fprintf( svgFile,
"%X", val );
1181 if ( ucs4_char >=
' ' || ucs4_char ==
'\t' || ucs4_char ==
'\n' || ucs4_char ==
'\r' )
1182 fprintf( svgFile,
"&#x%x;", ucs4_char );
1184 fprintf( svgFile,
"&#x%x;",
' ' );
1204 fprintf( svgFile,
"<tspan " );
1208 if ( ( ucs4_char & 0x00F ) == 0x000 )
1210 fprintf( svgFile,
"font-family=\"sans-serif\" " );
1212 else if ( ( ucs4_char & 0x00F ) == 0x001 )
1214 fprintf( svgFile,
"font-family=\"serif\" " );
1216 else if ( ( ucs4_char & 0x00F ) == 0x002 )
1218 fprintf( svgFile,
"font-family=\"mono-space\" " );
1220 else if ( ( ucs4_char & 0x00F ) == 0x003 )
1222 fprintf( svgFile,
"font-family=\"cursive\" " );
1224 else if ( ( ucs4_char & 0x00F ) == 0x004 )
1227 fprintf( svgFile,
"font-family=\"sans-serif\" " );
1232 if ( ( ucs4_char & 0x0F0 ) == 0x000 )
1234 fprintf( svgFile,
"font-style=\"normal\" " );
1236 else if ( ( ucs4_char & 0x0F0 ) == 0x010 )
1238 fprintf( svgFile,
"font-style=\"italic\" " );
1240 else if ( ( ucs4_char & 0x0F0 ) == 0x020 )
1242 fprintf( svgFile,
"font-style=\"oblique\" " );
1247 if ( ( ucs4_char & 0xF00 ) == 0x000 )
1249 fprintf( svgFile,
"font-weight=\"normal\">" );
1251 else if ( ( ucs4_char & 0xF00 ) == 0x100 )
1253 fprintf( svgFile,
"font-weight=\"bold\">" );
int plParseDrvOpts(DrvOpt *acc_opt)
void plP_script_scale(PLBOOL ifupper, PLINT *level, PLFLT *old_scale, PLFLT *scale, PLFLT *old_offset, PLFLT *offset)
static void svg_fill_background_color(PLStream *)
static void write_hex(FILE *, unsigned char)
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_line_svg(PLStream *, short, short, short, short)
void(* plD_tidy_fp)(struct PLStream_struct *)
static int svg_family_check(PLStream *)
static void svg_general(SVG *, const char *)
void plOpenFile(PLStream *pls)
void plCloseFile(PLStream *pls)
void plGetFam(PLStream *pls)
static void proc_str(PLStream *, EscText *)
void plD_tidy_svg(PLStream *)
#define FONT_SHIFT_OFFSET
static void svg_attr_values(SVG *, const char *, const char *,...)
static void gradient(PLStream *, short *, short *, PLINT)
static void poly_line(PLStream *, short *, short *, PLINT, short)
void plFamInit(PLStream *pls)
void(* plD_polyline_fp)(struct PLStream_struct *, short *, short *, PLINT)
static void specify_font(FILE *, PLUNICODE)
void plD_polyline_svg(PLStream *, short *, short *, PLINT)
void(* plD_esc_fp)(struct PLStream_struct *, PLINT, void *)
void plD_bop_svg(PLStream *)
void(* plD_bop_fp)(struct PLStream_struct *)
void plD_dispatch_init_svg(PLDispatchTable *pdt)
static void svg_open(SVG *, const char *)
static void svg_attr_value(SVG *, const char *, const char *)
void difilt_clip(PLINT *x_coords, PLINT *y_coords)
static void write_unicode(FILE *, PLUNICODE)
void plD_init_svg(PLStream *)
void plP_setpxl(PLFLT xpmm, PLFLT ypmm)
static void svg_stroke_color(PLStream *)
static void svg_open_end(SVG *)
static void svg_stroke_width(PLStream *)
#define PLDLLIMPEXP_DRIVER
static PLStream * pls[PL_NSTREAMS]
void plP_setphy(PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
static void svg_close(SVG *, const char *)
void plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
unsigned short unicode_array_len
static PLFLT value(double n1, double n2, double hue)
static int already_warned
void plD_esc_svg(PLStream *, PLINT, void *)
void plD_state_svg(PLStream *, PLINT)
void plwarn(PLCHAR_VECTOR errormsg)
static DrvOpt svg_options[]
static void svg_fill_color(PLStream *)
void plD_eop_svg(PLStream *)
plD_polyline_fp pl_polyline
static void svg_indent(SVG *)
PLUNICODE * unicode_array
PLDLLIMPEXP_CXX void fill(PLINT n, const PLFLT *x, const PLFLT *y)
PLDLLIMPEXP_DRIVER const char * plD_DEVICE_INFO_svg
void(* plD_init_fp)(struct PLStream_struct *)