本文整理汇总了C++中FT_New_Face函数的典型用法代码示例。如果您正苦于以下问题:C++ FT_New_Face函数的具体用法?C++ FT_New_Face怎么用?C++ FT_New_Face使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了FT_New_Face函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Shader
font::font(Window* window){
parentWindow = window;
shader = new Shader(window);
shader->load(shadersPath + "text.vert", shadersPath + "text.frag", "");
glUseProgram(shader->ID);
// FreeType
FT_Library ft;
// All functions return a value different than 0 whenever an error occurred
if (FT_Init_FreeType(&ft))
std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
// Load font as face
FT_Face face;
if (FT_New_Face(ft, "../fonts/arial.ttf", 0, &face))
std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
// Set size to load glyphs as
FT_Set_Pixel_Sizes(face, 0, 48);
// Disable byte-alignment restriction
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Load first 128 characters of ASCII set
for (GLubyte c = 0; c < 128; c++){
// Load character glyph
if (FT_Load_Char(face, c, FT_LOAD_RENDER)){
std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
continue;
}
// Generate texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RED,
face->glyph->bitmap.width,
face->glyph->bitmap.rows,
0,
GL_RED,
GL_UNSIGNED_BYTE,
face->glyph->bitmap.buffer
);
// Set texture options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Now store character for later use
Character character = {
texture,
glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
(GLuint)face->glyph->advance.x
};
Characters.insert(std::pair<GLchar, Character>(c, character));
}
glBindTexture(GL_TEXTURE_2D, 0);
// Destroy FreeType once we're finished
FT_Done_Face(face);
FT_Done_FreeType(ft);
// Configure VAO/VBO for texture quads
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
示例2: gfxfont_load
gfxfont_t* gfxfont_load(const char*id, const char*filename, unsigned int flags, double quality)
{
FT_Face face;
FT_Error error;
const char* fontname = 0;
FT_ULong charcode;
FT_UInt gindex;
gfxfont_t* font;
int t;
int*glyph2glyph = 0;
int*glyph2unicode = 0;
int max_unicode = 0;
int charmap = -1;
int isunicode = 1;
int has_had_errors = 0;
int num_names = 0;
if(ftlibrary == 0) {
if(FT_Init_FreeType(&ftlibrary)) {
fprintf(stderr, "Couldn't init freetype library!\n");
exit(1);
}
}
error = FT_New_Face(ftlibrary, filename, 0, &face);
FT_Set_Pixel_Sizes (face, 16*loadfont_scale, 16*loadfont_scale);
#ifdef DEBUG
printf("gfxfont_load(%s, %s, %f)\n", id, filename, quality);
#endif
if(error) {
fprintf(stderr, "Couldn't load file %s- not a TTF file? (error=%02x)\n", filename, error);
return 0;
}
if(face->num_glyphs <= 0) {
fprintf(stderr, "File %s contains %d glyphs\n", filename, (int)face->num_glyphs);
return 0;
}
font = (gfxfont_t*)rfx_calloc(sizeof(gfxfont_t));
//font->style = ((face->style_flags&FT_STYLE_FLAG_ITALIC)?FONT_STYLE_ITALIC:0) |((face->style_flags&FT_STYLE_FLAG_BOLD)?FONT_STYLE_BOLD:0);
//font->ascent = abs(face->ascender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMin;
//font->descent = abs(face->descender)*FT_SCALE*loadfont_scale*20/FT_SUBPIXELS/2; //face->bbox.xMax;
//font->leading = font->layout->ascent + font->layout->descent;
//font->encoding = FONT_ENCODING_UNICODE;
font->max_unicode = 0;
font->id = strdup(id);
font->glyphs = (gfxglyph_t*)rfx_calloc(face->num_glyphs*sizeof(gfxglyph_t));
glyph2unicode = (int*)rfx_calloc(face->num_glyphs*sizeof(int));
glyph2glyph = (int*)rfx_calloc(face->num_glyphs*sizeof(int));
if(FT_HAS_GLYPH_NAMES(face)) {
//font->glyphnames = rfx_calloc(face->num_glyphs*sizeof(char*));
}
fontname = FT_Get_Postscript_Name(face);
#ifdef DEBUG
for(t=0;t<face->num_charmaps;t++) {
printf("possible encoding: %c%c%c%c (%d of %d)\n",
(face->charmaps[t]->encoding >> 24)&255,
(face->charmaps[t]->encoding >> 16)&255,
(face->charmaps[t]->encoding >> 8)&255,
(face->charmaps[t]->encoding >> 0)&255,
t+1, face->num_charmaps
);
}
#endif
while(1)
{
charcode = FT_Get_First_Char(face, &gindex);
while(gindex != 0)
{
if(gindex >= 0 && gindex<face->num_glyphs) {
if(!glyph2unicode[gindex]) {
glyph2unicode[gindex] = charcode;
if(charcode + 1 > font->max_unicode) {
font->max_unicode = charcode + 1;
}
}
}
charcode = FT_Get_Next_Char(face, charcode, &gindex);
}
#ifdef DEBUG
if(face->charmap) {
printf("ENCODING: %c%c%c%c (%d of %d) max_unicode=%d\n",
(face->charmap->encoding >> 24)&255,
(face->charmap->encoding >> 16)&255,
(face->charmap->encoding >> 8)&255,
(face->charmap->encoding >> 0)&255,
charmap, face->num_charmaps, font->max_unicode
);
} else {
示例3: use
/*!
\brief Scan a folder for all valid fonts
\param fontspath Path of the folder to scan.
\return
- \c B_OK Success
- \c B_NAME_TOO_LONG The path specified is too long
- \c B_ENTRY_NOT_FOUND The path does not exist
- \c B_LINK_LIMIT A cyclic loop was detected in the file system
- \c B_BAD_VALUE Invalid input specified
- \c B_NO_MEMORY Insufficient memory to open the folder for reading
- \c B_BUSY A busy node could not be accessed
- \c B_FILE_ERROR An invalid file prevented the operation.
- \c B_NO_MORE_FDS All file descriptors are in use (too many open files).
*/
status_t FontServer::ScanDirectory(const char *fontspath)
{
// This bad boy does all the real work. It loads each entry in the
// directory. If a valid font file, it adds both the family and the style.
// Both family and style are stored internally as BStrings. Once everything
int32 validcount=0;
FT_Face face;
FT_Error error;
FT_CharMap charmap;
FontFamily *family;
DIR* hDir;
dirent* psEntry;
printf( "FontServer::ScanDirectory(): opening %s\n", fontspath );
if ( (hDir = opendir( fontspath ) ) )
{
while( (psEntry = readdir( hDir )) )
{
printf( "FontServer::ScanDirectory(): found entry %s\n", psEntry->d_name );
char zFullPath[ PATH_MAX ];
if ( strcmp( psEntry->d_name, "." ) == 0 || strcmp( psEntry->d_name, ".." ) == 0 )
{
continue;
}
strcpy( zFullPath, fontspath );
pathcat( zFullPath, psEntry->d_name );
error=FT_New_Face(ftlib, zFullPath,0,&face);
if (error!=0)
continue;
charmap=_GetSupportedCharmap(face);
if(!charmap)
{
FT_Done_Face(face);
continue;
}
face->charmap=charmap;
family=_FindFamily(face->family_name );
if (!family)
{
#ifdef PRINT_FONT_LIST
printf("Font Family: %s\n",face->family_name);
#endif
family=new FontFamily(face->family_name);
families->AddItem(family);
}
if(family->HasStyle(face->style_name))
{
FT_Done_Face(face);
continue;
}
#ifdef PRINT_FONT_LIST
printf("\tFont Style: %s\n",face->style_name);
#endif
// Has vertical metrics?
family->AddStyle(zFullPath,face);
validcount++;
FT_Done_Face(face);
}
printf( "Directory '%s' scanned, %ld fonts found\n", fontspath, validcount );
closedir( hDir );
}
need_update=true;
return B_OK;
}
示例4: drawIndicText
void drawIndicText(JNIEnv *env, jobject thiz, jstring unicodeText, jint xStart,
jint yBaseLine, jint charHeight, jobject lock, jstring fontPath, jint language) {
FT_Library ft_library;
FT_Face ft_face;
hb_font_t *font;
hb_buffer_t *buffer;
int glyph_count;
hb_glyph_info_t *glyph_info;
hb_glyph_position_t *glyph_pos;
hb_bool_t fail;
FT_UInt glyph_index;
FT_GlyphSlot slot;
FT_Error error;
jboolean iscopy;
const jchar *text;
int num_chars, i;
int pen_x;
int glyphPosX, glyphPosY;
const char *fontFilePath = (*env)->GetStringUTFChars(env, fontPath, NULL);
text = (*env)->GetStringChars(env, unicodeText, &iscopy);
num_chars = (*env)->GetStringLength(env, unicodeText);
/* initialize library */
error = FT_Init_FreeType(&ft_library);
if (error) {
__android_log_print(6, "drawIndicText",
"Error initializing FreeType library\n");
return;
}
// __android_log_print(2, "drawIndicText",
// "Successfully initialized FreeType library\n");
error = FT_New_Face(ft_library, fontFilePath, 0, &ft_face); /* create face object */
if (error == FT_Err_Unknown_File_Format) {
__android_log_print(6, "drawIndicText",
"The font file could be opened and read, but it appears that its font format is unsupported %s ",
fontFilePath);
return;
} else if (error) {
__android_log_print(6, "drawIndicText",
"The font file could not be opened or read, or it might be broken");
return;
}
// __android_log_print(2, "drawIndicText",
// "Successfully created font-face object\n");
font = hb_ft_font_create(ft_face, NULL);
error = FT_Set_Pixel_Sizes(ft_face, 0, charHeight); /* set character size */
slot = ft_face->glyph;
pen_x = xStart;
/* Create a buffer for harfbuzz to use */
buffer = hb_buffer_create();
hb_buffer_set_script(buffer, scripts[language]);
/* Layout the text */
hb_buffer_add_utf16(buffer, text, num_chars, 0, num_chars);
// __android_log_print(2, "drawIndicText", "Before HarfBuzz shape()\n");
hb_shape(font, buffer, NULL, 0);
// __android_log_print(2, "drawIndicText", "After HarfBuzz shape()\n");
glyph_count = hb_buffer_get_length(buffer);
glyph_info = hb_buffer_get_glyph_infos(buffer, 0);
glyph_pos = hb_buffer_get_glyph_positions(buffer, 0);
for (i = 0; i < glyph_count; i++) {
glyph_index = glyph_info[i].codepoint;
// __android_log_print(2, "drawIndicText", "Glyph%d = %x", i, glyph_index);
error = FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT);
if (error) {
/* ignore errors */
continue;
}
/* convert to an anti-aliased bitmap */
error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
if (error) {
continue;
}
/* now, draw to our target surface (convert position) */
draw_bitmap(&slot->bitmap, pen_x + slot->bitmap_left,
yBaseLine - slot->bitmap_top, env, thiz, lock);
/* increment pen position */
pen_x += slot->advance.x >> 6;
//.........这里部分代码省略.........
示例5: ft_enum_fonts
static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path, GF_FileEnumInfo *file_info)
{
char *szfont;
FT_Face face;
u32 num_faces, i;
GF_FontReader *dr = cbck;
FTBuilder *ftpriv = dr->udta;
GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path));
if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0;
if (!face || !face->family_name) return 0;
num_faces = face->num_faces;
/*locate right font in collection if several*/
for (i=0; i<num_faces; i++) {
/*only scan scalable fonts*/
if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
Bool bold, italic;
szfont = gf_malloc(sizeof(char)* (strlen(face->family_name)+100));
if (!szfont) continue;
strcpy(szfont, face->family_name);
/*remember first font found which looks like a alphabetical one*/
if (!ftpriv->font_dir) {
u32 gidx;
FT_Select_Charmap(face, FT_ENCODING_UNICODE);
gidx = FT_Get_Char_Index(face, (u32) 'a');
if (gidx) gidx = FT_Get_Char_Index(face, (u32) 'z');
if (gidx) gidx = FT_Get_Char_Index(face, (u32) '1');
if (gidx) gidx = FT_Get_Char_Index(face, (u32) '@');
if (gidx) ftpriv->font_dir = gf_strdup(szfont);
}
bold = italic = 0;
if (face->style_name) {
char *name = gf_strdup(face->style_name);
strupr(name);
if (strstr(name, "BOLD")) bold = 1;
if (strstr(name, "ITALIC")) italic = 1;
/*if font is not regular style, append all styles blindly*/
if (!strstr(name, "REGULAR")) {
strcat(szfont, " ");
strcat(szfont, face->style_name);
}
gf_free(name);
} else {
if (face->style_flags & FT_STYLE_FLAG_BOLD) bold = 1;
if (face->style_flags & FT_STYLE_FLAG_ITALIC) italic = 1;
if (bold) strcat(szfont, " Bold");
if (italic) strcat(szfont, " Italic");
}
gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szfont, file_path);
/*try to assign default fixed fonts*/
if (!bold && !italic) {
strcpy(szfont, face->family_name);
strlwr(szfont);
if (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) {
setBestFont(BEST_FIXED_FONTS, &(ftpriv->font_fixed), face->family_name);
}
setBestFont(BEST_SERIF_FONTS, &(ftpriv->font_serif), face->family_name);
setBestFont(BEST_SANS_FONTS, &(ftpriv->font_sans), face->family_name);
}
gf_free(szfont);
}
FT_Done_Face(face);
if (i+1==num_faces) return 0;
/*load next font in collection*/
if (FT_New_Face(ftpriv->library, file_path, i+1, & face )) return 0;
if (!face) return 0;
}
return 0;
}
示例6: m_pattern
FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
: m_pattern(0)
, m_size(fontDescription.computedSize())
, m_syntheticBold(false)
, m_syntheticOblique(false)
, m_scaledFont(0)
, m_face(0)
{
FontPlatformData::init();
CString familyNameString = familyName.string().utf8();
const char* fcfamily = familyNameString.data();
int fcslant = FC_SLANT_ROMAN;
// FIXME: Map all FontWeight values to fontconfig weights.
int fcweight = FC_WEIGHT_NORMAL;
float fcsize = fontDescription.computedSize();
if (fontDescription.italic())
fcslant = FC_SLANT_ITALIC;
if (fontDescription.weight() >= FontWeight600)
fcweight = FC_WEIGHT_BOLD;
FcConfig *config = FcConfigGetCurrent();
//printf("family = %s\n", fcfamily);
int type = fontDescription.genericFamily();
FcPattern* pattern = FcPatternCreate();
if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
goto freePattern;
switch (type) {
case FontDescription::SerifFamily:
fcfamily = "serif";
break;
case FontDescription::SansSerifFamily:
fcfamily = "sans-serif";
break;
case FontDescription::MonospaceFamily:
fcfamily = "monospace";
break;
case FontDescription::NoFamily:
case FontDescription::StandardFamily:
default:
fcfamily = "sans-serif";
}
if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
goto freePattern;
if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant))
goto freePattern;
if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))
goto freePattern;
if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize))
goto freePattern;
FcConfigSubstitute(config, pattern, FcMatchPattern);
FcDefaultSubstitute(pattern);
FcResult fcresult;
m_pattern = FcFontMatch(config, pattern, &fcresult);
FcPatternReference(m_pattern);
// FIXME: should we set some default font?
if (!m_pattern)
goto freePattern;
FcChar8 *fc_filename;
char *filename;
int id;
id = 0;
if (FcPatternGetString(m_pattern, FC_FILE, 0, &fc_filename) != FcResultMatch) {
DS_WAR("cannot retrieve font\n");
goto freePattern;
}
filename = (char *) fc_filename; //use C cast as FcChar is a fontconfig type
//printf("filename = %s\n", filename);
if (FcPatternGetInteger(m_pattern, FC_INDEX, 0, &id) != FcResultMatch) {
DS_WAR("cannot retrieve font index\n");
goto freePattern;
}
if (FT_Error error = FT_New_Face(m_library, filename, id, &m_face)) {
//if (FT_Error error = FT_New_Face(m_library, too, id, &m_face)) {
DS_WAR("fail to open font" << filename << "with index " << id << " (error = 0x%x)\n" << error);
m_face = 0;
goto freePattern;
}
FT_Set_Pixel_Sizes(m_face, 0, static_cast<uint> (fontDescription.computedSize()));
//DBGML(MODULE_FONTS, LEVEL_INFO, "open font %s with size %d\n", filename, static_cast<uint> (fontDescription.specifiedSize()));
freePattern:
FcPatternDestroy(pattern);
FcConfigDestroy(config);
}
示例7: Java_org_iisc_mile_indictext_android_EditIndicText_drawIndicText
void Java_org_iisc_mile_indictext_android_EditIndicText_drawIndicText(
JNIEnv* env, jobject thiz, jstring unicodeText, jint xStart,
jint yBaseLine, jint charHeight, jobject lock) {
FT_Library ft_library;
FT_Face ft_face;
hb_font_t *font;
hb_buffer_t *buffer;
int glyph_count;
hb_glyph_info_t *glyph_info;
hb_glyph_position_t *glyph_pos;
hb_bool_t fail;
FT_UInt glyph_index;
FT_GlyphSlot slot;
FT_Error error;
char* fontFilePath;
jboolean iscopy;
const jchar *text;
int num_chars, i;
int pen_x;
int glyphPosX, glyphPosY;
fontFilePath =
"/sdcard/Android/data/org.iisc.mile.indictext.android/Lohit-Kannada.ttf";
text = (*env)->GetStringChars(env, unicodeText, &iscopy);
num_chars = (*env)->GetStringLength(env, unicodeText);
error = FT_Init_FreeType(&ft_library); /* initialize library */
if (error) {
__android_log_print(6, "drawIndicText",
"Error initializing FreeType library\n");
return;
}
__android_log_print(2, "drawIndicText",
"Successfully initialized FreeType library\n");
error = FT_New_Face(ft_library, fontFilePath, 0, &ft_face); /* create face object */
if (error == FT_Err_Unknown_File_Format) {
__android_log_print(6, "drawIndicText",
"The font file could be opened and read, but it appears that its font format is unsupported");
return;
} else if (error) {
__android_log_print(6, "drawIndicText",
"The font file could not be opened or read, or it might be broken");
return;
}
__android_log_print(2, "drawIndicText",
"Successfully created font-face object\n");
font = hb_ft_font_create(ft_face, NULL);
error = FT_Set_Pixel_Sizes(ft_face, 0, charHeight); /* set character size */
/* error handling omitted */
__android_log_print(2, "drawIndicText",
"Successfully set character size to %d\n", charHeight);
__android_log_print(2, "drawIndicText", "Text being rendered = %s\n", text);
slot = ft_face->glyph;
pen_x = xStart;
/* Create a buffer for harfbuzz to use */
buffer = hb_buffer_create();
//hb_buffer_set_unicode_funcs(buffer, hb_icu_get_unicode_funcs());
//alternatively you can use hb_buffer_set_unicode_funcs(buffer, hb_glib_get_unicode_funcs());
//hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); /* or LTR */
hb_buffer_set_script(buffer, HB_SCRIPT_KANNADA); /* see hb-unicode.h */
//hb_buffer_set_language(buffer, hb_language_from_string("ka"));
/* Layout the text */
hb_buffer_add_utf16(buffer, text, num_chars, 0, num_chars);
__android_log_print(2, "drawIndicText", "Before HarfBuzz shape()\n");
hb_shape(font, buffer, NULL, 0);
__android_log_print(2, "drawIndicText", "After HarfBuzz shape()\n");
glyph_count = hb_buffer_get_length(buffer);
glyph_info = hb_buffer_get_glyph_infos(buffer, 0);
glyph_pos = hb_buffer_get_glyph_positions(buffer, 0);
for (i = 0; i < glyph_count; i++) {
glyph_index = glyph_info[i].codepoint;
__android_log_print(2, "drawIndicText", "Glyph%d = %x", i, glyph_index);
error = FT_Load_Glyph(ft_face, glyph_index, FT_LOAD_DEFAULT);
if (error) {
continue; /* ignore errors */
}
/* convert to an anti-aliased bitmap */
error = FT_Render_Glyph(ft_face->glyph, FT_RENDER_MODE_NORMAL);
if (error) {
continue;
}
/* now, draw to our target surface (convert position) */
draw_bitmap(&slot->bitmap, pen_x + slot->bitmap_left,
yBaseLine - slot->bitmap_top, env, thiz, lock);
//glyphPosX = pen_x + glyph_pos[i].x_offset;
//.........这里部分代码省略.........
示例8: FT_New_Face
bool Font::allocate(const char *name)
{
this->name = name;
return FT_New_Face(library, name, 0, &face) == 0;
}
示例9: configuration
/*-----------------------------------------------------------------------------------------------
Description:
Governs window creation, the initial OpenGL configuration (face culling, depth mask, even
though this is a 2D demo and that stuff won't be of concern), the creation of geometry, and
the creation of a texture.
Parameters:
argc (From main(...)) The number of char * items in argv. For glut's initialization.
argv (From main(...)) A collection of argument strings. For glut's initialization.
Returns:
False if something went wrong during initialization, otherwise true;
Exception: Safe
Creator:
John Cox (3-7-2016)
-----------------------------------------------------------------------------------------------*/
bool init(int argc, char *argv[])
{
glutInit(&argc, argv);
// I don't know what this is doing, but it has been working, so I'll leave it be for now
int windowWidth = 500; // square 500x500 pixels
int windowHeight = 500;
unsigned int displayMode = GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
displayMode = defaults(displayMode, windowWidth, windowHeight);
glutInitDisplayMode(displayMode);
// create the window
// ??does this have to be done AFTER glutInitDisplayMode(...)??
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(300, 200); // X = 0 is screen left, Y = 0 is screen top
int window = glutCreateWindow(argv[0]);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
// OpenGL 4.3 was where internal debugging was enabled, freeing the user from having to call
// glGetError() and analyzing it after every single OpenGL call, complete with surrounding it
// with #ifdef DEBUG ... #endif blocks
// Note: https://blog.nobel-joergensen.com/2013/02/17/debugging-opengl-part-2-using-gldebugmessagecallback/
int glMajorVersion = 4;
int glMinorVersion = 4;
glutInitContextVersion(glMajorVersion, glMinorVersion);
glutInitContextProfile(GLUT_CORE_PROFILE);
#ifdef DEBUG
glutInitContextFlags(GLUT_DEBUG); // if enabled,
#endif
// glload must load AFTER glut loads the context
glload::LoadTest glLoadGood = glload::LoadFunctions();
if (!glLoadGood) // apparently it has an overload for "bool type"
{
printf("glload::LoadFunctions() failed\n");
return false;
}
else if (!glload::IsVersionGEQ(glMajorVersion, glMinorVersion))
{
// the "is version" check is an "is at least version" check
printf("Your OpenGL version is %i, %i. You must have at least OpenGL %i.%i to run this tutorial.\n",
glload::GetMajorVersion(), glload::GetMinorVersion(), glMajorVersion, glMinorVersion);
glutDestroyWindow(window);
return 0;
}
else if (glext_ARB_debug_output)
{
// condition will be true if GLUT_DEBUG is a context flag
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(DebugFunc, (void*)15);
}
// these OpenGL initializations are for 3D stuff, where depth matters and multiple shapes can
// be "on top" of each other relative to the most distant thing rendered, and this barebones
// code is only for 2D stuff, but initialize them anyway as good practice (??bad idea? only
// use these once 3D becomes a thing??)
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);
glDepthRange(0.0f, 1.0f);
// FreeType needs to load itself into particular variables
// Note: FT_Init_FreeType(...) returns something called an FT_Error, which VS can't find.
// Based on the useage, it is assumed that 0 is returned if something went wrong, otherwise
// non-zero is returned. That is the only explanation for this kind of condition.
if (FT_Init_FreeType(&gFtLib))
{
fprintf(stderr, "Could not init freetype library\n");
return false;
}
// Note: FT_New_Face(...) also returns an FT_Error.
const char *fontFilePath = "FreeSans.ttf"; // file path relative to solution directory
if (FT_New_Face(gFtLib, fontFilePath, 0, &gFtFace))
{
fprintf(stderr, "Could not open font '%s'\n", fontFilePath);
return false;
}
gProgramId = CreateProgram();
// pick out the attributes and uniforms used in the FreeType GPU program
//.........这里部分代码省略.........
示例10: GetFontByFaceName
static FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
{
FT_Error err = FT_Err_Cannot_Open_Resource;
HKEY hKey;
LONG ret;
TCHAR vbuffer[MAX_PATH], dbuffer[256];
TCHAR *font_namep;
char *font_path;
uint index;
/* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the
* "Windows NT" key, on Windows 9x in the Windows key. To save us having
* to retrieve the windows version, we'll just query both */
ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_NT), 0, KEY_READ, &hKey);
if (ret != ERROR_SUCCESS) ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T(FONT_DIR_9X), 0, KEY_READ, &hKey);
if (ret != ERROR_SUCCESS) {
DEBUG(freetype, 0, "Cannot open registry key HKLM\\SOFTWARE\\Microsoft\\Windows (NT)\\CurrentVersion\\Fonts");
return err;
}
/* For Unicode we need some conversion between widechar and
* normal char to match the data returned by RegEnumValue,
* otherwise just use parameter */
#if defined(UNICODE)
font_namep = MallocT<TCHAR>(MAX_PATH);
MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR));
#else
font_namep = const_cast<char *>(font_name); // only cast because in unicode pointer is not const
#endif
for (index = 0;; index++) {
TCHAR *s;
DWORD vbuflen = lengthof(vbuffer);
DWORD dbuflen = lengthof(dbuffer);
ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen);
if (ret != ERROR_SUCCESS) goto registry_no_font_found;
/* The font names in the registry are of the following 3 forms:
* - ADMUI3.fon
* - Book Antiqua Bold (TrueType)
* - Batang & BatangChe & Gungsuh & GungsuhChe (TrueType)
* We will strip the font-type '()' if any and work with the font name
* itself, which must match exactly; if...
* TTC files, font files which contain more than one font are seperated
* byt '&'. Our best bet will be to do substr match for the fontname
* and then let FreeType figure out which index to load */
s = _tcschr(vbuffer, _T('('));
if (s != NULL) s[-1] = '\0';
if (_tcschr(vbuffer, _T('&')) == NULL) {
if (_tcsicmp(vbuffer, font_namep) == 0) break;
} else {
if (_tcsstr(vbuffer, font_namep) != NULL) break;
}
}
if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) {
DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory");
goto folder_error;
}
/* Some fonts are contained in .ttc files, TrueType Collection fonts. These
* contain multiple fonts inside this single file. GetFontData however
* returns the whole file, so we need to check each font inside to get the
* proper font.
* Also note that FreeType does not support UNICODE filesnames! */
#if defined(UNICODE)
/* We need a cast here back from wide because FreeType doesn't support
* widechar filenames. Just use the buffer we allocated before for the
* font_name search */
font_path = (char*)font_namep;
WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR));
#else
font_path = vbuffer;
#endif
ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR));
ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR));
/* Convert the path into something that FreeType understands */
font_path = GetShortPath(font_path);
index = 0;
do {
err = FT_New_Face(_library, font_path, index, face);
if (err != FT_Err_Ok) break;
if (strncasecmp(font_name, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
/* Try english name if font name failed */
if (strncasecmp(font_name + strlen(font_name) + 1, (*face)->family_name, strlen((*face)->family_name)) == 0) break;
err = FT_Err_Cannot_Open_Resource;
} while ((FT_Long)++index != (*face)->num_faces);
folder_error:
registry_no_font_found:
#if defined(UNICODE)
//.........这里部分代码省略.........
示例11: CreateFont
HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic,
char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision,
char lfQuality, char lfPitchAndFamily, const char *lfFaceName)
{
HGDIOBJ__ *font=NULL;
#ifdef SWELL_FREETYPE
FT_Face face=NULL;
if (!s_freetype_failed && !s_freetype) s_freetype_failed = !!FT_Init_FreeType(&s_freetype);
if (s_freetype)
{
if (!lfFaceName || !*lfFaceName) lfFaceName = "Arial";
int fn_len = strlen(lfFaceName);
const char *leadpath = "/usr/share/fonts/truetype/msttcorefonts"; // todo: scan subdirs?
char tmp[1024];
char bestmatch[512];
bestmatch[0]=0;
int x;
for (x=0;x < s_registered_fonts.GetSize(); x ++)
{
const char *fn = s_registered_fonts.Get(x);
if (fn)
{
const char *fnpart = WDL_get_filepart(fn);
if (!strnicmp(fnpart,lfFaceName,strlen(lfFaceName)))
{
FT_New_Face(s_freetype,fn,0,&face);
if (face) break;
}
}
}
if (!face)
{
snprintf(tmp,sizeof(tmp),"%s/%s.ttf",leadpath,lfFaceName);
FT_New_Face(s_freetype,tmp,0,&face);
}
if (!face)
{
WDL_DirScan ds;
if (!ds.First(leadpath)) do
{
if (!strnicmp(ds.GetCurrentFN(),lfFaceName,fn_len))
{
if (!stricmp(ds.GetCurrentFN()+fn_len,".ttf"))
{
snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,ds.GetCurrentFN());
FT_New_Face(s_freetype,tmp,0,&face);
}
else
{
// todo look for italic/bold/etc too
int sl = strlen(ds.GetCurrentFN());
if (sl > 4 && !stricmp(ds.GetCurrentFN() + sl - 4, ".ttf") && (!bestmatch[0] || sl < strlen(bestmatch)))
{
lstrcpyn_safe(bestmatch,ds.GetCurrentFN(),sizeof(bestmatch));
}
}
}
} while (!face && !ds.Next());
if (!face && bestmatch[0])
{
snprintf(tmp,sizeof(tmp),"%s/%s",leadpath,bestmatch);
FT_New_Face(s_freetype,tmp,0,&face);
}
}
if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/freefont/FreeSans.ttf",0,&face);
if (!face) FT_New_Face(s_freetype,"/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",0,&face);
}
if (face)
{
font = GDP_OBJECT_NEW();
font->type=TYPE_FONT;
font->fontface = face;
font->alpha = 1.0f;
////unsure here
if (lfWidth<0) lfWidth=-lfWidth;
if (lfHeight<0) lfHeight=-lfHeight;
FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi
// FT_Set_Pixel_Sizes(face,0,lfHeight);
}
#else
font->type=TYPE_FONT;
#endif
return font;
}
示例12: EnumerateFiles
void InstalledFontList::Load()
{
if (isLoaded) return;
isLoaded = true;
std::vector<std::string> paths;
#ifdef _WIN32
EnumerateFiles("C:\\Windows\\Fonts\\", paths);
#elif defined __APPLE__
EnumerateFiles("/System/Library/Fonts/", paths);
EnumerateFiles("/Library/Fonts/", paths);
#endif
FT_Library library = nullptr;
auto error = FT_Init_FreeType(&library);
for (auto& path : paths)
{
auto ext_ = GetFileExt(path.c_str());
std::string ext(ext_);
std::transform(ext_.begin(), ext_.end(), ext.begin(), tolower_);
// fonはアウトラインでないので未対応
if (ext == std::string("fon"))
{
continue;
}
FT_Face face = nullptr;
FT_New_Face(library, path.c_str(), 0, &face);
if (face == nullptr) continue;
Font font;
font.Name = ToAString(face->family_name);
font.Path = ToAString(path.c_str());
Fonts.push_back(font);
FT_Done_Face(face);
}
FT_Done_FreeType(library);
// レジストリだとフルネームが長い
/*
HKEY fontKey;
// レジストリを開く
auto r = RegOpenKeyExA(
HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Fonts",
0,
KEY_READ,
&fontKey);
if (r != ERROR_SUCCESS) return;
for (auto ind = 0;; ind++)
{
char valueName[1000];
DWORD valueNameSize = 1000;
char value[1000];
DWORD valueSize = 1000;
DWORD valueType;
auto result = SHEnumValueA(
fontKey,
ind,
valueName,
&valueNameSize,
&valueType,
value,
&valueSize);
if (result != ERROR_SUCCESS) break;
Font font;
font.Name = ToAString(valueName);
font.Path = ToAString(value);
Fonts.push_back(font);
}
// 終了
RegCloseKey(fontKey);
*/
}
示例13: glDeleteTextures
//------------------------------------------------------------------
void urFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, bool makeContours){
bMakeContours = makeContours;
//------------------------------------------------
if (bLoadedOk == true){
// we've already been loaded, try to clean up :
if (cps != NULL){
delete[] cps;
}
if (texNames != NULL){
for (int i = 0; i < nCharacters; i++){
glDeleteTextures(1, &texNames[i]);
}
delete[] texNames;
}
bLoadedOk = false;
}
//------------------------------------------------
filename = ofToDataPath(filename);
bLoadedOk = false;
bAntiAlised = _bAntiAliased;
bFullCharacterSet = _bFullCharacterSet;
fontSize = fontsize;
//--------------- load the library and typeface
FT_Library library;
if (FT_Init_FreeType( &library )){
// ofLog(OF_LOG_ERROR," PROBLEM WITH FT lib");
return;
}
FT_Face face;
if (FT_New_Face( library, filename.c_str(), 0, &face )) {
return;
}
FT_Set_Char_Size( face, fontsize << 6, fontsize << 6, 96, 96);
lineHeight = fontsize * 1.43f;
//------------------------------------------------------
//kerning would be great to support:
//ofLog(OF_LOG_NOTICE,"FT_HAS_KERNING ? %i", FT_HAS_KERNING(face));
//------------------------------------------------------
nCharacters = bFullCharacterSet ? 256 : 128 - NUM_CHARACTER_TO_START;
//--------------- initialize character info and textures
cps = new charProps[nCharacters];
texNames = new GLuint[nCharacters];
glGenTextures(nCharacters, texNames);
if(bMakeContours){
charOutlines.clear();
charOutlines.assign(nCharacters, ofTTFCharacter());
}
//--------------------- load each char -----------------------
for (int i = 0 ; i < nCharacters; i++){
//------------------------------------------ anti aliased or not:
if(FT_Load_Glyph( face, FT_Get_Char_Index( face, (unsigned char)(i+NUM_CHARACTER_TO_START) ), FT_LOAD_DEFAULT )){
// ofLog(OF_LOG_ERROR,"error with FT_Load_Glyph %i", i);
}
if (bAntiAlised == true) FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
else FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
//------------------------------------------
FT_Bitmap& bitmap= face->glyph->bitmap;
// 3 pixel border around the glyph
// We show 2 pixels of this, so that blending looks good.
// 1 pixels is hidden because we don't want to see the real edge of the texture
border = 3;
visibleBorder = 2;
if(bMakeContours){
if( printVectorInfo )printf("\n\ncharacter %c: \n", char( i+NUM_CHARACTER_TO_START ) );
//int character = i + NUM_CHARACTER_TO_START;
charOutlines[i] = makeContoursForCharacter( face );
}
// prepare the texture:
int width = ofNextPow2( bitmap.width + border*2 );
int height = ofNextPow2( bitmap.rows + border*2 );
// ------------------------- this is fixing a bug with small type
// ------------------------- appearantly, opengl has trouble with
// ------------------------- width or height textures of 1, so we
//.........这里部分代码省略.........
示例14: PsychRebuildFont
//.........这里部分代码省略.........
NULL);
}
// Set default settings for missing pattern properties:
FcDefaultSubstitute(target);
if (!FcConfigSubstitute(NULL, target, FcMatchPattern)) {
// Failed!
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig failed to substitute default properties for family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
FcPatternDestroy(target);
return(1);
}
// Have a matching pattern:
if (_verbosity > 3) {
fprintf(stderr, "libptbdrawtext_ftgl: Trying to find font that closely matches following specification:\n");
FcPatternPrint(target);
}
// Perform font matching for the font in the default configuration (0) that best matches the
// specified target pattern:
FcPattern* matched = FcFontMatch(NULL, target, &result);
if ((matched == NULL) || (result == FcResultNoMatch)) {
// Failed!
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig failed to find a matching font for family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
FcPatternDestroy(target);
return(1);
}
// Success: Extract relevant information for Freetype-2, the font filename and faceIndex:
if (_verbosity > 3) {
fprintf(stderr, "libptbdrawtext_ftgl: Best matching font which will be selected for drawing has following specs:\n");
FcPatternPrint(matched);
}
// Retrieve font filename for matched font:
FcChar8* localfontFileName = NULL;
if (FcPatternGetString(matched, FC_FILE, 0, (FcChar8**) &localfontFileName) != FcResultMatch) {
// Failed!
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find filename for font with family %s, size %f pts and style flags %i.\n", _fontName, (float) _fontSize, _fontStyle);
FcPatternDestroy(target);
FcPatternDestroy(matched);
return(1);
}
strcpy(_fontFileName, (char*) localfontFileName);
// Retrieve faceIndex within fontfile:
if (FcPatternGetInteger(matched, FC_INDEX, 0, &_faceIndex) != FcResultMatch) {
// Failed!
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: FontConfig did not find faceIndex for font file %s, family %s, size %f pts and style flags %i.\n", _fontFileName, _fontName, (float) _fontSize, _fontStyle);
FcPatternDestroy(target);
FcPatternDestroy(matched);
return(1);
}
// Release target pattern and matched pattern objects:
FcPatternDestroy(target);
FcPatternDestroy(matched);
}
else {
// Use "raw" values as passed by calling client code:
strcpy(_fontFileName, _fontName);
_faceIndex = (int) _fontStyle;
}
// Load & Create new font and face object, based on current spec settings:
// We directly use the Freetype library, so we can spec the faceIndex for selection of textstyle, which wouldn't be
// possible with the higher-level OGLFT constructor...
FT_Error error = FT_New_Face( OGLFT::Library::instance(), _fontFileName, _faceIndex, &ft_face );
if (error) {
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not load face with index %i from font file %s.\n", _faceIndex, _fontFileName);
return(1);
}
else {
if (_verbosity > 3) fprintf(stderr, "libptbdrawtext_ftgl: Freetype loaded face %p with index %i from font file %s.\n", ft_face, _faceIndex, _fontFileName);
}
// Create FTGL face from Freetype face with given size and a 72 DPI resolution, aka _fontSize == pixelsize:
if (_antiAliasing != 0) {
faceT = new OGLFT::TranslucentTexture(ft_face, _fontSize, 72);
// Test the created face to make sure it will work correctly:
if (!faceT->isValid()) {
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
return(1);
}
}
else {
faceM = new OGLFT::MonochromeTexture(ft_face, _fontSize, 72);
// Test the created face to make sure it will work correctly:
if (!faceM->isValid()) {
if (_verbosity > 1) fprintf(stderr, "libptbdrawtext_ftgl: Freetype did not recognize %s as a font file.\n", _fontName);
return(1);
}
}
// Ready!
_needsRebuild = false;
return(0);
}
示例15: load_glyph
// ------------------------------------------------------------- load_glyph ---
texture_glyph_t *
load_glyph( const char * filename, const wchar_t charcode,
const float highres_size, const float lowres_size,
const float padding )
{
size_t i, j;
FT_Library library;
FT_Face face;
FT_Init_FreeType( &library );
FT_New_Face( library, filename, 0, &face );
FT_Select_Charmap( face, FT_ENCODING_UNICODE );
FT_UInt glyph_index = FT_Get_Char_Index( face, charcode );
// Render glyph at high resolution (highres_size points)
FT_Set_Char_Size( face, highres_size*64, 0, 72, 72 );
FT_Load_Glyph( face, glyph_index,
FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
FT_GlyphSlot slot = face->glyph;
FT_Bitmap bitmap = slot->bitmap;
// Allocate high resolution buffer
size_t highres_width = bitmap.width + 2*padding*highres_size;
size_t highres_height = bitmap.rows + 2*padding*highres_size;
double * highres_data = (double *) malloc( highres_width*highres_height*sizeof(double) );
memset( highres_data, 0, highres_width*highres_height*sizeof(double) );
// Copy high resolution bitmap with padding and normalize values
for( j=0; j < bitmap.rows; ++j )
{
for( i=0; i < bitmap.width; ++i )
{
int x = i + padding;
int y = j + padding;
highres_data[y*highres_width+x] = bitmap.buffer[j*bitmap.width+i]/255.0;
}
}
// Compute distance map
distance_map( highres_data, highres_width, highres_height );
// Allocate low resolution buffer
size_t lowres_width = round(highres_width * lowres_size/highres_size);
size_t lowres_height = round(highres_height * lowres_width/(float) highres_width);
double * lowres_data = (double *) malloc( lowres_width*lowres_height*sizeof(double) );
memset( lowres_data, 0, lowres_width*lowres_height*sizeof(double) );
// Scale down highres buffer into lowres buffer
resize( highres_data, highres_width, highres_height,
lowres_data, lowres_width, lowres_height );
// Convert the (double *) lowres buffer into a (unsigned char *) buffer and
// rescale values between 0 and 255.
unsigned char * data =
(unsigned char *) malloc( lowres_width*lowres_height*sizeof(unsigned char) );
for( j=0; j < lowres_height; ++j )
{
for( i=0; i < lowres_width; ++i )
{
double v = lowres_data[j*lowres_width+i];
data[j*lowres_width+i] = (int) (255*(1-v));
}
}
// Compute new glyph information from highres value
float ratio = lowres_size / highres_size;
size_t pitch = lowres_width * sizeof( unsigned char );
// Create glyph
texture_glyph_t * glyph = texture_glyph_new( );
glyph->offset_x = (slot->bitmap_left + padding*highres_width) * ratio;
glyph->offset_y = (slot->bitmap_top + padding*highres_height) * ratio;
glyph->width = lowres_width;
glyph->height = lowres_height;
glyph->charcode = charcode;
/*
printf( "Glyph width: %ld\n", glyph->width );
printf( "Glyph height: %ld\n", glyph->height );
printf( "Glyph offset x: %d\n", glyph->offset_x );
printf( "Glyph offset y: %d\n", glyph->offset_y );
*/
ivec4 region = texture_atlas_get_region( atlas, glyph->width, glyph->height );
/*
printf( "Region x : %d\n", region.x );
printf( "Region y : %d\n", region.y );
printf( "Region width : %d\n", region.width );
printf( "Region height : %d\n", region.height );
*/
texture_atlas_set_region( atlas, region.x, region.y, glyph->width, glyph->height, data, pitch );
glyph->s0 = region.x/(float)atlas->width;
glyph->t0 = region.y/(float)atlas->height;
glyph->s1 = (region.x + glyph->width)/(float)atlas->width;
glyph->t1 = (region.y + glyph->height)/(float)atlas->height;
FT_Load_Glyph( face, glyph_index,
FT_LOAD_RENDER | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT);
glyph->advance_x = ratio * face->glyph->advance.x/64.0;
glyph->advance_y = ratio * face->glyph->advance.y/64.0;
/*
//.........这里部分代码省略.........