altos/draw: Add logo
authorKeith Packard <keithp@keithp.com>
Sun, 26 Feb 2023 07:46:25 +0000 (23:46 -0800)
committerKeith Packard <keithp@keithp.com>
Sun, 26 Feb 2023 07:46:25 +0000 (23:46 -0800)
Captures the SVG logo polygons and allows them to be
scaled to suit.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/draw/.gitignore
src/draw/Makefile
src/draw/ao_draw.h
src/draw/ao_logo.c [new file with mode: 0644]
src/draw/draw-test.c
src/draw/make-logo [new file with mode: 0755]

index 62968a97b262e23d9e073efda4df09461a46f141..3ed0f319b643a997329bcf8955f479b27b6fbea0 100644 (file)
@@ -1,3 +1,4 @@
 Frutiger*.c
 ao_font.h
+ao_logo.h
 draw-test
index ca5628b6f0216af071c1e7b5b9589c71d18f4aba..46771f1fde7c8b5576c2192631b44f1b8e550770 100644 (file)
@@ -15,13 +15,16 @@ FONT_SRCS=$(BDFS:.bdf=.c)
 .bdf.c:
        nickle font-convert $*.bdf > $@
 
-all: ao_font.h draw-test
+all: ao_font.h ao_logo.h draw-test
 
 $(FONT_SRCS): font-convert
 
 ao_font.h: $(FONT_SRCS)
        grep -h '^const struct ao_font' $(FONT_SRCS) | sed -e 's/^/extern /' -e 's/ =.*$$/;/' > $@
 
+ao_logo.h: make-logo Makefile
+       nickle make-logo ao_logo 48 0 10 > $@
+
 SRCS=\
        draw-test.c \
        ao_blt.c \
@@ -31,6 +34,7 @@ SRCS=\
        ao_rect.c \
        ao_poly.c \
        ao_text.c \
+       ao_logo.c \
        $(FONT_SRCS)
 
 OBJS=$(SRCS:.c=.o)
@@ -42,7 +46,8 @@ CFLAGS=-O0 -g
 HEADERS=\
        ao_draw.h \
        ao_draw_int.h \
-       ao_font.h
+       ao_font.h \
+       ao_logo.h
 
 draw-test: $(OBJS)
        cc $(CFLAGS) -o $@ $(OBJS) $(LIBS)
@@ -50,4 +55,4 @@ draw-test: $(OBJS)
 $(OBJS): $(HEADERS)
 
 clean:
-       rm -f $(OBJS) ao_font.h $(FONT_SRCS)
+       rm -f $(OBJS) ao_font.h ao_logo.h $(FONT_SRCS)
index 8d487a9975e57658ae0a602e0958a401c55a5035..fbbc61c419cc909653c149ad7aaf92c2b707154a 100644 (file)
@@ -107,6 +107,12 @@ ao_text(const struct ao_bitmap     *dst,
        uint32_t                fill,
        uint8_t                 rop);
 
+void
+ao_logo(const struct ao_bitmap *dst,
+       const struct ao_font    *font,
+       uint32_t                fill,
+       uint8_t                 rop);
+
 extern const struct ao_font FrutigerLT_Roman_50_font;
 
 #define AO_SHIFT       5
diff --git a/src/draw/ao_logo.c b/src/draw/ao_logo.c
new file mode 100644 (file)
index 0000000..1469ae2
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2023 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "ao_draw.h"
+#include "ao_logo.h"
+
+#define ARRAYSIZE(a)   (sizeof(a) / sizeof((a)[0]))
+
+void
+ao_logo(const struct ao_bitmap *dst,
+       const struct ao_font    *font,
+       uint32_t                fill,
+       uint8_t                 rop)
+{
+       ao_poly(dst, ao_logo_top, ARRAYSIZE(ao_logo_top), 0x00000000, AO_COPY);
+       ao_poly(dst, ao_logo_bottom, ARRAYSIZE(ao_logo_bottom), 0x00000000, AO_COPY);
+       ao_text(dst, font, 38, 31, "Altus", 0x00000000, AO_COPY);
+       ao_text(dst, font, 38, 57, "Metrum", 0x00000000, AO_COPY);
+}
index 2f8ca636462a32d79957f7573d183deb03fb74b1..58e08a40522220aef3d31579ad1890d6185c7770 100644 (file)
@@ -39,6 +39,7 @@ static struct ao_bitmap fb = {
 
 #define BIG_FONT FrutigerLT_Roman_64_font
 #define SMALL_FONT FrutigerLT_Roman_12_font
+#define LOGO_FONT FrutigerLT_Roman_24_font
 
 #define VALUE_Y                BIG_FONT.ascent
 #define LABEL_Y                BIG_FONT.ascent + SMALL_FONT.ascent + 2
@@ -81,8 +82,9 @@ void HandleExpose(Display *dpy, Window win, GC gc)
        ao_rect(&fb, 0, 0, WIDTH, HEIGHT, 0xffffffff, AO_COPY);
 
        if (do_polys) {
-               ao_poly(&fb, trek, NCOORD_TREK, 0x00000000, AO_COPY);
-               ao_poly(&fb, donut, NCOORD_DONUT, 0x00000000, AO_COPY);
+               ao_logo(&fb, &LOGO_FONT, 0x00000000, AO_COPY);
+//             ao_poly(&fb, trek, NCOORD_TREK, 0x00000000, AO_COPY);
+//             ao_poly(&fb, donut, NCOORD_DONUT, 0x00000000, AO_COPY);
        } else {
                char    str[64];
 
@@ -109,7 +111,6 @@ HandleKeyPress(Display *dpy, Window win, GC gc, XEvent *ev)
 {
        char    string[10];
        if (XLookupString ((XKeyEvent *) ev, string, sizeof (string), 0, 0) >= 1) {
-               printf("key %s\n", string);
                switch (string[0]) {
                case 'q':
                        exit (0);
diff --git a/src/draw/make-logo b/src/draw/make-logo
new file mode 100755 (executable)
index 0000000..ede1c37
--- /dev/null
@@ -0,0 +1,118 @@
+#!/usr/bin/nickle
+
+typedef struct {
+       string  cmd;
+       real    x, y;
+} coord_t;
+
+coord_t[] top = {
+       { .cmd = "m",  .x = 931.07168, .y = 27.69425 },
+       { .cmd = "l",  .x = 224.03682, .y = 720.46517 },
+       { .cmd = "l",  .x = -63.341, .y = 76.00913 },
+       { .cmd = "L",  .x = 931.07168, .y = 486.3269 },
+       { .cmd = "L",  .x = 770.37586, .y = 824.16855 },
+       { .cmd = "L",  .x = 707.03486, .y = 748.15942 },
+       { .cmd = "L",  .x = 931.07168, .y = 27.69425 },
+};
+
+coord_t[] bottom = {
+       { .cmd = "m",  .x = 931.07168, .y = 1164.597 },
+       { .cmd = "l",  .x = 248.86992, .y = -331.80265 },
+       { .cmd = "l",  .x = 416.1687, .y = 1338.32935 },
+       { .cmd = "l",  .x = 286.6484, .y = 267.1042 },
+       { .cmd = "l",  .x = -520.4224, .y = 0 },
+       { .cmd = "l",  .x = -270.2797, .y = -262.2181 },
+       { .cmd = "l",  .x = 0, .y = -1033.0627 },
+       { .cmd = "l",  .x = -160.98492, .y = 106.6818 },
+       { .cmd = "l",  .x = -160.98492, .y = -106.6818 },
+       { .cmd = "l",  .x = 0, .y = 1033.0627 },
+       { .cmd = "l",  .x = -270.2797, .y = 262.2181 },
+       { .cmd = "l",  .x = -520.4224, .y = 0 },
+       { .cmd = "l",  .x = 286.6484, .y = -267.1042 },
+       { .cmd = "l",  .x = 416.1687, .y = -1338.32935 },
+       { .cmd = "l",  .x = 248.86992, .y = 331.80265 },
+};
+
+typedef struct {
+       bool    set;
+       real    min_x, max_x, min_y, max_y;
+} bounds_t;
+
+bounds_t
+merge_bounds(coord_t[] polygon, bounds_t bounds)
+{
+       real x = 0.0;
+       real y = 0.0;
+
+       for (int i = 0; i < dim(polygon); i++) {
+               switch (polygon[i].cmd) {
+               case "m":
+               case "l":
+                       x += polygon[i].x;
+                       y += polygon[i].y;
+                       break;
+               case "M":
+               case "L":
+                       x = polygon[i].x;
+                       y = polygon[i].y;
+                       break;
+               }
+               if (!bounds.set) {
+                       bounds.min_x = bounds.max_x = x;
+                       bounds.min_y = bounds.max_y = y;
+                       bounds.set = true;
+               } else {
+                       bounds.min_x = min(x, bounds.min_x);
+                       bounds.max_x = max(x, bounds.max_x);
+                       bounds.min_y = min(y, bounds.min_y);
+                       bounds.max_y = max(y, bounds.max_y);
+               }
+       }
+       return bounds;
+}
+
+void
+print_poly(coord_t[] polygon, real height, bounds_t bounds, real x_pos, real y_pos)
+{
+       real x = 0.0;
+       real y = 0.0;
+
+       real scale = height / (bounds.max_y - bounds.min_y);
+       real x_off = bounds.min_x;
+       real y_off = bounds.min_y;
+
+       for (int i = 0; i < dim(polygon); i++) {
+               switch (polygon[i].cmd) {
+               case "m":
+               case "l":
+                       x += polygon[i].x;
+                       y += polygon[i].y;
+                       break;
+               case "M":
+               case "L":
+                       x = polygon[i].x;
+                       y = polygon[i].y;
+                       break;
+               }
+               printf("\t{ .x = %8g, .y = %8g },\n",
+                      (x - x_off) * scale + x_pos,
+                      (y - y_off) * scale + y_pos);
+       }
+}
+
+void
+print_logo(string name, real height, real x_pos, real y_pos)
+{
+       bounds_t bounds = { .set = false };
+       bounds = merge_bounds(top, bounds);
+       bounds = merge_bounds(bottom, bounds);
+       printf("const struct ao_coord %s_top[] = {\n", name);
+       print_poly(top, height, bounds, x_pos, y_pos);
+       printf("};\n");
+       printf("\n");
+       printf("const struct ao_coord %s_bottom[] = {\n", name);
+       print_poly(bottom, height, bounds, x_pos, y_pos);
+       printf("};\n");
+}
+
+print_logo(argv[1], string_to_real(argv[2]), string_to_real(argv[3]), string_to_real(argv[4]));