System/Libraries/(Css,Graphics2D,Html): Support underlined text
This commit adds the necessary functions to minimally implement support for CSS text-decoration: underline.
This commit is contained in:
parent
622c35e038
commit
24500f52a3
4 changed files with 64 additions and 0 deletions
|
@ -1,6 +1,8 @@
|
|||
#define CSS_TEXT_ALIGN_CENTER 1
|
||||
#define CSS_TEXT_ALIGN_RIGHT 2
|
||||
|
||||
#define CSS_TEXT_UNDERLINE 1
|
||||
|
||||
#define CSS_TOKENIZER_STATE_CONSUME_MATCH 0
|
||||
#define CSS_TOKENIZER_STATE_CONSUME_PROPERTY 1
|
||||
#define CSS_TOKENIZER_STATE_CONSUME_VALUE 2
|
||||
|
|
|
@ -1162,6 +1162,24 @@ I64 X2Pos(CDC* src)
|
|||
return -1;
|
||||
}
|
||||
|
||||
I64 Y2Pos(CDC* src)
|
||||
{
|
||||
I64 x = src->width - 1;
|
||||
I64 y = src->height - 1;
|
||||
I64 color;
|
||||
while (y > -1) {
|
||||
x = src->width - 1;
|
||||
while (x > -1) {
|
||||
color = GrPeek(src, x, y);
|
||||
if (color)
|
||||
return y;
|
||||
x--;
|
||||
}
|
||||
y--;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
I64 @get_truetype_text_width(U8* font_name, I64 size, U8* text)
|
||||
{
|
||||
stbtt_fontinfo* font = Fonts->@(font_name);
|
||||
|
@ -1178,6 +1196,26 @@ I64 @get_truetype_text_width(U8* font_name, I64 size, U8* text)
|
|||
return res;
|
||||
}
|
||||
|
||||
I64 @get_truetype_baseline(U8* font_name, I64 size)
|
||||
{
|
||||
stbtt_fontinfo* font = Fonts->@(font_name);
|
||||
if (!font) {
|
||||
return 0;
|
||||
}
|
||||
I64 res = 0;
|
||||
CDC* dc = DCNew(Display.Width() / 2, (size * 2));
|
||||
Free(dc->body);
|
||||
I32 i32char[16];
|
||||
MemSet(&i32char, NULL, 16);
|
||||
i32char[0] = 'o';
|
||||
dc->body = @stbtt_RenderText(font, dc->width_internal, dc->height, ToI64(size * 1.2), &i32char);
|
||||
dc->width -= 16;
|
||||
dc->height -= size / 4;
|
||||
res = Y2Pos(dc);
|
||||
DCDel(dc);
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 Text2D(Context2D* ctx, U8* font_name, I64 x, I64 y, I64 size, U32 color, U8* text)
|
||||
{
|
||||
stbtt_fontinfo* font = Fonts->@(font_name);
|
||||
|
|
|
@ -308,6 +308,7 @@ Bool @apply_css_rules_to_node(@html_dom_node* node, HtmlRenderer* renderer)
|
|||
node->fontSize = node->parentNode->fontSize;
|
||||
node->fontWeight = node->parentNode->fontWeight;
|
||||
node->textAlign = node->parentNode->textAlign;
|
||||
node->textDecoration = node->parentNode->textDecoration;
|
||||
node->italic = node->parentNode->italic;
|
||||
}
|
||||
|
||||
|
@ -425,6 +426,15 @@ Bool @apply_css_rules_to_node(@html_dom_node* node, HtmlRenderer* renderer)
|
|||
if (!StrICmp(key->name, "text-align") && !StrICmp(values->@(0), "right"))
|
||||
node->textAlign = CSS_TEXT_ALIGN_RIGHT;
|
||||
|
||||
if (!StrICmp(key->name, "text-decoration")) {
|
||||
if (!StrICmp(values->@(0), "none")) {
|
||||
node->textDecoration = 0;
|
||||
}
|
||||
if (!StrICmp(values->@(0), "underline")) {
|
||||
node->textDecoration = CSS_TEXT_UNDERLINE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!StrICmp(key->name, "line-height") && !StrICmp(values->@(0) + StrLen(values->@(0)) - 2, "px")) {
|
||||
StrCpy(node_tmpnum_buf, values->@(0));
|
||||
node_tmpnum_buf[StrLen(node_tmpnum_buf) - 2] = NULL;
|
||||
|
@ -849,6 +859,7 @@ U0 @render_node_text(@html_dom_node* node, HtmlRenderer* renderer)
|
|||
|
||||
U32 fragment_bounding_box_color = Color(0x00, 0xff, 0x00);
|
||||
U8* font_name = @resolved_font_name_for_node(node->parentNode);
|
||||
I64 underline_y_pos = -1;
|
||||
|
||||
for (i = 0; i < fragment_count; i++) {
|
||||
if (fragments[i] && *fragments[i]) {
|
||||
|
@ -860,6 +871,18 @@ U0 @render_node_text(@html_dom_node* node, HtmlRenderer* renderer)
|
|||
fragment_widget->data = node;
|
||||
fragment_widget->ctx = NewContext2D(text_width, ToI64(node->parentNode->fontSize * 1.2))->fill(node->parentNode->backgroundColor)->text(font_name, 0, 0, node->parentNode->fontSize, node->parentNode->color, fragments[i]);
|
||||
|
||||
switch (node->parentNode->textDecoration) {
|
||||
case CSS_TEXT_UNDERLINE:
|
||||
if (underline_y_pos < 0)
|
||||
underline_y_pos = @get_truetype_baseline(font_name, node->parentNode->fontSize) + 2;
|
||||
if (!(underline_y_pos < 0)) {
|
||||
fragment_widget->ctx->line(0, underline_y_pos, fragment_widget->ctx->width, underline_y_pos, node->parentNode->color);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (renderer->debug && fragment_widget->ctx) {
|
||||
fragment_widget->ctx->line(0, 0, fragment_widget->ctx->width - 1, 0, fragment_bounding_box_color);
|
||||
fragment_widget->ctx->line(0, fragment_widget->ctx->height - 1, fragment_widget->ctx->width - 1, fragment_widget->ctx->height - 1, fragment_bounding_box_color);
|
||||
|
|
|
@ -97,6 +97,7 @@ class @html_dom_node : JsonElement
|
|||
U8* fontFamily;
|
||||
I64 fontSize;
|
||||
I64 fontWeight;
|
||||
I64 textDecoration;
|
||||
Bool italic;
|
||||
Bool display_block;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue