source: mainline/uspace/app/fontviewer/fontviewer.c@ 2db5c83

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2db5c83 was 2bb6d04, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 6 years ago

Curb the proliferation of libdraw headers

libdraw provides a lot of ambiguously named headers, which makes it
confusing. This change merges the subdirectories into single headers,
and moves all headers into draw subdirectory, so that it's obvious
at a glance what library the header belongs to.

Compare:

#include <path.h>
#include <source.h>
#include <font/bitmap_backend.h>
#include <font/pcf.h>

vs.

#include <draw/path.h>
#include <draw/source.h>
#include <draw/font.h>

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Copyright (c) 2014 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fontviewer
30 * @{
31 */
32/** @file
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <errno.h>
38#include <stdlib.h>
39#include <stdbool.h>
40#include <str_error.h>
41#include <window.h>
42#include <canvas.h>
43#include <draw/surface.h>
44#include <draw/codec.h>
45#include <task.h>
46#include <draw/drawctx.h>
47#include <draw/font.h>
48#include <stdarg.h>
49#include <io/verify.h>
50
51#define NAME "fontviewer"
52
53#define WINDOW_WIDTH 640
54#define WINDOW_HEIGHT 480
55
56static window_t *main_window;
57static surface_t *surface = NULL;
58static canvas_t *canvas = NULL;
59static surface_coord_t width, height;
60uint16_t points = 16;
61bool show_metrics = true;
62char *font_path = NULL;
63
64static errno_t draw(void);
65
66static void on_keyboard_event(widget_t *widget, void *data)
67{
68 kbd_event_t *event = (kbd_event_t *) data;
69
70 if (event->type == KEY_PRESS) {
71 if (event->c == 'q')
72 exit(0);
73
74 if (event->key == KC_UP || event->key == KC_DOWN) {
75 uint16_t increment = (event->mods & KM_SHIFT) ? 10 : 1;
76
77 if (event->key == KC_UP)
78 points += increment;
79
80 if (event->key == KC_DOWN) {
81 if (points <= increment) {
82 points = 1;
83 } else {
84 points -= increment;
85 }
86 }
87
88 if (points < 1)
89 points = 1;
90 }
91
92 if (event->c == 'm')
93 show_metrics = !show_metrics;
94 }
95
96 errno_t rc = draw();
97 if (rc != EOK) {
98 printf("Failed drawing: %s.\n", str_error(rc));
99 exit(1);
100 }
101 update_canvas(canvas, surface);
102}
103
104static errno_t create_font(font_t **font, uint16_t points)
105{
106 if (font_path == NULL) {
107 return embedded_font_create(font, points);
108 }
109
110 return pcf_font_create(font, font_path, points);
111}
112
113static source_t rgb(uint8_t r, uint8_t g, uint8_t b)
114{
115 source_t source;
116 source_init(&source);
117 source_set_color(&source, PIXEL(255, r, g, b));
118 return source;
119}
120
121static void horizontal_rectangle(drawctx_t *drawctx, surface_coord_t x1,
122 surface_coord_t y1, surface_coord_t x2, surface_coord_t y2,
123 source_t *source)
124{
125 if (y2 < y1)
126 return;
127
128 drawctx_set_source(drawctx, source);
129 drawctx_transfer(drawctx, x1, y1, x2 - x1 + 1, y2 - y1 + 1);
130}
131
132static void horizontal_line(drawctx_t *drawctx, surface_coord_t y,
133 surface_coord_t x1, surface_coord_t x2, source_t *source)
134{
135 horizontal_rectangle(drawctx, x1, y, x2, y, source);
136}
137
138static int text(drawctx_t *, font_t *, source_t *, surface_coord_t x,
139 surface_coord_t, const char *, ...) _HELENOS_PRINTF_ATTRIBUTE(6, 7);
140static int text(drawctx_t *drawctx, font_t *font, source_t *source,
141 surface_coord_t x, surface_coord_t y, const char *fmt, ...)
142{
143 char *str = NULL;
144 va_list args;
145 va_start(args, fmt);
146 int ret = vasprintf(&str, fmt, args);
147 va_end(args);
148
149 if (ret >= 0) {
150 drawctx_set_source(drawctx, source);
151 drawctx_set_font(drawctx, font);
152 drawctx_print(drawctx, str, x, y);
153
154 free(str);
155 }
156
157 return ret;
158}
159
160static errno_t draw(void)
161{
162 source_t background = rgb(255, 255, 255);
163 source_t foreground = rgb(0, 0, 0);
164 source_t glyphs = rgb(0, 0, 255);
165 source_t ascender_bg = rgb(255, 230, 128);
166 source_t ascender_fg = rgb(255, 153, 85);
167 source_t descender_bg = rgb(204, 255, 170);
168 source_t descender_fg = rgb(85, 212, 0);
169 source_t leading_bg = rgb(170, 238, 255);
170 source_t leading_fg = rgb(0, 170, 212);
171 font_t *info_font = NULL;
172 font_t *font = NULL;
173
174 errno_t rc = create_font(&font, points);
175 if (rc != EOK) {
176 printf("Failed creating font\n");
177 goto out_err;
178 }
179
180 rc = embedded_font_create(&info_font, 16);
181 if (rc != EOK) {
182 printf("Failed creating info font\n");
183 goto out_err;
184 }
185
186 font_metrics_t font_metrics;
187 rc = font_get_metrics(font, &font_metrics);
188 if (rc != EOK)
189 goto out_err;
190
191 surface_coord_t top = 50;
192 metric_t ascender_top = top;
193 metric_t descender_top = ascender_top + font_metrics.ascender;
194 metric_t leading_top = descender_top + font_metrics.descender;
195 metric_t line_bottom = leading_top + font_metrics.leading;
196
197 drawctx_t drawctx;
198 drawctx_init(&drawctx, surface);
199
200 drawctx_set_source(&drawctx, &background);
201 drawctx_transfer(&drawctx, 0, 0,
202 width, height);
203
204 if (show_metrics) {
205 horizontal_rectangle(&drawctx, 0, ascender_top, width,
206 descender_top - 1, &ascender_bg);
207 horizontal_line(&drawctx, ascender_top, 0, width,
208 &ascender_fg);
209
210 horizontal_rectangle(&drawctx, 0, descender_top, width,
211 leading_top - 1, &descender_bg);
212 horizontal_line(&drawctx, descender_top, 0, width,
213 &descender_fg);
214
215 horizontal_rectangle(&drawctx, 0, leading_top,
216 width, line_bottom - 1, &leading_bg);
217 horizontal_line(&drawctx, leading_top, 0, width,
218 &leading_fg);
219 }
220
221 drawctx_set_source(&drawctx, &glyphs);
222 drawctx_set_font(&drawctx, font);
223 drawctx_print(&drawctx, "Čaj'_", 0, top);
224
225 if (show_metrics) {
226 surface_coord_t infos_top = line_bottom + 10;
227 text(&drawctx, info_font, &ascender_fg, 0, infos_top,
228 "Ascender: %d", font_metrics.ascender);
229 text(&drawctx, info_font, &descender_fg, 0, infos_top + 16,
230 "Descender: %d", font_metrics.descender);
231 text(&drawctx, info_font, &foreground, 0, infos_top + 32,
232 "Line height: %d",
233 font_metrics.ascender + font_metrics.descender);
234 text(&drawctx, info_font, &leading_fg, 0, infos_top + 48,
235 "Leading: %d", font_metrics.leading);
236
237 }
238
239out_err:
240 if (font)
241 font_release(font);
242 if (info_font)
243 font_release(info_font);
244 return rc;
245}
246
247int main(int argc, char *argv[])
248{
249 if (argc < 2) {
250 printf("Compositor server not specified.\n");
251 return 1;
252 }
253
254 if (argc < 3) {
255 font_path = NULL;
256 } else {
257 font_path = argv[2];
258 }
259
260 main_window = window_open(argv[1], NULL, WINDOW_MAIN, "fontviewer");
261 if (!main_window) {
262 printf("Cannot open main window.\n");
263 return 2;
264 }
265
266 surface = surface_create(WINDOW_WIDTH, WINDOW_HEIGHT, NULL,
267 SURFACE_FLAG_NONE);
268 if (surface == NULL) {
269 printf("Cannot create surface.\n");
270 return 2;
271 }
272
273 width = WINDOW_WIDTH;
274 height = WINDOW_HEIGHT;
275
276 errno_t rc = draw();
277 if (rc != EOK) {
278 printf("Failed drawing: %s.\n", str_error(rc));
279 return 2;
280 }
281
282 canvas = create_canvas(window_root(main_window), NULL,
283 WINDOW_WIDTH, WINDOW_HEIGHT, surface);
284 if (canvas == NULL) {
285 printf("Cannot create canvas.\n");
286 return 2;
287 }
288 sig_connect(&canvas->keyboard_event, NULL, on_keyboard_event);
289
290 window_resize(main_window, 200, 200, WINDOW_WIDTH, WINDOW_HEIGHT,
291 WINDOW_PLACEMENT_ABSOLUTE);
292 window_exec(main_window);
293
294 task_retval(0);
295 async_manager();
296
297 return 0;
298}
299
300/** @}
301 */
Note: See TracBrowser for help on using the repository browser.