📄 freetype.c
字号:
TT_Get_Glyph_Metrics (ttf_glyph_info->glyph, &metrics); x += metrics.advance / 64;#else x += ttf_inst_info->ave_width;#endif } if ((logfont->style & FS_SETWIDTH_CONDENSED) && ttf_glyph_info->can_kern) { x += compute_kernval (ttf_inst_info) / 64; } /* Kerning point syndrome avoidance */ if (ttf_inst_info->last_pen_pos > x) x = ttf_inst_info->last_pen_pos; ttf_inst_info->last_pen_pos = x; ttf_inst_info->last_glyph_code = index; x += cExtra; } return x;}static int get_ave_width (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); return ttf_inst_info->ave_width;}static int get_font_height (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); return ttf_inst_info->height;}static int get_font_size (LOGFONT* logfont, DEVFONT* devfont, int expect){ return expect;}static int get_font_ascent (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); return ttf_inst_info->ascent;}static int get_font_descent (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); return -ttf_inst_info->descent;}static size_t char_bitmap_size (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len){ int char_width; TT_UShort index; TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); TTFGLYPHINFO* ttf_glyph_info = ttf_inst_info->ttf_glyph_info; index = TT_Char_Index (ttf_glyph_info->char_map, (*devfont->charset_ops->conv_to_uc16) (mchar, len)); if (index < 256) char_width = ttf_inst_info->widths [index]; else char_width = ttf_inst_info->ave_width; return ((char_width + 7) >> 3) * ttf_inst_info->height;}static size_t max_bitmap_size (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); return ((ttf_inst_info->max_width + 7) >> 3) * ttf_inst_info->height;}/* call this function before output a string */static void start_str_output (LOGFONT* logfont, DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); ttf_inst_info->last_glyph_code = -1; /* reset kerning*/ ttf_inst_info->last_pen_pos = -1;}/* call this function before getting the bitmap/pixmap of the char * to get the bbox of the char */static int get_char_bbox (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len, int* px, int* py, int* pwidth, int* pheight){ TT_UShort uni_char; TT_F26Dot6 x = 0, y = 0; TT_F26Dot6 xmin, ymin, xmax, ymax; TT_Pos vec_x, vec_y; TT_Glyph_Metrics metrics; TT_BBox bbox; TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); TTFGLYPHINFO* ttf_glyph_info = ttf_inst_info->ttf_glyph_info; if (px) x = *px; if (py) y = *py; uni_char = (*devfont->charset_ops->conv_to_uc16) (mchar, len); ttf_inst_info->cur_glyph_code = TT_Char_Index (ttf_glyph_info->char_map, uni_char); vec_x = 0;#if 0 vec_y = ttf_inst_info->ascent << 6;#else vec_y = 0;#endif TT_Transform_Vector (&vec_x, &vec_y, &ttf_inst_info->matrix); x -= (vec_x & -64) >> 6; y += ((vec_y + 63) & -64) >> 6; if (TT_Load_Glyph (ttf_inst_info->instance, ttf_glyph_info->glyph, ttf_inst_info->cur_glyph_code, TTLOAD_DEFAULT) != TT_Err_Ok) return 0; TT_Get_Glyph_Metrics (ttf_glyph_info->glyph, &metrics); ttf_inst_info->cur_advance = metrics.advance; TT_Get_Glyph_Outline (ttf_glyph_info->glyph, &ttf_inst_info->cur_outline); if (ttf_inst_info->rotation) { TT_Transform_Outline (&ttf_inst_info->cur_outline, &ttf_inst_info->matrix); } if ((logfont->style & FS_SETWIDTH_CONDENSED) && ttf_glyph_info->can_kern) { if (ttf_inst_info->rotation) { vec_x = compute_kernval (ttf_inst_info); vec_y = 0; TT_Transform_Vector (&vec_x, &vec_y, &ttf_inst_info->matrix); x += vec_x / 64; y -= vec_y / 64; } else x += compute_kernval (ttf_inst_info) / 64; } /* we begin by grid-fitting the bounding box */ TT_Get_Outline_BBox (&ttf_inst_info->cur_outline, &bbox); xmin = (bbox.xMin & -64) >> 6; ymin = (bbox.yMin & -64) >> 6; xmax = ((bbox.xMax + 63) & -64) >> 6; ymax = ((bbox.yMax + 63) & -64) >> 6;#if 0 /* hack for ... */ if (ttf_inst_info->ascent < ymax) { int off = ymax - ttf_inst_info->ascent; ymax -= off; ymin -= off; }#endif ttf_inst_info->cur_xmin = (bbox.xMin & -64); ttf_inst_info->cur_ymin = (bbox.yMin & -64); ttf_inst_info->cur_width = xmax - xmin; ttf_inst_info->cur_height = ymax - ymin; if (pwidth) *pwidth = (int)(xmax - xmin); if (pheight) *pheight = (int)(ymax - ymin); if (px) *px = (int)(x + xmin); if (py) *py = (int)(y - ymax); return (int)(xmax - xmin);}/* call this function to get the bitmap/pixmap of the char */ static const void* char_bitmap_pixmap (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len, int* pitch) { int size; TT_Raster_Map Raster; TT_Error error; TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); size = ttf_inst_info->cur_width * ttf_inst_info->cur_height; /* now allocate the raster bitmap */ Raster.rows = ttf_inst_info->cur_height; Raster.width = ttf_inst_info->cur_width; if (!pitch) Raster.cols = (Raster.width + 7) >> 3; /* pad to 8-bits */ else *pitch = Raster.cols = (Raster.width + 3) & -4; /* pad to 32-bits */ Raster.flow = TT_Flow_Down; Raster.size = Raster.rows * Raster.cols; Raster.bitmap = get_raster_bitmap_buffer (Raster.size); memset (Raster.bitmap, 0, Raster.size); /* now render the glyph in the small bitmap/pixmap */ /* IMPORTANT NOTE: the offset parameters passed to the function */ /* TT_Get_Glyph_Bitmap() must be integer pixel values, i.e., */ /* multiples of 64. HINTING WILL BE RUINED IF THIS ISN'T THE CASE! */ /* This is why we _did_ grid-fit the bounding box, especially xmin */ /* and ymin. */ if (!pitch) { TT_Translate_Outline (&ttf_inst_info->cur_outline, -ttf_inst_info->cur_xmin, -ttf_inst_info->cur_ymin); if ((error = TT_Get_Outline_Bitmap (ttf_engine, &ttf_inst_info->cur_outline, &Raster))) return NULL; } else { TT_Translate_Outline (&ttf_inst_info->cur_outline, -ttf_inst_info->cur_xmin, -ttf_inst_info->cur_ymin); if ((error = TT_Get_Outline_Pixmap (ttf_engine, &ttf_inst_info->cur_outline, &Raster))) return NULL; }#if 0 { int i, j, k; for (i = 0; i < Raster.rows; i++) { for (j = 0; j < Raster.cols; j++) { BYTE byte = *((BYTE*)Raster.bitmap + i * Raster.cols + j); for (k = 0; k < 8; k++) if (byte & (0x80>>k)) fprintf (stderr, "*"); else fprintf (stderr, " "); } fprintf (stderr, "\n"); } }#endif return Raster.bitmap;}static const void* get_char_bitmap (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len){ return char_bitmap_pixmap (logfont, devfont, mchar, len, NULL);}static const void* get_char_pixmap (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len, int* pitch){ return char_bitmap_pixmap (logfont, devfont, mchar, len, pitch);}/* call this function after getting the bitmap/pixmap of the char * to get the advance of the char */static void get_char_advance (LOGFONT* logfont, DEVFONT* devfont, const unsigned char* mchar, int len, int* px, int* py){ TT_Pos vec_x, vec_y; TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); TTFGLYPHINFO* ttf_glyph_info = TTF_GLYPH_INFO_P (devfont); if (ttf_inst_info->rotation) { vec_x = ttf_inst_info->cur_advance; vec_y = 0; TT_Transform_Vector (&vec_x, &vec_y, &ttf_inst_info->matrix); *px += vec_x / 64; *py -= vec_y / 64; } else { *px += ttf_inst_info->cur_advance / 64; if ((logfont->style & FS_SETWIDTH_CONDENSED) && ttf_glyph_info->can_kern) { *px += compute_kernval (ttf_inst_info) / 64; } /* Kerning point syndrome avoidance */ if (ttf_inst_info->last_pen_pos > *px) *px = ttf_inst_info->last_pen_pos; ttf_inst_info->last_pen_pos = *px; } ttf_inst_info->last_glyph_code = ttf_inst_info->cur_glyph_code;}static DEVFONT* new_instance (LOGFONT* logfont, DEVFONT* devfont, BOOL need_sbc_font){ TTFGLYPHINFO* ttf_glyph_info = TTF_GLYPH_INFO_P (devfont); TTFINSTANCEINFO* ttf_inst_info = NULL; DEVFONT* new_devfont = NULL; float angle; TT_Face_Properties properties; TT_Instance_Metrics imetrics; int i, sum_width; unsigned short* widths = NULL; if ((new_devfont = calloc (1, sizeof (DEVFONT))) == NULL) goto out; if ((ttf_inst_info = calloc (1, sizeof (TTFINSTANCEINFO))) == NULL) goto out; if ((widths = calloc (256, sizeof (unsigned short))) == NULL) goto out; memcpy (new_devfont, devfont, sizeof (DEVFONT)); if (need_sbc_font && devfont->charset_ops->bytes_maxlen_char > 1) { char charset [LEN_FONT_NAME + 1]; fontGetCompatibleCharsetFromName (devfont->name, charset); new_devfont->charset_ops = GetCharsetOps (charset); } new_devfont->data = ttf_inst_info; ttf_inst_info->ttf_glyph_info = ttf_glyph_info; ttf_inst_info->widths = widths; /* Create instance */ if (TT_New_Instance (ttf_glyph_info->face, &ttf_inst_info->instance) != TT_Err_Ok) goto out; /* Set the instance resolution */ if (TT_Set_Instance_Resolutions (ttf_inst_info->instance, 96, 96) != TT_Err_Ok) goto out; /* We want real pixel sizes ... not points ...*/ TT_Set_Instance_PixelSizes (ttf_inst_info->instance, logfont->size, logfont->size, logfont->size * 64); /* reset kerning*/ ttf_inst_info->last_glyph_code = -1; ttf_inst_info->last_pen_pos = -1; /* Font rotation */ ttf_inst_info->rotation = logfont->rotation; /* in tenthdegrees */ /* Build the rotation matrix with the given angle */ TT_Set_Instance_Transform_Flags (ttf_inst_info->instance, TRUE, FALSE); angle = ttf_inst_info->rotation * M_PI / 1800; ttf_inst_info->matrix.yy = (TT_Fixed) (cos (angle) * (1 << 16)); ttf_inst_info->matrix.yx = (TT_Fixed) (sin (angle) * (1 << 16)); ttf_inst_info->matrix.xx = ttf_inst_info->matrix.yy; ttf_inst_info->matrix.xy = -ttf_inst_info->matrix.yx; /* Fill up the info fields */ TT_Get_Face_Properties (ttf_glyph_info->face, &properties); TT_Get_Instance_Metrics(ttf_inst_info->instance, &imetrics); ttf_inst_info->max_width = ((properties.horizontal->xMax_Extent * \ imetrics.x_scale)/ 0x10000) >> 6; ttf_inst_info->ascent = (((properties.horizontal->Ascender * \ imetrics.y_scale)/0x10000) >> 6) + 1; ttf_inst_info->descent = (((properties.horizontal->Descender * \ imetrics.y_scale)/0x10000) >> 6) + 1; ttf_inst_info->height = ttf_inst_info->ascent - ttf_inst_info->descent; sum_width = 0; for (i = 0; i <= ttf_glyph_info->last_glyph_index; i++) { widths [i] = Get_Glyph_Width (ttf_inst_info, i); sum_width += widths [i]; } if (properties.num_Glyphs > 255) ttf_inst_info->ave_width = Get_Glyph_Width (ttf_inst_info, 256); else ttf_inst_info->ave_width = sum_width / properties.num_Glyphs; return new_devfont;out: free (widths); free (ttf_inst_info); free (new_devfont); return NULL;}static void delete_instance (DEVFONT* devfont){ TTFINSTANCEINFO* ttf_inst_info = TTF_INST_INFO_P (devfont); TT_Done_Instance (ttf_inst_info->instance); free (ttf_inst_info->widths); free (ttf_inst_info); free (devfont);}/**************************** Global data ************************************/static FONTOPS freetype_font_ops = { get_char_width, get_str_width, get_ave_width, get_max_width, get_font_height, get_font_size, get_font_ascent, get_font_descent, char_bitmap_size, max_bitmap_size, get_char_bitmap, get_char_pixmap, start_str_output, get_char_bbox, get_char_advance, new_instance, delete_instance};#endif /* _TTF_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -