summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2016-08-06 19:14:31 -0300
committerWerner Almesberger <werner@almesberger.net>2016-08-06 19:14:31 -0300
commitae5c02bbe7498b38f6173d31b900170ae8e54ddc (patch)
tree5029e73220a66b19482f2bc3c2c8d392d5709d34
parentb3e7bfacea40336e4f855f662a8c88a31e94f007 (diff)
downloadeeshow-ae5c02bbe7498b38f6173d31b900170ae8e54ddc.tar.gz
eeshow-ae5c02bbe7498b38f6173d31b900170ae8e54ddc.tar.bz2
eeshow-ae5c02bbe7498b38f6173d31b900170ae8e54ddc.zip
eeshow/: use printf-style formatting for overlay text; test mode -F fmt string
-rw-r--r--Makefile2
-rw-r--r--fmt-pango.c145
-rw-r--r--fmt-pango.h24
-rw-r--r--gui-over.c23
-rw-r--r--gui-over.h4
-rw-r--r--gui.c25
-rw-r--r--main.c15
7 files changed, 218 insertions, 20 deletions
diff --git a/Makefile b/Makefile
index fb059cc..6323f05 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@
NAME = eeshow
OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \
- gui.o gui-over.o gui-aoi.o \
+ gui.o gui-over.o gui-aoi.o fmt-pango.o \
file.o git-util.o git-file.o git-hist.o \
style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o
diff --git a/fmt-pango.c b/fmt-pango.c
new file mode 100644
index 0000000..9ae77f4
--- /dev/null
+++ b/fmt-pango.c
@@ -0,0 +1,145 @@
+/*
+ * fmt-pango.c - Format strings for Pango markup
+ *
+ * Written 2016 by Werner Almesberger
+ * Copyright 2016 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#define _GNU_SOURCE /* for asprintf */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <alloca.h>
+
+#include "util.h"
+#include "fmt-pango.h"
+
+
+unsigned vsfmt_pango(char *buf, const char *fmt, va_list ap)
+{
+ char *res;
+ const char *p, *q, *s, *t;
+ char *u;
+ char *tmp_fmt;
+ char *tmp, *tmp2;
+ int len;
+ unsigned extra;
+
+ res = buf;
+ for (p = fmt; *p; p++) {
+ if (*p != '%') {
+ if (buf)
+ *res = *p;
+ res++;
+ continue;
+ }
+ for (q = p + 1; isdigit(*q) || *q == '.' || *q == '-'; q++);
+ tmp_fmt = alloca(q - p + 1 + 1);
+ memcpy(tmp_fmt, p, q - p + 1);
+ tmp_fmt[q - p + 1] = 0;
+ switch (*q) {
+ case 's':
+ s = va_arg(ap, const char *);
+ len = asprintf(&tmp, tmp_fmt, s);
+
+ extra = 0;
+ for (t = tmp; *t; t++)
+ switch (*t) {
+ case '<':
+ case '>':
+ extra += 3;
+ break;
+ case '&':
+ extra += 4;
+ break;
+ default:
+ break;
+ }
+
+ if (extra) {
+ tmp2 = u = alloca(len + extra + 1);
+ for (t = tmp; *t; t++) {
+ switch (*t) {
+ case '<':
+ strcpy(u, "&lt;");
+ u += 4;
+ break;
+ case '>':
+ strcpy(u, "&gt;");
+ u += 4;
+ break;
+ case '&':
+ strcpy(u, "&amp;");
+ u += 5;
+ break;
+ default:
+ *u++ = *t;
+ break;
+ }
+ }
+ *u = 0;
+ tmp = tmp2;
+ }
+
+ if (buf)
+ memcpy(res, tmp, len + extra);
+ res += len + extra;
+ break;
+ case 'c':
+ /* @@@ we don't filter markup meta-characters */
+ case 'd':
+ case 'x':
+ len = asprintf(&tmp, tmp_fmt, va_arg(ap, int));
+ if (buf)
+ memcpy(res, tmp, len);
+ res += len;
+ break;
+ case '%':
+ if (buf)
+ *res = '%';
+ res++;
+ break;
+ default:
+ fprintf(stderr, "unrecognized format '%%%c'\n", *q);
+ exit(1);
+ }
+ p = q;
+ }
+ if (buf)
+ *res = 0;
+ return res - buf;
+}
+
+
+char *vfmt_pango(const char *fmt, va_list ap)
+{
+ va_list aq;
+ unsigned len;
+ char *buf;
+
+ va_copy(aq, ap);
+ len = vsfmt_pango(NULL, fmt, ap);
+ buf = alloc_size(len + 1);
+ vsfmt_pango(buf, fmt, aq);
+ va_end(aq);
+ return buf;
+}
+
+
+char *fmt_pango(const char *fmt, ...)
+{
+ va_list ap;
+ char *buf;
+
+ va_start(ap, fmt);
+ buf = vfmt_pango(fmt, ap);
+ va_end(ap);
+ return buf;
+}
diff --git a/fmt-pango.h b/fmt-pango.h
new file mode 100644
index 0000000..5cf2416
--- /dev/null
+++ b/fmt-pango.h
@@ -0,0 +1,24 @@
+/*
+ * fmt-pango.h - Format strings for Pango markup
+ *
+ * Written 2016 by Werner Almesberger
+ * Copyright 2016 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#ifndef FMT_PANGO_H
+#define FMT_PANGO_H
+
+#include <stdarg.h>
+
+
+unsigned vsfmt_pango(char *buf, const char *fmt, va_list ap);
+char *vfmt_pango(const char *fmt, va_list ap);
+char *fmt_pango(const char *fmt, ...);
+
+#endif /* !FMT_PANGO_H */
diff --git a/gui-over.c b/gui-over.c
index 3b4550b..7f5186e 100644
--- a/gui-over.c
+++ b/gui-over.c
@@ -19,13 +19,16 @@
*/
#include <stddef.h>
+#include <stdarg.h>
#include <stdlib.h>
+#include <stdio.h>
#include <math.h>
#include <cairo/cairo.h>
#include <pango/pangocairo.h>
#include "util.h"
+#include "fmt-pango.h"
#include "gui-aoi.h"
#include "gui-over.h"
@@ -74,8 +77,8 @@ struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y)
PangoRectangle ink_rect;
layout = pango_cairo_create_layout(cr);
- pango_layout_set_text(layout, over->s, -1);
- desc = pango_font_description_from_string("Helvetica Bold 12");
+ pango_layout_set_markup(layout, over->s, -1);
+ desc = pango_font_description_from_string("Helvetica 10");
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
@@ -131,15 +134,14 @@ void overlay_draw_all(struct overlay *overlays, cairo_t *cr)
}
-struct overlay *overlay_add(struct overlay **overlays, const char *s,
- struct aoi **aois,
+struct overlay *overlay_add(struct overlay **overlays, struct aoi **aois,
bool (*hover)(void *user, bool on), void (*click)(void *user), void *user)
{
struct overlay *over;
struct overlay **anchor;
over = alloc_type(struct overlay);
- over->s = stralloc(s);
+ over->s = NULL;
over->aois = aois;
over->hover = hover;
@@ -155,6 +157,17 @@ struct overlay *overlay_add(struct overlay **overlays, const char *s,
}
+void overlay_text(struct overlay *over, const char *fmt, ...)
+{
+ va_list ap;
+
+ free((char *) over->s);
+ va_start(ap, fmt);
+ over->s = vfmt_pango(fmt, ap);
+ va_end(ap);
+}
+
+
static void overlay_free(struct overlay *over)
{
if (over->aoi)
diff --git a/gui-over.h b/gui-over.h
index 477c5d9..bdde9a6 100644
--- a/gui-over.h
+++ b/gui-over.h
@@ -25,9 +25,9 @@ struct overlay;
struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y);
void overlay_draw_all(struct overlay *overlays, cairo_t *cr);
-struct overlay *overlay_add(struct overlay **overlays, const char *s,
- struct aoi **aois,
+struct overlay *overlay_add(struct overlay **overlays, struct aoi **aois,
bool (*hover)(void *user, bool on), void (*click)(void *user), void *user);
+void overlay_text(struct overlay *over, const char *fmt, ...);
void overlay_remove(struct overlay **overlays, struct overlay *over);
void overlay_remove_all(struct overlay **overlays);
diff --git a/gui.c b/gui.c
index 5fc51a2..879abc7 100644
--- a/gui.c
+++ b/gui.c
@@ -303,14 +303,15 @@ static void click_history(void *user)
static void show_history(struct gui_ctx *ctx)
{
struct gui_hist *h = ctx->hist;
- char *s;
+ struct overlay *over;
overlay_remove_all(&ctx->vcs_overlays);
for (h = ctx->hist; h; h = h->next) {
// @@@ \n doesn't work with cairo_show_text :-(
- if (asprintf(&s, "commit\n%s", vcs_git_summary(h->hist))) {}
- overlay_add(&ctx->vcs_overlays, s, &ctx->aois,
+ over = overlay_add(&ctx->vcs_overlays, &ctx->aois,
NULL, click_history, h);
+ overlay_text(over, "<small>%.60s</small>",
+ vcs_git_summary(h->hist));
}
redraw(ctx);
}
@@ -341,6 +342,8 @@ static void close_subsheet(void *user)
static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
{
+ struct overlay *over;
+
if (!sheet->rendered) {
render_sheet(sheet);
mark_aois(ctx, sheet);
@@ -348,16 +351,16 @@ static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
ctx->curr_sheet = sheet;
overlay_remove_all(&ctx->sheet_overlays);
if (ctx->hist) {
- char *s;
-
- if (asprintf(&s, "%.40s",
- vcs_git_summary(ctx->curr_hist->hist))) {}
- overlay_add(&ctx->sheet_overlays, s, &ctx->aois,
+ over = overlay_add(&ctx->sheet_overlays, &ctx->aois,
NULL, show_history_cb, ctx);
+ overlay_text(over, "%.40s",
+ vcs_git_summary(ctx->curr_hist->hist));
+ }
+ if (sheet->sch->title) {
+ over = overlay_add(&ctx->sheet_overlays, &ctx->aois,
+ NULL, close_subsheet, ctx);
+ overlay_text(over, "<b>%s</b>", sheet->sch->title);
}
- if (sheet->sch->title)
- overlay_add(&ctx->sheet_overlays, sheet->sch->title,
- &ctx->aois, NULL, close_subsheet, ctx);
zoom_to_extents(ctx);
}
diff --git a/main.c b/main.c
index 815b556..0960015 100644
--- a/main.c
+++ b/main.c
@@ -27,6 +27,7 @@
#include "file.h"
#include "lib.h"
#include "sch.h"
+#include "fmt-pango.h"
#include "git-hist.h"
#include "gui.h"
#include "main.h"
@@ -94,6 +95,7 @@ int main(int argc, char **argv)
bool recurse = 0;
const char *cat = NULL;
const char *history = NULL;
+ const char *fmt = NULL;
char c;
int arg, dashdash;
bool have_dashdash = 0;
@@ -110,7 +112,7 @@ int main(int argc, char **argv)
if (!have_dashdash)
gtk_init(&argc, &argv);
- while ((c = getopt(dashdash, argv, "rvC:H:")) != EOF)
+ while ((c = getopt(dashdash, argv, "rvC:F:H:")) != EOF)
switch (c) {
case 'r':
recurse = 1;
@@ -121,6 +123,9 @@ int main(int argc, char **argv)
case 'C':
cat = optarg;
break;
+ case 'F':
+ fmt = optarg;
+ break;
case 'H':
history = optarg;
break;
@@ -149,6 +154,14 @@ int main(int argc, char **argv)
return 0;
}
+ if (fmt) {
+ char *buf;
+
+ buf = fmt_pango(fmt, argv[optind]);
+ printf("\"%s\"\n", buf);
+ return 0;
+ }
+
if (dashdash - optind < 1)
usage(*argv);