123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- #include "sys-defines.h"
- #include "extern.h"
- #define PL_MAX_SVG_STRING_LEN 256
- #define PL_SVG_FONT_SIZE_IN_PX 20.0
- static void write_svg_text_style (plOutbuf *page, const plDrawState *drawstate, int h_just, int v_just);
- typedef struct
- {
- char c;
- const char *s;
- }
- plCharEscape;
- #define NUM_SVG_CHAR_ESCAPES 5
- static const plCharEscape _svg_char_escapes[NUM_SVG_CHAR_ESCAPES] =
- {
- {'\'', "apos"},
- {'"', "quot"},
- {'&', "amp"},
- {'<', "lt"},
- {'>', "gt"}
- };
- #define MAX_SVG_CHAR_ESCAPE_LEN 4
- static const char * const svg_horizontal_alignment_style[PL_NUM_HORIZ_JUST_TYPES] =
- { "start", "middle", "end" };
- static const char * const svg_vertical_alignment_style[PL_NUM_VERT_JUST_TYPES] =
- { "text-before-edge", "central", "alphabetic", "text-after-edge", "hanging" };
- double
- _pl_s_paint_text_string (R___(Plotter *_plotter) const unsigned char *s, int h_just, int v_just)
- {
- const unsigned char *sp = s;
- unsigned char *t, *tp;
- int i, n = 0;
- double local_matrix[6];
- double angle = _plotter->drawstate->text_rotation;
-
-
- tp = t = (unsigned char *)_pl_xmalloc ((2 + MAX_SVG_CHAR_ESCAPE_LEN) * strlen ((const char *)s) + 1);
- while (*sp && n < PL_MAX_SVG_STRING_LEN)
- {
- bool matched;
- int i;
-
- matched = false;
- for (i = 0; i < NUM_SVG_CHAR_ESCAPES; i++)
- {
- if (*sp == (unsigned char)_svg_char_escapes[i].c)
- {
- matched = true;
- break;
- }
- }
- if (matched)
- {
- *tp++ = (unsigned char)'&';
- strcpy ((char *)tp, _svg_char_escapes[i].s);
- tp += strlen (_svg_char_escapes[i].s);
- *tp++ = (unsigned char)';';
- }
- else
- *tp++ = *sp;
- sp++;
- n++;
- }
- *tp = '\0';
-
- sprintf (_plotter->data->page->point, "<text ");
- _update_buffer (_plotter->data->page);
-
- local_matrix[0] = cos (M_PI * angle / 180.0);
- local_matrix[1] = sin (M_PI * angle / 180.0);
- local_matrix[2] = -sin (M_PI * angle / 180.0) * (-1);
- local_matrix[3] = cos (M_PI * angle / 180.0) * (-1);
-
- for (i = 0; i < 4; i++)
- local_matrix[i] *= (_plotter->drawstate->font_size
- / PL_SVG_FONT_SIZE_IN_PX);
- local_matrix[4] = _plotter->drawstate->pos.x;
- local_matrix[5] = _plotter->drawstate->pos.y;
- _pl_s_set_matrix (R___(_plotter) local_matrix);
- write_svg_text_style (_plotter->data->page, _plotter->drawstate,
- h_just, v_just);
- sprintf (_plotter->data->page->point, ">");
- _update_buffer (_plotter->data->page);
-
- sprintf (_plotter->data->page->point, "%s",
- (char *)t);
- _update_buffer (_plotter->data->page);
-
- sprintf (_plotter->data->page->point, "</text>\n");
- _update_buffer (_plotter->data->page);
- free (t);
- return _plotter->get_text_width (R___(_plotter) s);
- }
- static void
- write_svg_text_style (plOutbuf *page, const plDrawState *drawstate, int h_just, int v_just)
- {
- const char *ps_name, *css_family, *css_generic_family;
- const char *css_style, *css_weight, *css_stretch;
- bool css_family_is_ps_name;
- char color_buf[8];
-
- switch (drawstate->font_type)
- {
- int master_font_index;
- case PL_F_POSTSCRIPT:
- master_font_index =
- (_pl_g_ps_typeface_info[drawstate->typeface_index].fonts)[drawstate->font_index];
- ps_name = _pl_g_ps_font_info[master_font_index].ps_name;
- css_family = _pl_g_ps_font_info[master_font_index].css_family;
- css_generic_family = _pl_g_ps_font_info[master_font_index].css_generic_family;
- css_style = _pl_g_ps_font_info[master_font_index].css_style;
- css_weight = _pl_g_ps_font_info[master_font_index].css_weight;
- css_stretch = _pl_g_ps_font_info[master_font_index].css_stretch;
-
- page->ps_font_used[master_font_index] = true;
- break;
- case PL_F_PCL:
- master_font_index =
- (_pl_g_pcl_typeface_info[drawstate->typeface_index].fonts)[drawstate->font_index];
- ps_name = _pl_g_pcl_font_info[master_font_index].ps_name;
- css_family = _pl_g_pcl_font_info[master_font_index].css_family;
- css_generic_family = _pl_g_pcl_font_info[master_font_index].css_generic_family;
- css_style = _pl_g_pcl_font_info[master_font_index].css_style;
- css_weight = _pl_g_pcl_font_info[master_font_index].css_weight;
- css_stretch = _pl_g_pcl_font_info[master_font_index].css_stretch;
-
- page->pcl_font_used[master_font_index] = true;
- break;
- default:
- return;
- break;
- }
- if (strcmp (ps_name, css_family) == 0)
-
- css_family_is_ps_name = true;
- else
- css_family_is_ps_name = false;
-
- if (css_generic_family)
- {
- if (css_family_is_ps_name)
- sprintf (page->point, "font-family=\"%s,%s\" ",
- css_family, css_generic_family);
- else
- sprintf (page->point, "font-family=\"%s,%s,%s\" ",
- ps_name, css_family, css_generic_family);
- }
- else
- {
- if (css_family_is_ps_name)
- sprintf (page->point, "font-family=\"%s\" ",
- css_family);
- else
- sprintf (page->point, "font-family=\"%s,%s\" ",
- ps_name, css_family);
- }
- _update_buffer (page);
-
- if (strcmp (css_style, "normal") != 0)
- {
- sprintf (page->point, "font-style=\"%s\" ",
- css_style);
- _update_buffer (page);
- }
- if (strcmp (css_weight, "normal") != 0)
- {
- sprintf (page->point, "font-weight=\"%s\" ",
- css_weight);
- _update_buffer (page);
- }
- if (strcmp (css_stretch, "normal") != 0)
- {
- sprintf (page->point, "font-stretch=\"%s\" ",
- css_stretch);
- _update_buffer (page);
- }
- sprintf (page->point, "font-size=\"%.5gpx\" ",
-
- PL_SVG_FONT_SIZE_IN_PX);
- _update_buffer (page);
- if (h_just != PL_JUST_LEFT)
- {
- sprintf (page->point, "text-anchor=\"%s\" ",
- svg_horizontal_alignment_style[h_just]);
- _update_buffer (page);
- }
- if (v_just != PL_JUST_BASE)
- {
- sprintf (page->point, "alignment-baseline=\"%s\" ",
- svg_vertical_alignment_style[v_just]);
- _update_buffer (page);
- }
-
- sprintf (page->point, "stroke=\"none\" ");
- _update_buffer (page);
- if (drawstate->pen_type)
-
- {
- sprintf (page->point, "fill=\"%s\" ",
- _libplot_color_to_svg_color (drawstate->fgcolor, color_buf));
- _update_buffer (page);
- }
- }
|