From: erg Date: Sat, 28 Aug 2010 21:16:51 +0000 (+0000) Subject: The xdot text drawing relies on pango_parse_markup. This X-Git-Tag: LAST_LIBGRAPH~32^2~1210 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b0e646e0bf4d9d97fefc650e3dc98820e6952fcb;p=graphviz The xdot text drawing relies on pango_parse_markup. This assumes the input text is xml-compatible, so we have to wrap the string using xml_string(). --- diff --git a/cmd/smyrna/draw.c b/cmd/smyrna/draw.c index 5c7d3f585..53d59e5bf 100755 --- a/cmd/smyrna/draw.c +++ b/cmd/smyrna/draw.c @@ -458,7 +458,7 @@ static void EmbedText(sdot_op* o, int param) { o->font=glNewFont( view->widgets, - o->op.u.text.text, + xml_string (o->op.u.text.text), &view->penColor, pangotext, font_op->op.u.font.name,font_op->op.u.font.size,0); diff --git a/cmd/smyrna/smyrna_utils.c b/cmd/smyrna/smyrna_utils.c index 276108075..6540a024f 100644 --- a/cmd/smyrna/smyrna_utils.c +++ b/cmd/smyrna/smyrna_utils.c @@ -14,6 +14,13 @@ * AT&T Research, Florham Park NJ * **********************************************************/ #include "smyrna_utils.h" +#include "memory.h" +/* many of these functions are available in libcommon. + * We cannot use those because dependencies cause a great + * deal of libcommon to be brought in, which complicates + * and makes possible conflicts as some parts of libcommon + * rely on not using libcgraph. + */ int mapbool(char *p) { if (p == NULL) @@ -29,6 +36,100 @@ int mapbool(char *p) return atoi(p); } +/* return true if *s points to &[A-Za-z]*; (e.g. Ç ) + * or &#[0-9]*; (e.g. & ) + * or &#x[0-9a-fA-F]*; (e.g. 水 ) + */ +static int xml_isentity(char *s) +{ + s++; /* already known to be '&' */ + if (*s == '#') { + s++; + if (*s == 'x' || *s == 'X') { + s++; + while ((*s >= '0' && *s <= '9') + || (*s >= 'a' && *s <= 'f') + || (*s >= 'A' && *s <= 'F')) + s++; + } else { + while (*s >= '0' && *s <= '9') + s++; + } + } else { + while ((*s >= 'a' && *s <= 'z') + || (*s >= 'A' && *s <= 'Z')) + s++; + } + if (*s == ';') + return 1; + return 0; +} + +char *xml_string(char *s) +{ + static char *buf = NULL; + static int bufsize = 0; + char *p, *sub, *prev = NULL; + int len, pos = 0; + + if (!buf) { + bufsize = 64; + buf = N_NEW(bufsize, char); + } + + p = buf; + while (s && *s) { + if (pos > (bufsize - 8)) { + bufsize *= 2; + buf = realloc(buf, bufsize); + p = buf + pos; + } + /* escape '&' only if not part of a legal entity sequence */ + if (*s == '&' && !(xml_isentity(s))) { + sub = "&"; + len = 5; + } + /* '<' '>' are safe to substitute even if string is already UTF-8 coded + * since UTF-8 strings won't contain '<' or '>' */ + else if (*s == '<') { + sub = "<"; + len = 4; + } + else if (*s == '>') { + sub = ">"; + len = 4; + } + else if (*s == '-') { /* can't be used in xml comment strings */ + sub = "-"; + len = 5; + } + else if (*s == ' ' && prev && *prev == ' ') { + /* substitute 2nd and subsequent spaces with required_spaces */ + sub = " "; /* inkscape doesn't recognise   */ + len = 6; + } + else if (*s == '"') { + sub = """; + len = 6; + } + else if (*s == '\'') { + sub = "'"; + len = 5; + } + else { + sub = s; + len = 1; + } + while (len--) { + *p++ = *sub++; + pos++; + } + prev = s; + s++; + } + *p = '\0'; + return buf; +} #if 0 static int late_int(void *obj,Agsym_t* attr, int def, int low) { diff --git a/cmd/smyrna/smyrna_utils.h b/cmd/smyrna/smyrna_utils.h index 2fb958946..83310918e 100644 --- a/cmd/smyrna/smyrna_utils.h +++ b/cmd/smyrna/smyrna_utils.h @@ -19,6 +19,7 @@ #include "smyrnadefs.h" #include "cgraph.h" +extern char *xml_string(char *s); extern int l_int(void *obj, Agsym_t * attr, int def); extern float l_float(void *obj, Agsym_t * attr, float def); extern int mapbool(char *p);