source: mainline/uspace/lib/gfxfont/src/glyph_bmp.c@ efca2e4

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

Clear glyph using Ctrl-X

  • Property mode set to 100644
File size: 7.4 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 Glyph bitmap
34 */
35
36#include <errno.h>
37#include <gfx/bitmap.h>
38#include <gfx/coord.h>
39#include <gfx/glyph_bmp.h>
40#include <io/pixelmap.h>
41#include <stdlib.h>
42#include "../private/font.h"
43#include "../private/glyph.h"
44#include "../private/glyph_bmp.h"
45
46static errno_t gfx_glyph_bmp_extend(gfx_glyph_bmp_t *, gfx_coord2_t *);
47
48/** Open glyph bitmap for editing.
49 *
50 * @param glyph Glyph
51 * @param rbmp Place to store glyph bitmap
52 * @return EOK on success, ENOMEM if out of memory
53 */
54errno_t gfx_glyph_bmp_open(gfx_glyph_t *glyph, gfx_glyph_bmp_t **rbmp)
55{
56 gfx_font_t *font = glyph->font;
57 gfx_glyph_bmp_t *bmp;
58 pixelmap_t pmap;
59 gfx_bitmap_alloc_t alloc;
60 gfx_coord_t x, y;
61 pixel_t pixel;
62 errno_t rc;
63
64 bmp = calloc(1, sizeof(gfx_glyph_bmp_t));
65 if (bmp == NULL)
66 return ENOMEM;
67
68 /* Bitmap coordinates are relative to glyph origin point */
69 gfx_rect_rtranslate(&glyph->origin, &glyph->rect, &bmp->rect);
70
71 bmp->pixels = calloc((bmp->rect.p1.x - bmp->rect.p0.x) *
72 (bmp->rect.p1.y - bmp->rect.p0.y), sizeof(int));
73 if (bmp->pixels == NULL) {
74 free(bmp);
75 return ENOMEM;
76 }
77
78 rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
79 if (rc != EOK) {
80 free(bmp->pixels);
81 free(bmp);
82 return rc;
83 }
84
85 assert(font->rect.p0.x == 0);
86 assert(font->rect.p0.y == 0);
87 pmap.width = font->rect.p1.x;
88 pmap.height = font->rect.p1.y;
89 pmap.data = alloc.pixels;
90
91 /* Copy pixels from font bitmap */
92
93 for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
94 for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
95 pixel = pixelmap_get_pixel(&pmap, glyph->origin.x + x,
96 glyph->origin.y + y);
97 bmp->pixels[(y - bmp->rect.p0.y) *
98 (bmp->rect.p1.x - bmp->rect.p0.x) +
99 (x - bmp->rect.p0.x)] = (pixel != 0) ? 1 : 0;
100 }
101 }
102
103 bmp->glyph = glyph;
104 *rbmp = bmp;
105 return EOK;
106}
107
108/** Save glyph bitmap.
109 *
110 * @param bmp Glyph bitmap
111 * @return EOK on success, ENOMEM if out of memory
112 */
113errno_t gfx_glyph_bmp_save(gfx_glyph_bmp_t *bmp)
114{
115 gfx_glyph_t *glyph = bmp->glyph;
116 gfx_font_t *font = glyph->font;
117 gfx_coord_t x, y;
118 pixel_t pixel;
119 pixelmap_t pmap;
120 gfx_bitmap_alloc_t alloc;
121 errno_t rc;
122
123 /*
124 * Replace glyph with empty space in the font bitmap, the width
125 * of the empty equal to new glyph bitmap width. The glyph width
126 * is adjusted.
127 */
128 rc = gfx_font_splice_at_glyph(font, glyph, &bmp->rect);
129 if (rc != EOK)
130 return rc;
131
132 rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
133 if (rc != EOK)
134 return rc;
135
136 assert(font->rect.p0.x == 0);
137 assert(font->rect.p0.y == 0);
138 pmap.width = font->rect.p1.x;
139 pmap.height = font->rect.p1.y;
140 pmap.data = alloc.pixels;
141
142 /* Copy pixels to font bitmap */
143
144 for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
145 for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
146 pixel = bmp->pixels[(y - bmp->rect.p0.y) *
147 (bmp->rect.p1.x - bmp->rect.p0.x) +
148 (x - bmp->rect.p0.x)] ?
149 PIXEL(255, 255, 255, 255) : PIXEL(0, 0, 0, 0);
150 pixelmap_put_pixel(&pmap, glyph->origin.x + x,
151 glyph->origin.y + y, pixel);
152 }
153 }
154
155 return EOK;
156}
157
158/** Close glyph bitmap.
159 *
160 * @param bmp Glyph bitmap
161 */
162void gfx_glyph_bmp_close(gfx_glyph_bmp_t *bmp)
163{
164 free(bmp->pixels);
165 free(bmp);
166}
167
168/** Get rectangle covered by glyph bitmap.
169 *
170 * @param bmp Glyph bitmap
171 * @param rect Place to store rectangle
172 */
173void gfx_glyph_bmp_get_rect(gfx_glyph_bmp_t *bmp, gfx_rect_t *rect)
174{
175 *rect = bmp->rect;
176}
177
178/** Get pixel from glyph bitmap.
179 *
180 * @param bmp Glyph bitmap
181 * @param x X-coordinate
182 * @param y Y-coordinate
183 * @return Pixel value
184 */
185int gfx_glyph_bmp_getpix(gfx_glyph_bmp_t *bmp, gfx_coord_t x, gfx_coord_t y)
186{
187 gfx_coord2_t pos;
188 size_t pitch;
189
190 pos.x = x;
191 pos.y = y;
192 if (!gfx_pix_inside_rect(&pos, &bmp->rect))
193 return 0;
194
195 pitch = bmp->rect.p1.x - bmp->rect.p0.x;
196
197 return bmp->pixels[(y - bmp->rect.p0.y) * pitch +
198 (x - bmp->rect.p0.x)];
199}
200
201/** Set pixel in glyph bitmap.
202 *
203 * @param bmp Glyph bitmap
204 * @param x X-coordinate
205 * @param y Y-coordinate
206 *
207 * @reutrn EOK on success, ENOMEM if out of memory
208 */
209errno_t gfx_glyph_bmp_setpix(gfx_glyph_bmp_t *bmp, gfx_coord_t x,
210 gfx_coord_t y, int value)
211{
212 gfx_coord2_t pos;
213 size_t pitch;
214 errno_t rc;
215
216 pos.x = x;
217 pos.y = y;
218
219 if (!gfx_pix_inside_rect(&pos, &bmp->rect)) {
220 rc = gfx_glyph_bmp_extend(bmp, &pos);
221 if (rc != EOK)
222 return rc;
223 }
224
225 pitch = bmp->rect.p1.x - bmp->rect.p0.x;
226 bmp->pixels[(y - bmp->rect.p0.y) * pitch +
227 (x - bmp->rect.p0.x)] = value;
228 return EOK;
229}
230
231/** Clear glyph bitmap
232 *
233 * @param bmp Glyph bitmap
234 *
235 * @return EOK on sucesss, ENOMEM if out of memory
236 */
237errno_t gfx_glyph_bmp_clear(gfx_glyph_bmp_t *bmp)
238{
239 int *npixels;
240
241 /* Allocate new pixel array */
242 npixels = calloc(sizeof(int), 1);
243 if (npixels == NULL)
244 return ENOMEM;
245
246 /* Switch new and old data */
247 free(bmp->pixels);
248 bmp->pixels = npixels;
249 bmp->rect.p0.x = 0;
250 bmp->rect.p0.y = 0;
251 bmp->rect.p1.x = 0;
252 bmp->rect.p1.y = 0;
253
254 return EOK;
255}
256
257/** Extend glyph bitmap to cover a patricular pixel.
258 *
259 * @param bmp Glyph bitmap
260 * @param pos Pixel position
261 *
262 * @return EOK on sucesss, ENOMEM if out of memory
263 */
264static errno_t gfx_glyph_bmp_extend(gfx_glyph_bmp_t *bmp, gfx_coord2_t *pos)
265{
266 gfx_rect_t prect;
267 gfx_rect_t nrect;
268 int *npixels;
269 size_t npitch;
270 size_t opitch;
271 gfx_coord_t x, y;
272
273 /* Compute new rectangle enveloping current rectangle and new pixel */
274 prect.p0 = *pos;
275 prect.p1.x = prect.p0.x + 1;
276 prect.p1.y = prect.p0.y + 1;
277
278 gfx_rect_envelope(&bmp->rect, &prect, &nrect);
279
280 /* Allocate new pixel array */
281 npixels = calloc(sizeof(int), (nrect.p1.x - nrect.p0.x) *
282 (nrect.p1.y - nrect.p0.y));
283 if (npixels == NULL)
284 return ENOMEM;
285
286 /* Transfer pixel data */
287 opitch = bmp->rect.p1.x - bmp->rect.p0.x;
288 npitch = nrect.p1.x - nrect.p0.x;
289
290 for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
291 for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
292 npixels[(y - nrect.p0.y) * npitch + x - nrect.p0.x] =
293 bmp->pixels[(y - bmp->rect.p0.y) * opitch +
294 x - bmp->rect.p0.x];
295 }
296 }
297
298 /* Switch new and old data */
299 free(bmp->pixels);
300 bmp->pixels = npixels;
301 bmp->rect = nrect;
302
303 return EOK;
304}
305
306/** @}
307 */
Note: See TracBrowser for help on using the repository browser.