📄 text.c
字号:
ft_r->set_font_size(ft_r, fontSize); ft_r->get_font_metrics(ft_r, &st->ascent, &st->descent, &font_height); st->bounds.width = st->bounds.height = 0; for (i=0; i < txt->string.count; i++) { char *str = txt->string.vals[i]; if (!str) continue; len = gf_utf8_mbstowcs(wcTemp, 5000, (const char **) &str); if (len == (size_t) (-1)) continue; first_char = 0; for (j=0; j<len; j++) { /*we currently only split sentences at spaces*/ if ((j+1!=len) && (wcTemp[j] != (unsigned short) ' ')) continue; if (FSLTR) { for (k=0; k<=j - first_char; k++) letter[k] = wcTemp[first_char+k]; } else { for (k=0; k<=j - first_char; k++) letter[k] = wcTemp[len - first_char - k - 1]; } letter[k] = (unsigned short) 0; tl = new_text_line(eff->surface->render, st->text_lines); /*word splitting only happen in layout, so we don't need top/left anchors*/ ft_r->add_text_to_path(ft_r, tl->path, 1, letter, 0, 0, FIX_ONE, FIX_ONE, st->ascent, &rc); gf_path_get_bounds(tl->path, &tl->bounds); tl->bounds.width = rc.width; if (tl->bounds.x != 0) tl->bounds.width -= tl->bounds.x; tl->bounds.x = 0; tl->bounds.height = MAX(st->ascent + st->descent, tl->bounds.height); if (tl->bounds.y != 0) tl->bounds.height -= tl->bounds.y; tl->bounds.y = 0; first_char = j+1; } }}typedef struct{ unsigned short *wcText; u32 length; Fixed width, height; Fixed x_scaling, y_scaling;} TextLine;static void BuildVerticalTextGraph(TextStack *st, M_Text *txt, RenderEffect3D *eff){ TextLine *lines; CachedTextLine *tl; unsigned short wcTemp[5000]; u32 i, int_major, len, k; Fixed fontSize, start_x, start_y, space, line_spacing, tot_width, tot_height, max_scale; GF_Rect rc, final; Fixed lw, lh, max_lw; unsigned short letter[2]; GF_FontRaster *ft_r = st->compositor->font_engine; M_FontStyle *fs = (M_FontStyle *)txt->fontStyle; fontSize = get_font_size(fs, eff); line_spacing = gf_mulfix(FSSPACE , fontSize); if (ft_r->set_font(ft_r, FSFAMILY, FSSTYLE) != GF_OK) { if (ft_r->set_font(ft_r, NULL, NULL) != GF_OK) { return; } } ft_r->set_font_size(ft_r, fontSize); ft_r->get_font_metrics(ft_r, &st->ascent, &st->descent, &space); /*compute overall bounding box size*/ tot_width = 0; tot_height = 0; lines = (TextLine *) malloc(sizeof(TextLine)*txt->string.count); memset(lines, 0, sizeof(TextLine)*txt->string.count); letter[1] = (unsigned short) '\0'; for (i=0; i < txt->string.count; i++) { Fixed tmp; char *str = txt->string.vals[i]; if (!str) continue; lines[i].length = 0; len = gf_utf8_mbstowcs(wcTemp, 5000, (const char **) &str); if (len == (size_t) (-1)) continue; lines[i].wcText = (u16*)malloc(sizeof(unsigned short) * len); memcpy(lines[i].wcText, wcTemp, sizeof(unsigned short) * len); lines[i].length = len; lines[i].y_scaling = lines[i].x_scaling = FIX_ONE; lines[i].height = gf_mulfix(len , space); if (!lines[i].height) continue; if ((txt->length.count>i) && (txt->length.vals[i]>0) ) lines[i].y_scaling = gf_divfix(txt->length.vals[i], lines[i].height); tmp = gf_mulfix(lines[i].height , lines[i].y_scaling); if (tot_height < tmp) tot_height = tmp; } tot_width = gf_mulfix(txt->string.count , line_spacing); st->bounds.width = tot_width; max_scale = FIX_ONE; if ((txt->maxExtent>0) && (tot_height>txt->maxExtent)) { max_scale = gf_divfix(txt->maxExtent , tot_height); tot_height = txt->maxExtent; } if (!strcmp(FSMINOR, "MIDDLE")) { if (FSLTR) { start_x = -tot_width/2; st->bounds.x = start_x; } else { start_x = tot_width/2 - line_spacing; st->bounds.x = - tot_width + line_spacing; } } else if (!strcmp(FSMINOR, "END")) { if (FSLTR) { start_x = -tot_width; st->bounds.x = start_x; } else { start_x = tot_width-line_spacing; st->bounds.x = 0; } } else { if (FSLTR) { start_x = 0; st->bounds.x = start_x; } else { start_x = -line_spacing; st->bounds.x = -tot_width; } } if (!strcmp(FSMAJOR, "MIDDLE")) { int_major = 0; } else if (!strcmp(FSMAJOR, "END")) { int_major = 1; } else { int_major = 2; } final.width = final.height = 0; for (i=0; i < txt->string.count; i++) { switch (int_major) { case 0: if (FSTTB) start_y = lines[i].height/2; else start_y = -lines[i].height/2 + space; break; case 1: if (FSTTB) start_y = lines[i].height; else start_y = -lines[i].height + space; break; default: if (FSTTB) start_y = 0; else start_y = space; break; } if (lines[i].length) { tl = new_text_line(eff->surface->render, st->text_lines); /*adjust horizontal offset on first column*/ if (!i) { max_lw = 0; for (k=0; k<lines[i].length; k++) { letter[0] = lines[i].wcText[k]; /*get glyph width so that all letters are centered on the same vertical line*/ ft_r->get_text_size(ft_r, letter, &lw, &lh); if (max_lw < lw) max_lw = lw; } st->bounds.width += max_lw/2; start_x += max_lw/2; } for (k=0; k<lines[i].length; k++) { letter[0] = lines[i].wcText[k]; /*get glyph width so that all letters are centered on the same vertical line*/ ft_r->get_text_size(ft_r, letter, &lw, &lh); ft_r->add_text_to_path(ft_r, tl->path, 1, letter, start_x - lw/2, start_y, lines[i].x_scaling, gf_mulfix(lines[i].y_scaling, max_scale), st->ascent, &rc); if (FSTTB) start_y -= space; else start_y += space; } gf_path_get_bounds(tl->path, &rc); gf_rect_union(&final, &rc); } if (FSLTR) { start_x += line_spacing; } else { start_x -= line_spacing; } /*free unicode buffer*/ free(lines[i].wcText); } /*free remaining unicode buffers*/ for (; i < txt->string.count; i++) free(lines[i].wcText); free(lines); st->bounds.height = final.height; st->bounds.y = final.y;}static void BuildTextGraph(TextStack *st, M_Text *txt, RenderEffect3D *eff){ TextLine *lines; CachedTextLine *tl; unsigned short wcTemp[5000]; u32 i, int_major, len, k; Fixed fontSize, start_x, start_y, font_height, line_spacing, tot_width, tot_height, max_scale; GF_Rect final; GF_FontRaster *ft_r = st->compositor->font_engine; M_FontStyle *fs = (M_FontStyle *)txt->fontStyle; if (!FSHORIZ) { BuildVerticalTextGraph(st, txt, eff); return; } fontSize = get_font_size(fs, eff); if (ft_r->set_font(ft_r, FSFAMILY, FSSTYLE) != GF_OK) { if (ft_r->set_font(ft_r, NULL, NULL) != GF_OK) { return; } } ft_r->set_font_size(ft_r, fontSize); ft_r->get_font_metrics(ft_r, &st->ascent, &st->descent, &font_height); /*spacing= FSSPACING * (font_height) and fontSize not adjusted */ line_spacing = gf_mulfix(FSSPACE , fontSize); tot_width = 0; lines = (TextLine *) malloc(sizeof(TextLine)*txt->string.count); memset(lines, 0, sizeof(TextLine)*txt->string.count); for (i=0; i < txt->string.count; i++) { Fixed tmp; char *str = txt->string.vals[i]; if (!str) continue; lines[i].length = 0; len = gf_utf8_mbstowcs(wcTemp, 5000, (const char **) &str); if (len == (size_t) (-1)) continue; lines[i].length = len; lines[i].wcText = (u16*)malloc(sizeof(unsigned short) * (len+1)); if (!FSLTR) { for (k=0; k<len; k++) lines[i].wcText[k] = wcTemp[len-k-1]; } else { memcpy(lines[i].wcText, wcTemp, sizeof(unsigned short) * len); } lines[i].wcText[len] = (unsigned short) '\0'; lines[i].y_scaling = lines[i].x_scaling = FIX_ONE; ft_r->get_text_size(ft_r, lines[i].wcText, &lines[i].width, &lines[i].height); if (!lines[i].width) continue; if ((txt->length.count>i) && (txt->length.vals[i]>0)) { lines[i].x_scaling = gf_divfix(txt->length.vals[i], lines[i].width); } tmp = gf_mulfix(lines[i].width, lines[i].x_scaling); if (tot_width < tmp) tot_width = tmp; } max_scale = FIX_ONE; if ((txt->maxExtent > 0) && (tot_width>txt->maxExtent)) { max_scale = gf_divfix(txt->maxExtent, tot_width); tot_width = txt->maxExtent; } tot_height = (txt->string.count-1) * line_spacing + (st->ascent + st->descent); st->bounds.height = tot_height; if (!strcmp(FSMINOR, "MIDDLE")) { if (FSTTB) { start_y = tot_height/2; st->bounds.y = start_y; } else { start_y = st->descent + st->ascent - tot_height/2; st->bounds.y = tot_height/2; } } else if (!strcmp(FSMINOR, "BEGIN")) { if (FSTTB) { start_y = st->descent; start_y = 0; st->bounds.y = start_y; } else { st->bounds.y = st->bounds.height; start_y = st->descent + st->ascent; } } else if (!strcmp(FSMINOR, "END")) { if (FSTTB) { start_y = tot_height; st->bounds.y = start_y; } else { start_y = -tot_height + 2*st->descent + st->ascent; st->bounds.y = start_y - (st->descent + st->ascent) + tot_height; } } else { start_y = st->ascent; st->bounds.y = FSTTB ? start_y : (tot_height - st->descent); } /*major-justification*/ if (!strcmp(FSMAJOR, "MIDDLE") ) { int_major = 0; } else if (!strcmp(FSMAJOR, "END") ) { int_major = 1; } else { int_major = 2; } final.width = final.height = 0; for (i=0; i < txt->string.count; i++) { switch (int_major) { /*major-justification MIDDLE*/ case 0: start_x = -lines[i].width/2; break; /*major-justification END*/ case 1: start_x = (FSLTR) ? -lines[i].width : 0; break; /*BEGIN, FIRST or default*/ default: start_x = (FSLTR) ? 0 : -lines[i].width; break; } if (lines[i].length) { tl = new_text_line(eff->surface->render, st->text_lines); /*if using the font engine the font is already configured*/ ft_r->add_text_to_path(ft_r, tl->path, 1, lines[i].wcText, start_x, start_y, gf_mulfix(lines[i].x_scaling, max_scale), lines[i].y_scaling, st->ascent, &tl->bounds); gf_rect_union(&final, &tl->bounds); gf_path_get_bounds(tl->path, &tl->bounds); } if (FSTTB) { start_y -= line_spacing; } else { start_y += line_spacing; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -