[rrd-developers] [patch] [SVG] Support for CSS font families.
Alexander V Alekseev
alex at alemate.ru
Fri May 25 16:25:59 CEST 2007
Hello!
As specified in SVG 1.1 specification
(http://www.w3.org/TR/SVG11/text.html#FontFamilyProperty), the only
fonts you can rely upon are 5 CSS2 font families:
'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'
(As specified at http://www.w3.org/TR/REC-CSS2/fonts.html#value-def-generic-family ).
But RRD 1.2.15 considers all of them unknown. I've made a small
patch (attached), which allows usage of those fonts for SVG output
format. (Font metrics are taken from RRD_AFM_DEFAULT_FONT).
This patch doesn't solve the general problem, that all font
calculation should depend on output format. But this is just my first patch
to rrd. ;-))
Bye. Alex.
-------------- next part --------------
--- rrdtool-1.2.15/src/rrd_gfx.c.orig Mon May 21 20:29:39 2007
+++ rrdtool-1.2.15/src/rrd_gfx.c Tue May 22 18:12:18 2007
@@ -282,7 +282,24 @@
switch (canvas->imgformat) {
case IF_PNG:
return gfx_get_text_width_libart (canvas, start, font, size, tabwidth, text, rotation);
- case IF_SVG: /* fall through */
+ case IF_SVG:
+ /* There are 5 predefined fonts in SVG:
+ * 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'.
+ * http://www.w3.org/TR/SVG11/text.html#FontFamilyProperty
+ * http://www.w3.org/TR/REC-CSS2/fonts.html#value-def-generic-family
+ *
+ * If any of them found, calculate metrics based on default font.
+ */
+
+ if( strcasecmp(font,"serif") ||
+ strcasecmp(font,"sans-serif") ||
+ strcasecmp(font,"cursive") ||
+ strcasecmp(font,"fantasy") ||
+ strcasecmp(font,"monospace")
+ ){
+ font=RRD_AFM_DEFAULT_FONT;
+ }
+ /* fall through */
case IF_EPS:
case IF_PDF:
return afm_get_text_width(start, font, size, tabwidth, text);
@@ -916,9 +933,10 @@
}
-static void pdf_calc(int page_height, gfx_node_t *node, pdf_coords *g)
+static void pdf_calc(int page_height, gfx_node_t *node, pdf_coords *g, enum gfx_if_en format)
{
pdf_point a, b, c;
+ char *font;
#if PDF_CALC_DEBUG
/* g->debug = !!strstr(node->text, "RevProxy-1") || !!strstr(node->text, "08:00"); */
g->debug = !!strstr(node->text, "sekunder") || !!strstr(node->text, "Web");
@@ -934,9 +952,32 @@
g->cos_r = 1;
g->sin_r = 0;
}
- g->ascender = afm_get_ascender(node->filename, node->size);
- g->descender = afm_get_descender(node->filename, node->size);
- g->sizep.x = afm_get_text_width(0, node->filename, node->size, node->tabwidth, node->text);
+ if( format == IF_SVG ){
+ /* There are 5 predefined fonts in SVG:
+ * 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'.
+ * http://www.w3.org/TR/SVG11/text.html#FontFamilyProperty
+ * http://www.w3.org/TR/REC-CSS2/fonts.html#value-def-generic-family
+ *
+ * Substitute default font in theese cases.
+ *
+ */
+
+ if( strcasecmp(node->filename,"serif") &&
+ strcasecmp(node->filename,"sans-serif") &&
+ strcasecmp(node->filename,"cursive") &&
+ strcasecmp(node->filename,"fantasy") &&
+ strcasecmp(node->filename,"monospace")
+ ){
+ font = node->filename;
+ } else {
+ font = RRD_AFM_DEFAULT_FONT;
+ }
+ }else{
+ font = node->filename;
+ }
+ g->ascender = afm_get_ascender(font, node->size);
+ g->descender = afm_get_descender(font, node->size);
+ g->sizep.x = afm_get_text_width(0, font, node->size, node->tabwidth, node->text);
/* seems like libart ignores the descender when doing vertial-align = bottom,
so we do that too, to get labels v-aligning properly */
g->sizep.y = -g->ascender; /* + afm_get_descender(font->ps_font, node->size); */
@@ -1382,7 +1423,7 @@
bottom-left corner like pdf and eps, we have to fake the coords
using offset and inverse sin(r) value */
int page_height = 1000;
- pdf_calc(page_height, node, &g);
+ pdf_calc(page_height, node, &g,IF_SVG);
if (node->angle != 0) {
svg_start_tag(fp, "g");
/* can't use svg_write_number as 2 decimals is far from enough to avoid
@@ -1399,7 +1440,22 @@
svg_write_number(fp, page_height - g.tmy);
fputs("\"", fp);
}
- fontname = afm_get_font_name(node->filename);
+ /* There are 5 predefined fonts in SVG:
+ * 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'.
+ * http://www.w3.org/TR/SVG11/text.html#FontFamilyProperty
+ * http://www.w3.org/TR/REC-CSS2/fonts.html#value-def-generic-family
+ */
+
+ if( strcasecmp(node->filename,"serif") &&
+ strcasecmp(node->filename,"sans-serif") &&
+ strcasecmp(node->filename,"cursive") &&
+ strcasecmp(node->filename,"fantasy") &&
+ strcasecmp(node->filename,"monospace")
+ ){
+ fontname = afm_get_font_name(node->filename);
+ } else {
+ fontname = node->filename;
+ }
if (strcmp(fontname, svg_default_font))
fprintf(fp, " font-family=\"%s\"", fontname);
fputs(" font-size=\"", fp);
@@ -1423,7 +1479,22 @@
one. It reduces the number of font-familty attributes. */
while (node) {
if (node->type == GFX_TEXT && node->filename) {
- svg_default_font = afm_get_font_name(node->filename);
+ /* There are 5 predefined fonts in SVG:
+ * 'serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'.
+ * http://www.w3.org/TR/SVG11/text.html#FontFamilyProperty
+ * http://www.w3.org/TR/REC-CSS2/fonts.html#value-def-generic-family
+ */
+
+ if( strcasecmp(node->filename,"serif") &&
+ strcasecmp(node->filename,"sans-serif") &&
+ strcasecmp(node->filename,"cursive") &&
+ strcasecmp(node->filename,"fantasy") &&
+ strcasecmp(node->filename,"monospace")
+ ){
+ svg_default_font = afm_get_font_name(node->filename);
+ }else{
+ svg_default_font = node->filename;
+ }
break;
}
node = node->next;
@@ -1754,7 +1825,7 @@
if (!p)
return;
#endif
- pdf_calc(state->page_height, node, &g);
+ pdf_calc(state->page_height, node, &g,IF_EPS);
eps_set_color(state, node->color);
if (strcmp(ps_font, state->font) || node->size != state->font_size) {
state->font = ps_font;
@@ -2287,7 +2358,7 @@
state->has_failed = 1;
return;
}
- pdf_calc(state->page_height, node, &g);
+ pdf_calc(state->page_height, node, &g,IF_PDF);
#if PDF_CALC_DEBUG
pdf_puts(s, "q % debug green box\n");
pdf_write_matrix(state, node, &g, 0);
More information about the rrd-developers
mailing list