source: mainline/uspace/lib/draw/font.c@ 79ea5af

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 79ea5af was 2cc1ec0, checked in by Martin Sucha <sucha14@…>, 11 years ago

Refactor drawing of fonts into multiple layers.

This will need further work to split glyph resolution
process to separate functions in order to support ligatures,
addition of kerning support, separate text layout functions,
etc.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 * Copyright (c) 2012 Petr Koupy
3 * Copyright (c) 2014 Martin Sucha
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup draw
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <malloc.h>
38#include <errno.h>
39#include <str.h>
40
41#include "font.h"
42#include "font/embedded.h"
43#include "drawctx.h"
44
45font_t *font_create(font_backend_t *backend, void *backend_data)
46{
47 font_t *font = malloc(sizeof(font_t));
48 if (font == NULL)
49 return NULL;
50
51 font->backend = backend;
52 font->backend_data = backend_data;
53
54 return font;
55}
56
57void font_release(font_t *font)
58{
59 font->backend->release(font->backend_data);
60}
61
62int font_get_metrics(font_t *font, font_metrics_t *metrics) {
63 return font->backend->get_font_metrics(font->backend_data, metrics);
64}
65
66int font_resolve_glyph(font_t *font, wchar_t c, glyph_id_t *glyph_id) {
67 return font->backend->resolve_glyph(font->backend_data, c, glyph_id);
68}
69
70int font_get_glyph_metrics(font_t *font, glyph_id_t glyph_id,
71 glyph_metrics_t *glyph_metrics)
72{
73 return font->backend->get_glyph_metrics(font->backend_data,
74 glyph_id, glyph_metrics);
75}
76
77int font_render_glyph(font_t *font, drawctx_t *context, source_t *source,
78 sysarg_t x, sysarg_t y, glyph_id_t glyph_id)
79{
80 return font->backend->render_glyph(font->backend_data, context, source,
81 x, y, glyph_id);
82}
83
84/* TODO this is bad interface */
85int font_get_box(font_t *font, char *text, sysarg_t *width, sysarg_t *height)
86{
87 font_metrics_t fm;
88 int rc = font_get_metrics(font, &fm);
89 if (rc != EOK)
90 return rc;
91
92 native_t x = 0;
93
94 size_t off = 0;
95 while (true) {
96 wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
97 if (c == 0)
98 break;
99
100 glyph_id_t glyph_id;
101 rc = font_resolve_glyph(font, c, &glyph_id);
102 if (rc != EOK) {
103 int rc2 = font_resolve_glyph(font, U_SPECIAL, &glyph_id);
104 if (rc2 != EOK) {
105 return rc;
106 }
107 }
108
109 glyph_metrics_t glyph_metrics;
110 rc = font_get_glyph_metrics(font, glyph_id, &glyph_metrics);
111 if (rc != EOK)
112 return rc;
113
114 x += glyph_metrics_get_advancement(&glyph_metrics);
115 }
116
117 *width = x;
118 *height = fm.ascender + fm.descender;
119 return EOK;
120}
121
122/* TODO this is bad interface */
123int font_draw_text(font_t *font, drawctx_t *context, source_t *source,
124 const char *text, sysarg_t sx, sysarg_t sy)
125{
126 drawctx_save(context);
127 drawctx_set_compose(context, compose_over);
128
129 font_metrics_t fm;
130 int rc = font_get_metrics(font, &fm);
131 if (rc != EOK)
132 return rc;
133
134 native_t baseline = sy + fm.ascender;
135 native_t x = sx;
136
137 size_t off = 0;
138 while (true) {
139 wchar_t c = str_decode(text, &off, STR_NO_LIMIT);
140 if (c == 0)
141 break;
142
143 glyph_id_t glyph_id;
144 rc = font_resolve_glyph(font, c, &glyph_id);
145 if (rc != EOK) {
146 int rc2 = font_resolve_glyph(font, U_SPECIAL, &glyph_id);
147 if (rc2 != EOK) {
148 return rc;
149 }
150 }
151
152 glyph_metrics_t glyph_metrics;
153 rc = font_get_glyph_metrics(font, glyph_id, &glyph_metrics);
154 if (rc != EOK)
155 return rc;
156
157 rc = font_render_glyph(font, context, source, x, baseline,
158 glyph_id);
159 if (rc != EOK)
160 return rc;
161
162 x += glyph_metrics_get_advancement(&glyph_metrics);
163
164 }
165
166 drawctx_restore(context);
167 source_set_mask(source, NULL, false);
168
169 return EOK;
170}
171
172/** @}
173 */
Note: See TracBrowser for help on using the repository browser.