/* * Copyright © 2009 CNRS * Copyright © 2009-2020 Inria. All rights reserved. * Copyright © 2009-2010 Université Bordeaux * Copyright © 2011 Cisco Systems, Inc. All rights reserved. * See COPYING in top-level directory. */ #include "private/autogen/config.h" #include "hwloc.h" #include #include #include #include #include "lstopo.h" /* .fig back-end. */ #define FIG_FACTOR 20 static int fig_color_index = 32; static int fig_declare_color(struct lstopo_output *loutput, struct lstopo_color *lcolor) { FILE *file = loutput->file; int r = lcolor->r, g = lcolor->g, b = lcolor->b; if (r == 0xff && g == 0xff && b == 0xff) { lcolor->private.fig.color = 7; return 0; } else if (!r && !g && !b) { lcolor->private.fig.color = 0; return 0; } else { lcolor->private.fig.color = fig_color_index++; } fprintf(file, "0 %d #%02x%02x%02x\n", lcolor->private.fig.color, (unsigned) r, (unsigned) g, (unsigned) b); return 0; } static void fig_box(struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth, unsigned x, unsigned width, unsigned y, unsigned height, hwloc_obj_t obj __hwloc_attribute_unused, unsigned box_id __hwloc_attribute_unused) { FILE *file = loutput->file; struct lstopo_obj_userdata *ou = obj ? obj->userdata : NULL; unsigned linestyle = 0; /* solid */ unsigned dashspace = 0; /* no dash */ unsigned thickness = loutput->thickness; if (!width || !height) return; if (loutput->show_cpukinds && ou && ou->cpukind_style) { linestyle = 1; /* dash */ dashspace = 1U << ou->cpukind_style; thickness *= (1 + ou->cpukind_style); } x *= FIG_FACTOR; y *= FIG_FACTOR; width *= FIG_FACTOR; height *= FIG_FACTOR; fprintf(file, "2 2 %u %u 0 %d %u -1 20 %u.0 0 0 -1 0 0 5\n\t", linestyle, thickness, lcolor->private.fig.color, depth, dashspace); fprintf(file, " %u %u", x, y); fprintf(file, " %u %u", x + width, y); fprintf(file, " %u %u", x + width, y + height); fprintf(file, " %u %u", x, y + height); fprintf(file, " %u %u", x, y); fprintf(file, "\n"); } static void fig_line(struct lstopo_output *loutput, const struct lstopo_color *lcolor, unsigned depth, unsigned x1, unsigned y1, unsigned x2, unsigned y2, hwloc_obj_t obj __hwloc_attribute_unused, unsigned line_id __hwloc_attribute_unused) { FILE *file = loutput->file; x1 *= FIG_FACTOR; y1 *= FIG_FACTOR; x2 *= FIG_FACTOR; y2 *= FIG_FACTOR; fprintf(file, "2 1 0 %u 0 %d %u -1 -1 0.0 0 0 -1 0 0 2\n\t", loutput->thickness, lcolor->private.fig.color, depth); fprintf(file, " %u %u", x1, y1); fprintf(file, " %u %u", x2, y2); fprintf(file, "\n"); } #define FIG_FONTSIZE_SCALE(size) (((size) * 11) / 10) /* assume character width is half their height on average */ #define FIG_TEXT_WIDTH(length, fontsize) (((length) * (fontsize))/2) static void fig_text(struct lstopo_output *loutput, const struct lstopo_color *lcolor, int size, unsigned depth, unsigned x, unsigned y, const char *text, hwloc_obj_t obj __hwloc_attribute_unused, unsigned text_id __hwloc_attribute_unused) { FILE *file = loutput->file; struct lstopo_obj_userdata *ou = obj ? obj->userdata : NULL; unsigned fontflags = 0; /* normal */ int len = (int)strlen(text); int color; if (loutput->show_cpukinds && ou && (ou->cpukind_style % 2)) fontflags = 2; /* bold for odd styles */ color = lcolor->private.fig.color; x *= FIG_FACTOR; y *= FIG_FACTOR; /* move the origin of the text away from the box corner */ x += (size * FIG_FACTOR * 2) / 10; y += (size * FIG_FACTOR * 4) / 10; size = FIG_FONTSIZE_SCALE(size); fprintf(file, "4 0 %d %u -1 %u %d 0.0 4 %d %d %u %u %s\\001\n", color, depth, fontflags, size, size * FIG_FACTOR, FIG_TEXT_WIDTH(len, size) * FIG_FACTOR, x, y + size * 10, text); } static void fig_textsize(struct lstopo_output *loutput __hwloc_attribute_unused, const char *text __hwloc_attribute_unused, unsigned textlength, unsigned fontsize, unsigned *width) { fontsize = FIG_FONTSIZE_SCALE(fontsize); *width = FIG_TEXT_WIDTH(textlength, fontsize); } static struct draw_methods fig_draw_methods = { fig_declare_color, NULL, fig_box, fig_line, fig_text, fig_textsize, }; int output_fig (struct lstopo_output *loutput, const char *filename) { FILE *output = open_output(filename, loutput->overwrite); if (!output) { fprintf(stderr, "Failed to open %s for writing (%s)\n", filename, strerror(errno)); return -1; } loutput->file = output; loutput->methods = &fig_draw_methods; /* recurse once for preparing sizes and positions */ loutput->drawing = LSTOPO_DRAWING_PREPARE; output_draw(loutput); loutput->drawing = LSTOPO_DRAWING_DRAW; fprintf(output, "#FIG 3.2 Produced by hwloc's lstopo\n"); fprintf(output, "Landscape\n"); fprintf(output, "Center\n"); fprintf(output, "Inches\n"); fprintf(output, "letter\n"); fprintf(output, "100.00\n"); /* magnification */ fprintf(output, "Single\n"); /* single page */ fprintf(output, "-2\n"); /* no transparent color */ fprintf(output, "1200 2\n"); /* 1200 ppi resolution, upper left origin */ /* ready */ declare_colors(loutput); lstopo_prepare_custom_styles(loutput); output_draw(loutput); if (output != stdout) fclose(output); destroy_colors(loutput); return 0; }