source: mainline/uspace/lib/gfxfont/src/typeface.c

Last change on this file was ea459d4, checked in by Jiri Svoboda <jiri@…>, 5 years ago

Reading typeface from TPF file

  • Property mode set to 100644
File size: 6.1 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 Typeface
34 */
35
36#include <adt/list.h>
37#include <assert.h>
38#include <errno.h>
39#include <gfx/bitmap.h>
40#include <gfx/font.h>
41#include <gfx/glyph.h>
42#include <gfx/typeface.h>
43#include <mem.h>
44#include <riff/chunk.h>
45#include <stdlib.h>
46#include "../private/font.h"
47#include "../private/glyph.h"
48#include "../private/tpf_file.h"
49#include "../private/typeface.h"
50
51/** Create typeface in graphics context.
52 *
53 * @param gc Graphic context
54 * @param rtface Place to store pointer to new typeface
55 *
56 * @return EOK on success, EINVAL if parameters are invald,
57 * ENOMEM if insufficient resources, EIO if graphic device connection
58 * was lost
59 */
60errno_t gfx_typeface_create(gfx_context_t *gc, gfx_typeface_t **rtface)
61{
62 gfx_typeface_t *tface;
63
64 tface = calloc(1, sizeof(gfx_typeface_t));
65 if (tface == NULL)
66 return ENOMEM;
67
68 tface->gc = gc;
69 list_initialize(&tface->fonts);
70
71 *rtface = tface;
72 return EOK;
73}
74
75/** Destroy typeface.
76 *
77 * @param tface Typeface
78 */
79void gfx_typeface_destroy(gfx_typeface_t *tface)
80{
81 gfx_font_info_t *finfo;
82
83 if (tface->riffr != NULL)
84 (void) riff_rclose(tface->riffr);
85
86 finfo = gfx_typeface_first_font(tface);
87 while (finfo != NULL) {
88 if (finfo->font != NULL)
89 gfx_font_close(finfo->font);
90 list_remove(&finfo->lfonts);
91 free(finfo);
92
93 finfo = gfx_typeface_first_font(tface);
94 }
95
96 free(tface);
97}
98
99/** Get info on first font in typeface.
100 *
101 * @param tface Typeface
102 * @return First font info or @c NULL if there are none
103 */
104gfx_font_info_t *gfx_typeface_first_font(gfx_typeface_t *tface)
105{
106 link_t *link;
107
108 link = list_first(&tface->fonts);
109 if (link == NULL)
110 return NULL;
111
112 return list_get_instance(link, gfx_font_info_t, lfonts);
113}
114
115/** Get info on next font in typeface.
116 *
117 * @param cur Current font info
118 * @return Next font info in font or @c NULL if @a cur was the last one
119 */
120gfx_font_info_t *gfx_typeface_next_font(gfx_font_info_t *cur)
121{
122 link_t *link;
123
124 link = list_next(&cur->lfonts, &cur->typeface->fonts);
125 if (link == NULL)
126 return NULL;
127
128 return list_get_instance(link, gfx_font_info_t, lfonts);
129}
130
131/** Open typeface from a TPF file.
132 *
133 * @param gc Graphic context
134 * @param fname File name
135 * @param rtface Place to store pointer to open typeface
136 * @return EOK on success or an error code
137 */
138errno_t gfx_typeface_open(gfx_context_t *gc, const char *fname,
139 gfx_typeface_t **rtface)
140{
141 riffr_t *riffr = NULL;
142 gfx_typeface_t *tface = NULL;
143 errno_t rc;
144 riff_rchunk_t riffck;
145 uint32_t format;
146
147 rc = gfx_typeface_create(gc, &tface);
148 if (rc != EOK)
149 goto error;
150
151 rc = riff_ropen(fname, &riffck, &riffr);
152 if (rc != EOK)
153 goto error;
154
155 rc = riff_read_uint32(&riffck, &format);
156 if (rc != EOK)
157 goto error;
158
159 if (format != FORM_TPFC) {
160 rc = ENOTSUP;
161 goto error;
162 }
163
164 while (true) {
165 rc = gfx_font_info_load(tface, &riffck);
166 if (rc == ENOENT)
167 break;
168
169 if (rc != EOK)
170 goto error;
171 }
172
173 rc = riff_rchunk_end(&riffck);
174 if (rc != EOK)
175 goto error;
176
177 tface->riffr = riffr;
178 *rtface = tface;
179 return EOK;
180error:
181 if (riffr != NULL)
182 riff_rclose(riffr);
183 if (tface != NULL)
184 gfx_typeface_destroy(tface);
185 return rc;
186}
187
188/** Make sure all typeface fonts are loaded.
189 *
190 * @param tface Typeface
191 * @return EOK on success or an error code
192 */
193static errno_t gfx_typeface_loadin(gfx_typeface_t *tface)
194{
195 gfx_font_t *font;
196 gfx_font_info_t *finfo;
197 errno_t rc;
198
199 finfo = gfx_typeface_first_font(tface);
200 while (finfo != NULL) {
201 /* Open font to make sure it is loaded */
202 rc = gfx_font_open(finfo, &font);
203 if (rc != EOK)
204 return rc;
205
206 /* Don't need this anymore */
207 (void)font;
208
209 finfo = gfx_typeface_next_font(finfo);
210 }
211
212 return EOK;
213}
214
215/** Save typeface into a TPF file.
216 *
217 * @param tface Typeface
218 * @param fname Destination file name
219 * @return EOK on success or an error code
220 */
221errno_t gfx_typeface_save(gfx_typeface_t *tface, const char *fname)
222{
223 riffw_t *riffw = NULL;
224 errno_t rc;
225 gfx_font_info_t *finfo;
226 riff_wchunk_t riffck;
227
228 /*
229 * Make sure all fonts are loaded before writing (in case
230 * we are writing into our original backing file).
231 */
232 rc = gfx_typeface_loadin(tface);
233 if (rc != EOK)
234 return rc;
235
236 rc = riff_wopen(fname, &riffw);
237 if (rc != EOK)
238 return rc;
239
240 rc = riff_wchunk_start(riffw, CKID_RIFF, &riffck);
241 if (rc != EOK)
242 goto error;
243
244 rc = riff_write_uint32(riffw, FORM_TPFC);
245 if (rc != EOK)
246 goto error;
247
248 finfo = gfx_typeface_first_font(tface);
249 while (finfo != NULL) {
250 /* Save font */
251 rc = gfx_font_save(finfo, riffw);
252 if (rc != EOK)
253 goto error;
254
255 finfo = gfx_typeface_next_font(finfo);
256 }
257
258 rc = riff_wchunk_end(riffw, &riffck);
259 if (rc != EOK)
260 goto error;
261
262 rc = riff_wclose(riffw);
263 if (rc != EOK)
264 return rc;
265
266 return EOK;
267error:
268 if (riffw != NULL)
269 riff_wclose(riffw);
270 return rc;
271}
272
273/** @}
274 */
Note: See TracBrowser for help on using the repository browser.