source: mainline/uspace/lib/gfxfont/src/text.c@ 8bf9058

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8bf9058 was 8bf9058, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Bottom text should be aligned on the descender line

However, we'll leave baseline alignment as an explicit option.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * Copyright (c) 2020 Jiri Svoboda
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 libgfxfont
30 * @{
31 */
32/**
33 * @file Text rendering
34 */
35
36#include <errno.h>
37#include <gfx/font.h>
38#include <gfx/glyph.h>
39#include <gfx/text.h>
40#include <mem.h>
41
42/** Initialize text formatting structure.
43 *
44 * Text formatting structure must always be initialized using this function
45 * first.
46 *
47 * @param fmt Text formatting structure
48 */
49void gfx_text_fmt_init(gfx_text_fmt_t *fmt)
50{
51 memset(fmt, 0, sizeof(gfx_text_fmt_t));
52}
53
54/** Compute text width.
55 *
56 * @param font Font
57 * @param str String
58 * @return Text width
59 */
60gfx_coord_t gfx_text_width(gfx_font_t *font, const char *str)
61{
62 gfx_glyph_metrics_t gmetrics;
63 size_t stradv;
64 const char *cp;
65 gfx_glyph_t *glyph;
66 gfx_coord_t width;
67 errno_t rc;
68
69 width = 0;
70 cp = str;
71 while (*cp != '\0') {
72 rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
73 if (rc != EOK) {
74 ++cp;
75 continue;
76 }
77
78 gfx_glyph_get_metrics(glyph, &gmetrics);
79
80 cp += stradv;
81 width += gmetrics.advance;
82 }
83
84 return width;
85}
86
87/** Render text.
88 *
89 * @param font Font
90 * @param pos Anchor position
91 * @param fmt Text formatting
92 * @param str String
93 * @return EOK on success or an error code
94 */
95errno_t gfx_puttext(gfx_font_t *font, gfx_coord2_t *pos,
96 gfx_text_fmt_t *fmt, const char *str)
97{
98 gfx_font_metrics_t fmetrics;
99 gfx_glyph_metrics_t gmetrics;
100 size_t stradv;
101 const char *cp;
102 gfx_glyph_t *glyph;
103 gfx_coord2_t cpos;
104 gfx_coord_t width;
105 errno_t rc;
106
107 cpos = *pos;
108
109 /* Adjust position for horizontal alignment */
110 if (fmt->halign != gfx_halign_left) {
111 width = gfx_text_width(font, str);
112 switch (fmt->halign) {
113 case gfx_halign_center:
114 cpos.x -= width / 2;
115 break;
116 case gfx_halign_right:
117 cpos.x -= width;
118 break;
119 default:
120 break;
121 }
122 }
123
124 /* Adjust position for vertical alignment */
125 gfx_font_get_metrics(font, &fmetrics);
126
127 if (fmt->valign != gfx_valign_baseline) {
128 switch (fmt->valign) {
129 case gfx_valign_top:
130 cpos.y += fmetrics.ascent;
131 break;
132 case gfx_valign_center:
133 cpos.y += fmetrics.ascent / 2;
134 break;
135 case gfx_valign_bottom:
136 cpos.y -= fmetrics.descent;
137 break;
138 default:
139 break;
140 }
141 }
142
143 cp = str;
144 while (*cp != '\0') {
145 rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
146 if (rc != EOK) {
147 ++cp;
148 continue;
149 }
150
151 gfx_glyph_get_metrics(glyph, &gmetrics);
152
153 rc = gfx_glyph_render(glyph, &cpos);
154 if (rc != EOK)
155 return rc;
156
157 cp += stradv;
158 cpos.x += gmetrics.advance;
159 }
160
161 return EOK;
162}
163
164/** @}
165 */
Note: See TracBrowser for help on using the repository browser.