Changes in uspace/lib/gfxfont/src/text.c [a0aeb8f:f2d4a46] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gfxfont/src/text.c
ra0aeb8f rf2d4a46 1 1 /* 2 * Copyright (c) 202 1Jiri Svoboda2 * Copyright (c) 2022 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 97 97 /** Print string using text characters in text mode. 98 98 * 99 * @param font Font100 99 * @param pos Position of top-left corner of text 101 * @param color Text color100 * @param fmt Formatting 102 101 * @param str String 103 102 * @return EOK on success or an error code 104 103 */ 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 = f ont->typeface->gc;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 = fmt->font->typeface->gc; 109 108 gfx_bitmap_params_t params; 110 109 gfx_bitmap_t *bitmap; 111 110 gfx_bitmap_alloc_t alloc; 111 gfx_coord_t width; 112 112 uint8_t attr; 113 113 pixelmap_t pmap; 114 114 gfx_coord_t x; 115 gfx_coord_t rmargin; 115 116 pixel_t pixel; 116 117 char32_t c; 117 118 size_t off; 119 bool ellipsis; 118 120 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 else 129 rmargin = width; 130 } else { 131 ellipsis = false; 132 rmargin = width; 133 } 119 134 120 135 /* … … 123 138 */ 124 139 125 gfx_color_get_ega( color, &attr);140 gfx_color_get_ega(fmt->color, &attr); 126 141 127 142 gfx_bitmap_params_init(¶ms); 128 143 params.rect.p0.x = 0; 129 144 params.rect.p0.y = 0; 130 params.rect.p1.x = str_width(str);145 params.rect.p1.x = width; 131 146 params.rect.p1.y = 1; 132 147 … … 151 166 152 167 off = 0; 153 for (x = 0; x < params.rect.p1.x; x++) {168 for (x = 0; x < rmargin; x++) { 154 169 c = str_decode(str, &off, STR_NO_LIMIT); 155 170 pixel = PIXEL(attr, … … 160 175 } 161 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 } 187 162 188 rc = gfx_bitmap_render(bitmap, NULL, pos); 163 189 … … 168 194 /** Get text starting position. 169 195 * 170 * @param font Font171 196 * @param pos Anchor position 172 197 * @param fmt Text formatting … … 174 199 * @param spos Place to store starting position 175 200 */ 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)201 void gfx_text_start_pos(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, 202 const char *str, gfx_coord2_t *spos) 178 203 { 179 204 gfx_font_metrics_t fmetrics; … … 184 209 /* Adjust position for horizontal alignment */ 185 210 if (fmt->halign != gfx_halign_left) { 186 width = gfx_text_width(font, str); 211 /* Compute text width */ 212 width = gfx_text_width(fmt->font, str); 213 if (fmt->abbreviate && width > fmt->width) 214 width = fmt->width; 215 187 216 switch (fmt->halign) { 188 217 case gfx_halign_center: … … 198 227 199 228 /* Adjust position for vertical alignment */ 200 gfx_font_get_metrics(f ont, &fmetrics);229 gfx_font_get_metrics(fmt->font, &fmetrics); 201 230 202 231 if (fmt->valign != gfx_valign_baseline) { … … 219 248 /** Render text. 220 249 * 221 * @param font Font222 250 * @param pos Anchor position 223 251 * @param fmt Text formatting … … 225 253 * @return EOK on success or an error code 226 254 */ 227 errno_t gfx_puttext(gfx_font_t *font, gfx_coord2_t *pos, 228 gfx_text_fmt_t *fmt, const char *str) 255 errno_t gfx_puttext(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str) 229 256 { 230 257 gfx_glyph_metrics_t gmetrics; 258 gfx_font_metrics_t fmetrics; 231 259 size_t stradv; 232 260 const char *cp; 233 261 gfx_glyph_t *glyph; 234 262 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; 235 268 errno_t rc; 236 269 237 gfx_text_start_pos( font, pos, fmt, str, &cpos);270 gfx_text_start_pos(pos, fmt, str, &spos); 238 271 239 272 /* Text mode */ 240 if ((f ont->finfo->props.flags & gff_text_mode) != 0)241 return gfx_puttext_textmode( font, &cpos, fmt->color, str);242 243 rc = gfx_set_color(f ont->typeface->gc, fmt->color);273 if ((fmt->font->finfo->props.flags & gff_text_mode) != 0) 274 return gfx_puttext_textmode(&spos, fmt, str); 275 276 rc = gfx_set_color(fmt->font->typeface->gc, fmt->color); 244 277 if (rc != EOK) 245 278 return rc; 246 279 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; 247 292 cp = str; 248 293 while (*cp != '\0') { 249 rc = gfx_font_search_glyph(f ont, cp, &glyph, &stradv);294 rc = gfx_font_search_glyph(fmt->font, cp, &glyph, &stradv); 250 295 if (rc != EOK) { 251 296 ++cp; … … 255 300 gfx_glyph_get_metrics(glyph, &gmetrics); 256 301 302 /* Stop if we would run over the right margin */ 303 if (fmt->abbreviate && cpos.x + gmetrics.advance > rmargin) 304 break; 305 257 306 rc = gfx_glyph_render(glyph, &cpos); 258 307 if (rc != EOK) … … 263 312 } 264 313 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 265 353 return EOK; 266 354 } … … 268 356 /** Find character position in string by X coordinate. 269 357 * 270 * @param font Font271 358 * @param pos Anchor position 272 359 * @param fmt Text formatting … … 280 367 * offset of the following character. 281 368 */ 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)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 371 { 285 372 gfx_glyph_metrics_t gmetrics; … … 292 379 errno_t rc; 293 380 294 gfx_text_start_pos( font,pos, fmt, str, &cpos);381 gfx_text_start_pos(pos, fmt, str, &cpos); 295 382 296 383 /* Text mode */ 297 if ((f ont->finfo->props.flags & gff_text_mode) != 0) {384 if ((fmt->font->finfo->props.flags & gff_text_mode) != 0) { 298 385 off = 0; 299 386 strsize = str_size(str); … … 311 398 off = 0; 312 399 while (*cp != '\0') { 313 rc = gfx_font_search_glyph(f ont, cp, &glyph, &stradv);400 rc = gfx_font_search_glyph(fmt->font, cp, &glyph, &stradv); 314 401 if (rc != EOK) { 315 402 ++cp; … … 337 424 * to the same objects, respectively. 338 425 * 339 * @param font Font340 426 * @param pos Anchor position 341 427 * @param fmt Text formatting … … 344 430 * @param cfmt Place to store format for continuation 345 431 */ 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) 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) 349 434 { 350 435 gfx_coord2_t spos; … … 352 437 353 438 /* 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(f ont, str);439 gfx_text_start_pos(pos, fmt, str, &spos); 440 cpos->x = spos.x + gfx_text_width(fmt->font, str); 356 441 cpos->y = spos.y; 357 442 … … 364 449 tfmt.valign = gfx_valign_baseline; 365 450 451 /* Remaining available width */ 452 tfmt.width = fmt->width - (cpos->x - spos.x); 453 366 454 *cfmt = tfmt; 367 455 } … … 369 457 /** Get text bounding rectangle. 370 458 * 371 * @param font Font372 459 * @param pos Anchor position 373 460 * @param fmt Text formatting … … 375 462 * @param rect Place to store bounding rectangle 376 463 */ 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)464 void gfx_text_rect(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str, 465 gfx_rect_t *rect) 379 466 { 380 467 gfx_coord2_t spos; 381 382 gfx_text_start_pos(font, pos, fmt, str, &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 474 384 475 rect->p0.x = spos.x; 385 rect->p0.y = spos.y - f ont->metrics.ascent;386 rect->p1.x = spos.x + gfx_text_width(font, str);387 rect->p1.y = spos.y + font->metrics.descent + 1;476 rect->p0.y = spos.y - fmt->font->metrics.ascent; 477 rect->p1.x = spos.x + width; 478 rect->p1.y = spos.y + fmt->font->metrics.descent + 1; 388 479 } 389 480
Note:
See TracChangeset
for help on using the changeset viewer.