1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-11-26 21:01:31 +02:00

eeshow/: use printf-style formatting for overlay text; test mode -F fmt string

This commit is contained in:
Werner Almesberger 2016-08-06 19:14:31 -03:00
parent 45726be08f
commit 18c3b6e476
7 changed files with 218 additions and 20 deletions

View File

@ -12,7 +12,7 @@
NAME = eeshow NAME = eeshow
OBJS = main.o sch-parse.o sch-render.o lib-parse.o lib-render.o \ 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 \ 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 style.o fig.o record.o cro.o diff.o gfx.o dwg.o text.o misc.o

145
eeshow/fmt-pango.c Normal file
View File

@ -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;
}

24
eeshow/fmt-pango.h Normal file
View File

@ -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 */

View File

@ -19,13 +19,16 @@
*/ */
#include <stddef.h> #include <stddef.h>
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <math.h> #include <math.h>
#include <cairo/cairo.h> #include <cairo/cairo.h>
#include <pango/pangocairo.h> #include <pango/pangocairo.h>
#include "util.h" #include "util.h"
#include "fmt-pango.h"
#include "gui-aoi.h" #include "gui-aoi.h"
#include "gui-over.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; PangoRectangle ink_rect;
layout = pango_cairo_create_layout(cr); layout = pango_cairo_create_layout(cr);
pango_layout_set_text(layout, over->s, -1); pango_layout_set_markup(layout, over->s, -1);
desc = pango_font_description_from_string("Helvetica Bold 12"); desc = pango_font_description_from_string("Helvetica 10");
pango_layout_set_font_description(layout, desc); pango_layout_set_font_description(layout, desc);
pango_font_description_free(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 overlay *overlay_add(struct overlay **overlays, struct aoi **aois,
struct aoi **aois,
bool (*hover)(void *user, bool on), void (*click)(void *user), void *user) bool (*hover)(void *user, bool on), void (*click)(void *user), void *user)
{ {
struct overlay *over; struct overlay *over;
struct overlay **anchor; struct overlay **anchor;
over = alloc_type(struct overlay); over = alloc_type(struct overlay);
over->s = stralloc(s); over->s = NULL;
over->aois = aois; over->aois = aois;
over->hover = hover; 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) static void overlay_free(struct overlay *over)
{ {
if (over->aoi) if (over->aoi)

View File

@ -25,9 +25,9 @@ struct overlay;
struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y); struct overlay *overlay_draw(struct overlay *over, cairo_t *cr, int *x, int *y);
void overlay_draw_all(struct overlay *overlays, cairo_t *cr); void overlay_draw_all(struct overlay *overlays, cairo_t *cr);
struct overlay *overlay_add(struct overlay **overlays, const char *s, struct overlay *overlay_add(struct overlay **overlays, struct aoi **aois,
struct aoi **aois,
bool (*hover)(void *user, bool on), void (*click)(void *user), void *user); 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(struct overlay **overlays, struct overlay *over);
void overlay_remove_all(struct overlay **overlays); void overlay_remove_all(struct overlay **overlays);

View File

@ -303,14 +303,15 @@ static void click_history(void *user)
static void show_history(struct gui_ctx *ctx) static void show_history(struct gui_ctx *ctx)
{ {
struct gui_hist *h = ctx->hist; struct gui_hist *h = ctx->hist;
char *s; struct overlay *over;
overlay_remove_all(&ctx->vcs_overlays); overlay_remove_all(&ctx->vcs_overlays);
for (h = ctx->hist; h; h = h->next) { for (h = ctx->hist; h; h = h->next) {
// @@@ \n doesn't work with cairo_show_text :-( // @@@ \n doesn't work with cairo_show_text :-(
if (asprintf(&s, "commit\n%s", vcs_git_summary(h->hist))) {} over = overlay_add(&ctx->vcs_overlays, &ctx->aois,
overlay_add(&ctx->vcs_overlays, s, &ctx->aois,
NULL, click_history, h); NULL, click_history, h);
overlay_text(over, "<small>%.60s</small>",
vcs_git_summary(h->hist));
} }
redraw(ctx); 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) static void go_to_sheet(struct gui_ctx *ctx, struct gui_sheet *sheet)
{ {
struct overlay *over;
if (!sheet->rendered) { if (!sheet->rendered) {
render_sheet(sheet); render_sheet(sheet);
mark_aois(ctx, 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; ctx->curr_sheet = sheet;
overlay_remove_all(&ctx->sheet_overlays); overlay_remove_all(&ctx->sheet_overlays);
if (ctx->hist) { if (ctx->hist) {
char *s; over = overlay_add(&ctx->sheet_overlays, &ctx->aois,
if (asprintf(&s, "%.40s",
vcs_git_summary(ctx->curr_hist->hist))) {}
overlay_add(&ctx->sheet_overlays, s, &ctx->aois,
NULL, show_history_cb, ctx); 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); zoom_to_extents(ctx);
} }

View File

@ -27,6 +27,7 @@
#include "file.h" #include "file.h"
#include "lib.h" #include "lib.h"
#include "sch.h" #include "sch.h"
#include "fmt-pango.h"
#include "git-hist.h" #include "git-hist.h"
#include "gui.h" #include "gui.h"
#include "main.h" #include "main.h"
@ -94,6 +95,7 @@ int main(int argc, char **argv)
bool recurse = 0; bool recurse = 0;
const char *cat = NULL; const char *cat = NULL;
const char *history = NULL; const char *history = NULL;
const char *fmt = NULL;
char c; char c;
int arg, dashdash; int arg, dashdash;
bool have_dashdash = 0; bool have_dashdash = 0;
@ -110,7 +112,7 @@ int main(int argc, char **argv)
if (!have_dashdash) if (!have_dashdash)
gtk_init(&argc, &argv); gtk_init(&argc, &argv);
while ((c = getopt(dashdash, argv, "rvC:H:")) != EOF) while ((c = getopt(dashdash, argv, "rvC:F:H:")) != EOF)
switch (c) { switch (c) {
case 'r': case 'r':
recurse = 1; recurse = 1;
@ -121,6 +123,9 @@ int main(int argc, char **argv)
case 'C': case 'C':
cat = optarg; cat = optarg;
break; break;
case 'F':
fmt = optarg;
break;
case 'H': case 'H':
history = optarg; history = optarg;
break; break;
@ -149,6 +154,14 @@ int main(int argc, char **argv)
return 0; return 0;
} }
if (fmt) {
char *buf;
buf = fmt_pango(fmt, argv[optind]);
printf("\"%s\"\n", buf);
return 0;
}
if (dashdash - optind < 1) if (dashdash - optind < 1)
usage(*argv); usage(*argv);