Changeset 8a9a41e in mainline for uspace/lib/gfxfont/src/text.c
- Timestamp:
- 2021-10-24T08:28:43Z (2 years ago)
- Children:
- fcb4e15
- Parents:
- 2ce943a (diff), cd981f2a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - git-author:
- Erik Kučák <35500848+Riko196@…> (2021-10-24 08:28:43)
- git-committer:
- GitHub <noreply@…> (2021-10-24 08:28:43)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gfxfont/src/text.c
r2ce943a r8a9a41e 1 1 /* 2 * Copyright (c) 202 0Jiri Svoboda2 * Copyright (c) 2021 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 110 110 gfx_bitmap_t *bitmap; 111 111 gfx_bitmap_alloc_t alloc; 112 uint 16_t r, g, b;112 uint8_t attr; 113 113 pixelmap_t pmap; 114 114 gfx_coord_t x; 115 115 pixel_t pixel; 116 char32_t c; 117 size_t off; 116 118 errno_t rc; 117 119 … … 121 123 */ 122 124 123 gfx_color_get_rgb_i16(color, &r, &g, &b); 124 125 /* 126 * We are setting the *background* color, the foreground color 127 * will be set to its complement. 128 */ 129 r = 0xff ^ (r >> 8); 130 g = 0xff ^ (g >> 8); 131 b = 0xff ^ (b >> 8); 125 gfx_color_get_ega(color, &attr); 132 126 133 127 gfx_bitmap_params_init(¶ms); … … 156 150 pmap.data = alloc.pixels; 157 151 152 off = 0; 158 153 for (x = 0; x < params.rect.p1.x; x++) { 159 pixel = PIXEL(str[x], r, g, b); 154 c = str_decode(str, &off, STR_NO_LIMIT); 155 pixel = PIXEL(attr, 156 (c >> 16) & 0xff, 157 (c >> 8) & 0xff, 158 c & 0xff); 160 159 pixelmap_put_pixel(&pmap, x, 0, pixel); 161 160 } … … 167 166 } 168 167 168 /** Get text starting position. 169 * 170 * @param font Font 171 * @param pos Anchor position 172 * @param fmt Text formatting 173 * @param str String 174 * @param spos Place to store starting position 175 */ 176 void gfx_text_start_pos(gfx_font_t *font, gfx_coord2_t *pos, 177 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *spos) 178 { 179 gfx_font_metrics_t fmetrics; 180 gfx_coord_t width; 181 182 *spos = *pos; 183 184 /* Adjust position for horizontal alignment */ 185 if (fmt->halign != gfx_halign_left) { 186 width = gfx_text_width(font, str); 187 switch (fmt->halign) { 188 case gfx_halign_center: 189 spos->x -= width / 2; 190 break; 191 case gfx_halign_right: 192 spos->x -= width; 193 break; 194 default: 195 break; 196 } 197 } 198 199 /* Adjust position for vertical alignment */ 200 gfx_font_get_metrics(font, &fmetrics); 201 202 if (fmt->valign != gfx_valign_baseline) { 203 switch (fmt->valign) { 204 case gfx_valign_top: 205 spos->y += fmetrics.ascent; 206 break; 207 case gfx_valign_center: 208 spos->y += fmetrics.ascent / 2; 209 break; 210 case gfx_valign_bottom: 211 spos->y -= fmetrics.descent + 1; 212 break; 213 default: 214 break; 215 } 216 } 217 } 218 169 219 /** Render text. 170 220 * … … 178 228 gfx_text_fmt_t *fmt, const char *str) 179 229 { 180 gfx_font_metrics_t fmetrics;181 230 gfx_glyph_metrics_t gmetrics; 182 231 size_t stradv; … … 184 233 gfx_glyph_t *glyph; 185 234 gfx_coord2_t cpos; 186 gfx_coord_t width;187 235 errno_t rc; 188 236 189 cpos = *pos; 190 191 /* Adjust position for horizontal alignment */ 192 if (fmt->halign != gfx_halign_left) { 193 width = gfx_text_width(font, str); 194 switch (fmt->halign) { 195 case gfx_halign_center: 196 cpos.x -= width / 2; 197 break; 198 case gfx_halign_right: 199 cpos.x -= width - 1; 200 break; 201 default: 202 break; 203 } 204 } 205 206 /* Adjust position for vertical alignment */ 207 gfx_font_get_metrics(font, &fmetrics); 208 209 if (fmt->valign != gfx_valign_baseline) { 210 switch (fmt->valign) { 211 case gfx_valign_top: 212 cpos.y += fmetrics.ascent; 213 break; 214 case gfx_valign_center: 215 cpos.y += fmetrics.ascent / 2; 216 break; 217 case gfx_valign_bottom: 218 cpos.y -= fmetrics.descent; 219 break; 220 default: 221 break; 222 } 223 } 237 gfx_text_start_pos(font, pos, fmt, str, &cpos); 224 238 225 239 /* Text mode */ … … 252 266 } 253 267 268 /** Find character position in string by X coordinate. 269 * 270 * @param font Font 271 * @param pos Anchor position 272 * @param fmt Text formatting 273 * @param str String 274 * @param fpos Position for which we need to find offset 275 * 276 * @return Byte offset in @a str of character corresponding to position 277 * @a fpos. Note that the position is rounded, that is, 278 * if it is before the center of character A, it will return 279 * offset of A, if it is after the center of A, it will return 280 * offset of the following character. 281 */ 282 size_t gfx_text_find_pos(gfx_font_t *font, gfx_coord2_t *pos, 283 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *fpos) 284 { 285 gfx_glyph_metrics_t gmetrics; 286 size_t stradv; 287 const char *cp; 288 gfx_glyph_t *glyph; 289 gfx_coord2_t cpos; 290 size_t off; 291 size_t strsize; 292 errno_t rc; 293 294 gfx_text_start_pos(font, pos, fmt, str, &cpos); 295 296 /* Text mode */ 297 if ((font->finfo->props.flags & gff_text_mode) != 0) { 298 off = 0; 299 strsize = str_size(str); 300 while (off < strsize) { 301 if (fpos->x <= cpos.x) 302 return off; 303 (void) str_decode(str, &off, strsize); 304 cpos.x++; 305 } 306 307 return off; 308 } 309 310 cp = str; 311 off = 0; 312 while (*cp != '\0') { 313 rc = gfx_font_search_glyph(font, cp, &glyph, &stradv); 314 if (rc != EOK) { 315 ++cp; 316 continue; 317 } 318 319 gfx_glyph_get_metrics(glyph, &gmetrics); 320 321 if (fpos->x < cpos.x + gmetrics.advance / 2) 322 return off; 323 324 cp += stradv; 325 off += stradv; 326 cpos.x += gmetrics.advance; 327 } 328 329 return off; 330 } 331 332 /** Get text continuation parameters. 333 * 334 * Return the anchor position and format needed to continue printing 335 * text after the specified string. It is allowed for the sources 336 * (@a pos, @a fmt) and destinations (@a cpos, @a cfmt) to point 337 * to the same objects, respectively. 338 * 339 * @param font Font 340 * @param pos Anchor position 341 * @param fmt Text formatting 342 * @param str String 343 * @param cpos Place to store anchor position for continuation 344 * @param cfmt Place to store format for continuation 345 */ 346 void gfx_text_cont(gfx_font_t *font, gfx_coord2_t *pos, 347 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *cpos, 348 gfx_text_fmt_t *cfmt) 349 { 350 gfx_coord2_t spos; 351 gfx_text_fmt_t tfmt; 352 353 /* Continuation should start where the current string ends */ 354 gfx_text_start_pos(font, pos, fmt, str, &spos); 355 cpos->x = spos.x + gfx_text_width(font, str); 356 cpos->y = spos.y; 357 358 /* 359 * Formatting is the same, except the text should be aligned 360 * so that it starts at the anchor point. 361 */ 362 tfmt = *fmt; 363 tfmt.halign = gfx_halign_left; 364 tfmt.valign = gfx_valign_baseline; 365 366 *cfmt = tfmt; 367 } 368 369 /** Get text bounding rectangle. 370 * 371 * @param font Font 372 * @param pos Anchor position 373 * @param fmt Text formatting 374 * @param str String 375 * @param rect Place to store bounding rectangle 376 */ 377 void gfx_text_rect(gfx_font_t *font, gfx_coord2_t *pos, 378 gfx_text_fmt_t *fmt, const char *str, gfx_rect_t *rect) 379 { 380 gfx_coord2_t spos; 381 382 gfx_text_start_pos(font, pos, fmt, str, &spos); 383 384 rect->p0.x = spos.x; 385 rect->p0.y = spos.y - font->metrics.ascent; 386 rect->p1.x = spos.x + gfx_text_width(font, str); 387 rect->p1.y = spos.y + font->metrics.descent + 1; 388 } 389 254 390 /** @} 255 391 */
Note:
See TracChangeset
for help on using the changeset viewer.