Changes in uspace/lib/gfxfont/src/text.c [f2d4a46:9eb8d12] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gfxfont/src/text.c
rf2d4a46 r9eb8d12 1 1 /* 2 * Copyright (c) 202 2Jiri Svoboda2 * Copyright (c) 2021 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 97 97 /** Print string using text characters in text mode. 98 98 * 99 * @param font Font 99 100 * @param pos Position of top-left corner of text 100 * @param fmt Formatting101 * @param color Text color 101 102 * @param str String 102 103 * @return EOK on success or an error code 103 104 */ 104 static errno_t gfx_puttext_textmode(gfx_ coord2_t *pos, gfx_text_fmt_t *fmt,105 const char *str)106 { 107 gfx_context_t *gc = f mt->font->typeface->gc;105 static errno_t gfx_puttext_textmode(gfx_font_t *font, gfx_coord2_t *pos, 106 gfx_color_t *color, const char *str) 107 { 108 gfx_context_t *gc = font->typeface->gc; 108 109 gfx_bitmap_params_t params; 109 110 gfx_bitmap_t *bitmap; 110 111 gfx_bitmap_alloc_t alloc; 111 gfx_coord_t width; 112 uint8_t attr; 112 uint16_t r, g, b; 113 113 pixelmap_t pmap; 114 114 gfx_coord_t x; 115 gfx_coord_t rmargin;116 115 pixel_t pixel; 117 char32_t c;118 size_t off;119 bool ellipsis;120 116 errno_t rc; 121 122 width = str_width(str);123 if (fmt->abbreviate && width > fmt->width) {124 ellipsis = true;125 width = fmt->width;126 if (width > 3)127 rmargin = width - 3;128 else129 rmargin = width;130 } else {131 ellipsis = false;132 rmargin = width;133 }134 117 135 118 /* … … 138 121 */ 139 122 140 gfx_color_get_ega(fmt->color, &attr); 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); 141 132 142 133 gfx_bitmap_params_init(¶ms); 143 134 params.rect.p0.x = 0; 144 135 params.rect.p0.y = 0; 145 params.rect.p1.x = width;136 params.rect.p1.x = str_width(str); 146 137 params.rect.p1.y = 1; 147 138 … … 165 156 pmap.data = alloc.pixels; 166 157 167 off = 0; 168 for (x = 0; x < rmargin; x++) { 169 c = str_decode(str, &off, STR_NO_LIMIT); 170 pixel = PIXEL(attr, 171 (c >> 16) & 0xff, 172 (c >> 8) & 0xff, 173 c & 0xff); 158 for (x = 0; x < params.rect.p1.x; x++) { 159 pixel = PIXEL(str[x], r, g, b); 174 160 pixelmap_put_pixel(&pmap, x, 0, pixel); 175 }176 177 if (ellipsis) {178 for (x = rmargin; x < params.rect.p1.x; x++) {179 c = '.';180 pixel = PIXEL(attr,181 (c >> 16) & 0xff,182 (c >> 8) & 0xff,183 c & 0xff);184 pixelmap_put_pixel(&pmap, x, 0, pixel);185 }186 161 } 187 162 … … 194 169 /** Get text starting position. 195 170 * 171 * @param font Font 196 172 * @param pos Anchor position 197 173 * @param fmt Text formatting … … 199 175 * @param spos Place to store starting position 200 176 */ 201 void gfx_text_start_pos(gfx_ coord2_t *pos, gfx_text_fmt_t *fmt,202 const char *str, gfx_coord2_t *spos)177 void gfx_text_start_pos(gfx_font_t *font, gfx_coord2_t *pos, 178 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *spos) 203 179 { 204 180 gfx_font_metrics_t fmetrics; 181 gfx_coord2_t cpos; 205 182 gfx_coord_t width; 206 183 … … 209 186 /* Adjust position for horizontal alignment */ 210 187 if (fmt->halign != gfx_halign_left) { 211 /* Compute text width */ 212 width = gfx_text_width(fmt->font, str); 213 if (fmt->abbreviate && width > fmt->width) 214 width = fmt->width; 215 188 width = gfx_text_width(font, str); 216 189 switch (fmt->halign) { 217 190 case gfx_halign_center: … … 219 192 break; 220 193 case gfx_halign_right: 221 spos->x -= width ;194 spos->x -= width - 1; 222 195 break; 223 196 default: … … 227 200 228 201 /* Adjust position for vertical alignment */ 229 gfx_font_get_metrics(f mt->font, &fmetrics);202 gfx_font_get_metrics(font, &fmetrics); 230 203 231 204 if (fmt->valign != gfx_valign_baseline) { … … 238 211 break; 239 212 case gfx_valign_bottom: 240 spos->y -= fmetrics.descent + 1;213 cpos.y -= fmetrics.descent; 241 214 break; 242 215 default: … … 248 221 /** Render text. 249 222 * 223 * @param font Font 250 224 * @param pos Anchor position 251 225 * @param fmt Text formatting … … 253 227 * @return EOK on success or an error code 254 228 */ 255 errno_t gfx_puttext(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str) 229 errno_t gfx_puttext(gfx_font_t *font, gfx_coord2_t *pos, 230 gfx_text_fmt_t *fmt, const char *str) 256 231 { 257 232 gfx_glyph_metrics_t gmetrics; 258 gfx_font_metrics_t fmetrics;259 233 size_t stradv; 260 234 const char *cp; 261 235 gfx_glyph_t *glyph; 262 236 gfx_coord2_t cpos; 263 gfx_coord2_t spos;264 gfx_rect_t rect;265 gfx_coord_t width;266 gfx_coord_t rmargin;267 bool ellipsis;268 237 errno_t rc; 269 238 270 gfx_text_start_pos( pos, fmt, str, &spos);239 gfx_text_start_pos(font, pos, fmt, str, &cpos); 271 240 272 241 /* Text mode */ 273 if ((f mt->font->finfo->props.flags & gff_text_mode) != 0)274 return gfx_puttext_textmode( &spos, fmt, str);275 276 rc = gfx_set_color(f mt->font->typeface->gc, fmt->color);242 if ((font->finfo->props.flags & gff_text_mode) != 0) 243 return gfx_puttext_textmode(font, &cpos, fmt->color, str); 244 245 rc = gfx_set_color(font->typeface->gc, fmt->color); 277 246 if (rc != EOK) 278 247 return rc; 279 248 280 width = gfx_text_width(fmt->font, str);281 282 if (fmt->abbreviate && width > fmt->width) {283 /* Need to append ellipsis */284 ellipsis = true;285 rmargin = spos.x + fmt->width - gfx_text_width(fmt->font, "...");286 } else {287 ellipsis = false;288 rmargin = spos.x + width;289 }290 291 cpos = spos;292 249 cp = str; 293 250 while (*cp != '\0') { 294 rc = gfx_font_search_glyph(f mt->font, cp, &glyph, &stradv);251 rc = gfx_font_search_glyph(font, cp, &glyph, &stradv); 295 252 if (rc != EOK) { 296 253 ++cp; … … 300 257 gfx_glyph_get_metrics(glyph, &gmetrics); 301 258 302 /* Stop if we would run over the right margin */303 if (fmt->abbreviate && cpos.x + gmetrics.advance > rmargin)304 break;305 306 259 rc = gfx_glyph_render(glyph, &cpos); 307 260 if (rc != EOK) … … 312 265 } 313 266 314 /* Text underlining */315 if (fmt->underline) {316 gfx_font_get_metrics(fmt->font, &fmetrics);317 318 rect.p0.x = spos.x;319 rect.p0.y = spos.y + fmetrics.underline_y0;320 rect.p1.x = cpos.x;321 rect.p1.y = spos.y + fmetrics.underline_y1;322 323 rc = gfx_fill_rect(fmt->font->typeface->gc, &rect);324 if (rc != EOK)325 return rc;326 }327 328 /* Render ellipsis, if required */329 if (ellipsis) {330 rc = gfx_font_search_glyph(fmt->font, ".", &glyph, &stradv);331 if (rc != EOK)332 return EOK;333 334 gfx_glyph_get_metrics(glyph, &gmetrics);335 336 rc = gfx_glyph_render(glyph, &cpos);337 if (rc != EOK)338 return rc;339 340 cpos.x += gmetrics.advance;341 342 rc = gfx_glyph_render(glyph, &cpos);343 if (rc != EOK)344 return rc;345 346 cpos.x += gmetrics.advance;347 348 rc = gfx_glyph_render(glyph, &cpos);349 if (rc != EOK)350 return rc;351 }352 353 267 return EOK; 354 268 } … … 356 270 /** Find character position in string by X coordinate. 357 271 * 272 * @param font Font 358 273 * @param pos Anchor position 359 274 * @param fmt Text formatting … … 367 282 * offset of the following character. 368 283 */ 369 size_t gfx_text_find_pos(gfx_ coord2_t *pos, gfx_text_fmt_t *fmt,370 const char *str, gfx_coord2_t *fpos)284 size_t gfx_text_find_pos(gfx_font_t *font, gfx_coord2_t *pos, 285 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *fpos) 371 286 { 372 287 gfx_glyph_metrics_t gmetrics; … … 379 294 errno_t rc; 380 295 381 gfx_text_start_pos( pos, fmt, str, &cpos);296 gfx_text_start_pos(font, pos, fmt, str, &cpos); 382 297 383 298 /* Text mode */ 384 if ((f mt->font->finfo->props.flags & gff_text_mode) != 0) {299 if ((font->finfo->props.flags & gff_text_mode) != 0) { 385 300 off = 0; 386 301 strsize = str_size(str); … … 398 313 off = 0; 399 314 while (*cp != '\0') { 400 rc = gfx_font_search_glyph(f mt->font, cp, &glyph, &stradv);315 rc = gfx_font_search_glyph(font, cp, &glyph, &stradv); 401 316 if (rc != EOK) { 402 317 ++cp; … … 424 339 * to the same objects, respectively. 425 340 * 341 * @param font Font 426 342 * @param pos Anchor position 427 343 * @param fmt Text formatting … … 430 346 * @param cfmt Place to store format for continuation 431 347 */ 432 void gfx_text_cont(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str, 433 gfx_coord2_t *cpos, gfx_text_fmt_t *cfmt) 348 void gfx_text_cont(gfx_font_t *font, gfx_coord2_t *pos, 349 gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *cpos, 350 gfx_text_fmt_t *cfmt) 434 351 { 435 352 gfx_coord2_t spos; … … 437 354 438 355 /* Continuation should start where the current string ends */ 439 gfx_text_start_pos( pos, fmt, str, &spos);440 cpos->x = spos.x + gfx_text_width(f mt->font, str);356 gfx_text_start_pos(font, pos, fmt, str, &spos); 357 cpos->x = spos.x + gfx_text_width(font, str); 441 358 cpos->y = spos.y; 442 359 … … 449 366 tfmt.valign = gfx_valign_baseline; 450 367 451 /* Remaining available width */452 tfmt.width = fmt->width - (cpos->x - spos.x);453 454 368 *cfmt = tfmt; 455 369 } … … 457 371 /** Get text bounding rectangle. 458 372 * 373 * @param font Font 459 374 * @param pos Anchor position 460 375 * @param fmt Text formatting … … 462 377 * @param rect Place to store bounding rectangle 463 378 */ 464 void gfx_text_rect(gfx_ coord2_t *pos, gfx_text_fmt_t *fmt, const char *str,465 gfx_ rect_t *rect)379 void gfx_text_rect(gfx_font_t *font, gfx_coord2_t *pos, 380 gfx_text_fmt_t *fmt, const char *str, gfx_rect_t *rect) 466 381 { 467 382 gfx_coord2_t spos; 468 gfx_coord_t width; 469 470 gfx_text_start_pos(pos, fmt, str, &spos); 471 width = gfx_text_width(fmt->font, str); 472 if (fmt->abbreviate && width > fmt->width) 473 width = fmt->width; 383 384 gfx_text_start_pos(font, pos, fmt, str, &spos); 474 385 475 386 rect->p0.x = spos.x; 476 rect->p0.y = spos.y - f mt->font->metrics.ascent;477 rect->p1.x = spos.x + width;478 rect->p1.y = spos.y + fmt->font->metrics.descent + 1;387 rect->p0.y = spos.y - font->metrics.ascent; 388 rect->p1.x = spos.x + gfx_text_width(font, str); 389 rect->p1.y = spos.y + font->metrics.descent + 1; 479 390 } 480 391
Note:
See TracChangeset
for help on using the changeset viewer.