/* * Copyright (c) 2014 Martin Sucha * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @addtogroup fontviewer * @{ */ /** @file */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NAME "fontviewer" #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 static window_t *main_window; static surface_t *surface = NULL; static canvas_t *canvas = NULL; static surface_coord_t width, height; uint16_t points = 16; bool show_metrics = true; char *font_path = NULL; static int draw(void); static void on_keyboard_event(widget_t *widget, void *data) { kbd_event_t *event = (kbd_event_t *) data; if (event->type == KEY_PRESS) { if (event->c == 'q') exit(0); if (event->key == KC_UP || event->key == KC_DOWN) { uint16_t increment = (event->mods & KM_SHIFT) ? 10 : 1; if (event->key == KC_UP) points += increment; if (event->key == KC_DOWN) { if (points <= increment) { points = 1; } else { points-= increment; } } if (points < 1) points = 1; } if (event->c == 'm') show_metrics = !show_metrics; } int rc = draw(); if (rc != EOK) { printf("Failed drawing: %d.\n", rc); exit(1); } update_canvas(canvas, surface); } static int create_font(font_t **font, uint16_t points) { if (font_path == NULL) { return embedded_font_create(font, points); } return pcf_font_create(font, font_path, points); } static source_t rgb(uint8_t r, uint8_t g, uint8_t b) { source_t source; source_init(&source); source_set_color(&source, PIXEL(255, r, g, b)); return source; } static void horizontal_rectangle(drawctx_t *drawctx, surface_coord_t x1, surface_coord_t y1, surface_coord_t x2, surface_coord_t y2, source_t *source) { if (y2 < y1) return; drawctx_set_source(drawctx, source); drawctx_transfer(drawctx, x1, y1, x2 - x1 + 1, y2 - y1 + 1); } static void horizontal_line(drawctx_t *drawctx, surface_coord_t y, surface_coord_t x1, surface_coord_t x2, source_t *source) { horizontal_rectangle(drawctx, x1, y, x2, y, source); } static int text(drawctx_t *, font_t *, source_t *, surface_coord_t x, surface_coord_t , const char *, ...) PRINTF_ATTRIBUTE(6, 7); static int text(drawctx_t *drawctx, font_t *font, source_t *source, surface_coord_t x, surface_coord_t y, const char *fmt, ...) { char *str = NULL; va_list args; va_start(args, fmt); int ret = vasprintf(&str, fmt, args); va_end(args); if (ret <= 0) return ret; drawctx_set_source(drawctx, source); drawctx_set_font(drawctx, font); drawctx_print(drawctx, str, x, y); free(str); return ret; } static int draw(void) { source_t background = rgb(255, 255, 255); source_t foreground = rgb(0, 0, 0); source_t glyphs = rgb(0, 0, 255); source_t ascender_bg = rgb(255, 230, 128); source_t ascender_fg = rgb(255, 153, 85); source_t descender_bg = rgb(204, 255, 170); source_t descender_fg = rgb(85, 212, 0); source_t leading_bg = rgb(170, 238, 255); source_t leading_fg = rgb(0, 170, 212); font_t *font; int rc = create_font(&font, points); if (rc != EOK) { printf("Failed creating font\n"); return rc; } font_t *info_font; rc = embedded_font_create(&info_font, 16); if (rc != EOK) { printf("Failed creating info font\n"); return rc; } font_metrics_t font_metrics; rc = font_get_metrics(font, &font_metrics); if (rc != EOK) return rc; surface_coord_t top = 50; metric_t ascender_top = top; metric_t descender_top = ascender_top + font_metrics.ascender; metric_t leading_top = descender_top + font_metrics.descender; metric_t line_bottom = leading_top + font_metrics.leading; drawctx_t drawctx; drawctx_init(&drawctx, surface); drawctx_set_source(&drawctx, &background); drawctx_transfer(&drawctx, 0, 0, width, height); if (show_metrics) { horizontal_rectangle(&drawctx, 0, ascender_top, width, descender_top - 1, &ascender_bg); horizontal_line(&drawctx, ascender_top, 0, width, &ascender_fg); horizontal_rectangle(&drawctx, 0, descender_top, width, leading_top - 1, &descender_bg); horizontal_line(&drawctx, descender_top, 0, width, &descender_fg); horizontal_rectangle(&drawctx, 0, leading_top, width, line_bottom - 1, &leading_bg); horizontal_line(&drawctx, leading_top, 0, width, &leading_fg); } drawctx_set_source(&drawctx, &glyphs); drawctx_set_font(&drawctx, font); drawctx_print(&drawctx, "Čaj'_", 0, top); if (show_metrics) { surface_coord_t infos_top = line_bottom + 10; text(&drawctx, info_font, &ascender_fg, 0, infos_top, "Ascender: %d", font_metrics.ascender); text(&drawctx, info_font, &descender_fg, 0, infos_top + 16, "Descender: %d", font_metrics.descender); text(&drawctx, info_font, &foreground, 0, infos_top + 32, "Line height: %d", font_metrics.ascender + font_metrics.descender); text(&drawctx, info_font, &leading_fg, 0, infos_top + 48, "Leading: %d", font_metrics.leading); } font_release(font); return EOK; } int main(int argc, char *argv[]) { if (argc < 2) { printf("Compositor server not specified.\n"); return 1; } if (argc < 3) { font_path = NULL; } else { font_path = argv[2]; } main_window = window_open(argv[1], NULL, WINDOW_MAIN, "fontviewer"); if (!main_window) { printf("Cannot open main window.\n"); return 2; } surface = surface_create(WINDOW_WIDTH, WINDOW_HEIGHT, NULL, SURFACE_FLAG_NONE); if (surface == NULL) { printf("Cannot create surface.\n"); return 2; } width = WINDOW_WIDTH; height = WINDOW_HEIGHT; int rc = draw(); if (rc != EOK) { printf("Failed drawing: %d.\n", rc); return 2; } canvas = create_canvas(window_root(main_window), NULL, WINDOW_WIDTH, WINDOW_HEIGHT, surface); if (canvas == NULL) { printf("Cannot create canvas.\n"); return 2; } sig_connect(&canvas->keyboard_event, NULL, on_keyboard_event); window_resize(main_window, 200, 200, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_PLACEMENT_ABSOLUTE); window_exec(main_window); task_retval(0); async_manager(); return 0; } /** @} */