📄 ttf.c
字号:
cached->miny = cached->maxy - FT_CEIL(metrics->height); cached->yoffset = font->ascent - cached->maxy; cached->advance = FT_CEIL(metrics->horiAdvance); /* Adjust for bold and italic text */ if (font->style & TTF_STYLE_BOLD) { cached->maxx += font->glyph_overhang; } if (font->style & TTF_STYLE_ITALIC) { cached->maxx += (int) ceil(font->glyph_italics); } cached->stored |= CACHED_METRICS; } if (((want & CACHED_BITMAP) && !(cached->stored & CACHED_BITMAP)) || ((want & CACHED_PIXMAP) && !(cached->stored & CACHED_PIXMAP))) { int mono = (want & CACHED_BITMAP); int i; FT_Bitmap *src; FT_Bitmap *dst; /* Handle the italic style */ if (font->style & TTF_STYLE_ITALIC) { FT_Matrix shear; shear.xx = 1 << 16; shear.xy = (int) (font->glyph_italics * (1 << 16)) / font->height; shear.yx = 0; shear.yy = 1 << 16; FT_Outline_Transform(outline, &shear); } /* Render the glyph */ if (mono) { error = FT_Render_Glyph(glyph, ft_render_mode_mono); } else { error = FT_Render_Glyph(glyph, ft_render_mode_normal); } if (error) { return error; } /* Copy over information to cache */ src = &glyph->bitmap; if (mono) { dst = &cached->bitmap; } else { dst = &cached->pixmap; } memcpy(dst, src, sizeof(*dst)); if (mono) { dst->pitch *= 8; } /* Adjust for bold and italic text */ if (font->style & TTF_STYLE_BOLD) { int bump = font->glyph_overhang; dst->pitch += bump; dst->width += bump; } if (font->style & TTF_STYLE_ITALIC) { int bump = (int) ceil(font->glyph_italics); dst->pitch += bump; dst->width += bump; } if (dst->rows != 0) { dst->buffer = malloc(dst->pitch * dst->rows); if (!dst->buffer) { return FT_Err_Out_Of_Memory; } memset(dst->buffer, 0, dst->pitch * dst->rows); for (i = 0; i < src->rows; i++) { int soffset = i * src->pitch; int doffset = i * dst->pitch; if (mono) { unsigned char *srcp = src->buffer + soffset; unsigned char *dstp = dst->buffer + doffset; int j; for (j = 0; j < src->width; j += 8) { unsigned char ch = *srcp++; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; ch <<= 1; *dstp++ = (ch & 0x80) >> 7; } } else { memcpy(dst->buffer + doffset, src->buffer + soffset, src->pitch); } } } /* Handle the bold style */ if (font->style & TTF_STYLE_BOLD) { int row; int col; int offset; int pixel; unsigned char *pixmap; /* The pixmap is a little hard, we have to add and clamp */ for (row = dst->rows - 1; row >= 0; --row) { pixmap = (unsigned char *) dst->buffer + row * dst->pitch; for (offset = 1; offset <= font->glyph_overhang; ++offset) { for (col = dst->width - 1; col > 0; --col) { pixel = (pixmap[col] + pixmap[col - 1]); if (pixel > NUM_GRAYS - 1) { pixel = NUM_GRAYS - 1; } pixmap[col] = (unsigned char) pixel; } } } } /* Mark that we rendered this format */ if (mono) { cached->stored |= CACHED_BITMAP; } else { cached->stored |= CACHED_PIXMAP; } } /* We're done, mark this glyph cached */ cached->cached = ch; return 0;}static FT_Error Find_Glyph(TTF_Font * font, unsigned short ch, int want){ int retval = 0; if (ch < 256) { font->current = &font->cache[ch]; } else { if (font->scratch.cached != ch) { Flush_Glyph(&font->scratch); } font->current = &font->scratch; } if ((font->current->stored & want) != want) { retval = Load_Glyph(font, ch, font->current, want); } return retval;}int TTF_SizeUNICODE(TTF_Font * font, const unsigned short *text, int *w, int *h){ int status; const unsigned short *ch; int x, z; int minx, maxx; int miny, maxy; c_glyph *glyph; FT_Error error; /* Initialize everything to 0 */ if (!TTF_initialized) { return -1; } status = 0; minx = maxx = 0; miny = maxy = 0; /* Load each character and sum it's bounding box */ x = 0; for (ch = text; *ch; ++ch) { error = Find_Glyph(font, *ch, CACHED_METRICS); if (error) { return -1; } glyph = font->current; z = x + glyph->minx; if (minx > z) { minx = z; } if (font->style & TTF_STYLE_BOLD) { x += font->glyph_overhang; } if (glyph->advance > glyph->maxx) { z = x + glyph->advance; } else { z = x + glyph->maxx; } if (maxx < z) { maxx = z; } x += glyph->advance; if (glyph->miny < miny) { miny = glyph->miny; } if (glyph->maxy > maxy) { maxy = glyph->maxy; } } /* Fill the bounds rectangle */ if (w) { *w = (maxx - minx); } if (h) *h = font->height; return status;}unsigned char *TTF_RenderUNICODE_Shaded(TTF_Font * font, const unsigned short *text, unsigned int fg, unsigned int bg){ int xstart; int width; int height; unsigned char *textbuf; int rdiff; int gdiff; int bdiff; unsigned short val, bgc; const unsigned short *ch; unsigned char *src; unsigned char *dst; int row, col; c_glyph *glyph; FT_Error error; /* Get the dimensions of the text surface */ if ((TTF_SizeUNICODE(font, text, &width, NULL) < 0) || !width) { fprintf(stderr, "Text has zero width\n"); return NULL; } height = font->height; /* Create the target surface */ textbuf = malloc(width * height * fbbytes); if (textbuf == NULL) { return NULL; } /* Load and render each character */ xstart = 0; for (ch = text; *ch; ++ch) { FT_Bitmap *current; error = Find_Glyph(font, *ch, CACHED_METRICS | CACHED_PIXMAP); if (error) { free(textbuf); return NULL; } glyph = font->current; current = &glyph->pixmap; for (row = 0; row < current->rows; ++row) { dst = (unsigned char *) framebuffer + (fbypos + row + glyph->yoffset) * fblinelen + (xstart + glyph->minx + fbxpos) * fbbytes; src = current->buffer + row * current->pitch; for (col = current->width; col > 0; --col) { val = *src++; bgc = *(unsigned short *) dst; /* get color parts from real color */ rdiff = (fg >> 16); gdiff = ((fg >> 8) & 0xff); bdiff = (fg & 0xff); val = alpha * val / 100; /* dim color down to current pixel value */ rdiff = rdiff * val / 0xff; gdiff = gdiff * val / 0xff; bdiff = bdiff * val / 0xff;#if 1 /* do alpha transparency */ //rdiff=(rdiff*alpha/100); rdiff += ((bgc) >> 8 & 0xf8) * (0xff - val) / 0xff; //gdiff=(gdiff*alpha/100); gdiff += ((bgc >> 3) & 0xfc) * (0xff - val) / 0xff; //bdiff=(bdiff*alpha/100); bdiff += ((bgc << 3) & 0xf8) * (0xff - val) / 0xff;#endif val = ((rdiff & 0xf8) << 8) | ((gdiff & 0xfc) << 3) | (bdiff >> 3); //*dst++ = (val >>8); *dst++ = val & 0xff; *dst++ = (val >> 8); } //printf("\n"); } xstart += glyph->advance; if (font->style & TTF_STYLE_BOLD) { xstart += font->glyph_overhang; } } /* Handle the underline style */ if (font->style & TTF_STYLE_UNDERLINE) { row = font->ascent - font->underline_offset - 1; if (row >= fby) { row = (height - 1) - font->underline_height; } dst = (unsigned char *) textbuf + row * width * fbbytes; for (row = font->underline_height; row > 0; --row) { memset(dst, NUM_GRAYS - 1, width); dst += width * fbbytes; } } return textbuf;}int rendertext(char *text, char *fontname, unsigned int ptsize, unsigned int forecol){ TTF_Font *font; int renderstyle = 0; enum { RENDER_LATIN1, RENDER_UTF8, RENDER_UNICODE } rendertype; /* Initialize the TTF library */ if (TTF_Init() < 0) { fprintf(stderr, "Couldn't initialize TTF.\n"); return (2); } atexit(TTF_Quit); /* Open the font file with the requested point size */ font = TTF_OpenFont(fontname, ptsize); if (font == NULL) { fprintf(stderr, "Couldn't load %d pt font from %s\n", ptsize, fontname); return (2); } renderstyle = TTF_STYLE_NORMAL; rendertype = RENDER_LATIN1; TTF_SetFontStyle(font, renderstyle); text = TTF_RenderText_Shaded(font, text, forecol, 0); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -