本文整理汇总了C++中FT_Load_Glyph函数的典型用法代码示例。如果您正苦于以下问题:C++ FT_Load_Glyph函数的具体用法?C++ FT_Load_Glyph怎么用?C++ FT_Load_Glyph使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了FT_Load_Glyph函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Font
void Label::makeFont(string f)
{
if(fonts.find(f) != fonts.end())
{
font = fonts[f];
return;
}
string floc = Location + f + ".ttf";
font = fonts[f] = new Font();
font->point = 200;
// Create And Initilize A FreeType Font Library.
FT_Init_FreeType( &ft );
// This Is Where We Load In The Font Information From The File.
// Of All The Places Where The Code Might Die, This Is The Most Likely,
// As FT_New_Face Will Fail If The Font File Does Not Exist Or Is Somehow Broken.
if (FT_New_Face( ft, floc.c_str(), 0, &font->face ))
return;
// For Some Twisted Reason, FreeType Measures Font Size
// In Terms Of 1/64ths Of Pixels. Thus, To Make A Font
// h Pixels High, We Need To Request A Size Of h*64.
// (h << 6 Is Just A Prettier Way Of Writing h*64)
FT_Set_Char_Size( font->face, font->point * 64, font->point * 64, 96, 96);
bool use_kerning = FT_HAS_KERNING( font->face );
for(unsigned char c=0; c<128; c++)
{
// The First Thing We Do Is Get FreeType To Render Our Character
// Into A Bitmap. This Actually Requires A Couple Of FreeType Commands:
// Load The Glyph For Our Character.
if(FT_Load_Glyph( font->face, FT_Get_Char_Index( font->face, c ), FT_LOAD_DEFAULT ))
return;
// Move The Face's Glyph Into A Glyph Object.
FT_Glyph glyph;
if(FT_Get_Glyph( font->face->glyph, &glyph ))
return;
// Convert The Glyph To A Bitmap.
FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
// This Reference Will Make Accessing The Bitmap Easier.
FT_Bitmap& bitmap=bitmap_glyph->bitmap;
// Use Our Helper Function To Get The Widths Of
// The Bitmap Data That We Will Need In Order To Create
// Our Texture.
int downsample = 8;
int width = next_p2( bitmap.width + 4 * downsample );
int height = next_p2( bitmap.rows + 4 * downsample );
float xs = (float)bitmap.width / width;
float ys = (float)bitmap.rows / height;
width /= downsample;
height /= downsample;
// Allocate Memory For The Texture Data.
GLubyte* tex = (GLubyte*)malloc(width * height);
memset(tex, 0, width*height);
for(int i=0; i < width; i++)
for(int j=0; j < height; j++)
{
tex[i + j*width]= edgeDistance(bitmap.buffer, bitmap.width, bitmap.rows, (i)/xs/width, (j)/ys/height, 1.0);
}
glGenTextures(1, &font->chars[c]);
glBindTexture(GL_TEXTURE_2D, font->chars[c]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex);
for(int k=0; k<128; k++)
{
if(use_kerning)
{
FT_Vector kern;
FT_Get_Kerning( font->face,
FT_Get_Char_Index( font->face, c ),
FT_Get_Char_Index( font->face, k ),
FT_KERNING_DEFAULT,
&kern );
font->kerning[c][k] = (font->face->glyph->advance.x + kern.x) / (font->point * 64.0f);
}
else
{
font->kerning[c][k] = font->face->glyph->advance.x / (font->point * 64.0f);
}
//.........这里部分代码省略.........
示例2: geCreateFontTtf
void geCreateFontTtf(ge_Font* font){
FT_GlyphSlot slot = ((FT_Face)font->face)->glyph;
u16 n;
u16 chr = 0;
int x = 0;
int y = font->size;
bool first_null_char = true;
int total_width = 0;
for(n=0; n<256; n++){
chr = n;
FT_UInt glyph_index = FT_Get_Char_Index((FT_Face)font->face, chr);
int error = FT_Load_Glyph((FT_Face)font->face, glyph_index, FT_LOAD_DEFAULT);
if (error) continue;
error = FT_Render_Glyph(((FT_Face)font->face)->glyph, ft_render_mode_normal);
if (error) continue;
if(!glyph_index && !first_null_char){
continue;
}
total_width += slot->bitmap.width;
first_null_char = false;
}
if(font->texture)geFreeImage(font->texture);
#ifdef PSP
ge_Image* dest = geCreateSurface(512, 512, 0x00000000);
#else
// ge_Image* dest = geCreateSurface(1024, 1024, 0x00000000);
ge_Image* dest = geCreateSurface(font->size*16*1.5, font->size*16*1.5, 0x00000000);
#endif
font->texture = dest;
first_null_char = true;
for(n=0; n<256; n++){
chr = n;
FT_UInt glyph_index = FT_Get_Char_Index((FT_Face)font->face, chr);
int error = FT_Load_Glyph((FT_Face)font->face, glyph_index, FT_LOAD_DEFAULT);
if (error) continue;
error = FT_Render_Glyph(((FT_Face)font->face)->glyph, ft_render_mode_normal);
if (error) continue;
if(x+(slot->advance.x>>6) > dest->width){
x = 0;
y += font->size * 1.5;
}
font->positions[n].x = x;
if(font->positions[n].x<0)font->positions[n].x=0;
font->positions[n].y = y - slot->bitmap_top;
font->positions[n].w = slot->bitmap.width + slot->bitmap_left;
font->positions[n].h = slot->bitmap.rows;
font->positions[n].advX = slot->advance.x >> 6;
font->positions[n].posY = slot->bitmap_top;
if(!glyph_index && !first_null_char){
continue;
}
// fontPrintTextImage(&slot->bitmap, x + slot->bitmap_left, y - slot->bitmap_top, 0xffffffff, dest);
fontPrintTextImpl2(&slot->bitmap, x + slot->bitmap_left, y - slot->bitmap_top, 0xffffffff, dest->data, dest->width, dest->height, dest->textureWidth);
/*
int jump = slot->bitmap.width;
int jump2 = slot->advance.x >> 6;
if(jump2 > jump){
jump = jump2;
}
jump = slot->bitmap.width + (slot->advance.x >> 6);
x += jump;
*/
// x += slot->advance.x >> 6;
x += font->size;
// y += slot->advance.y >> 6;
first_null_char = false;
}
// geSwizzle(dest);
geUpdateImage(dest);
}
示例3: clear_bitmaps
void FontRenderer::rasterize() {
clear_bitmaps();
if (!m_ft_face) {
return;
}
qDebug() << " begin rasterize_font ";
if (m_config->italic()!=0) {
FT_Matrix matrix;
const float angle = (-M_PI*m_config->italic()) / 180.0f;
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( 0/*sin( angle )*/ * 0x10000L );
matrix.yy = (FT_Fixed)( 1/*cos( angle )*/ * 0x10000L );
FT_Set_Transform(m_ft_face,&matrix,0);
} else {
FT_Set_Transform(m_ft_face,0,0);
}
/// fill metrics
if (FT_IS_SCALABLE(m_ft_face)) {
m_rendered.metrics.ascender = m_ft_face->size->metrics.ascender / 64;
m_rendered.metrics.descender = m_ft_face->size->metrics.descender/ 64;
m_rendered.metrics.height = m_ft_face->size->metrics.height/ 64;
} else {
m_rendered.metrics.ascender = m_ft_face->ascender;
m_rendered.metrics.descender = m_ft_face->descender;
m_rendered.metrics.height = m_ft_face->height;
}
bool use_kerning = FT_HAS_KERNING( m_ft_face );
const ushort* chars = m_config->characters().utf16();
size_t amount = 0;
while (chars[amount]!=0) amount++;
int error = 0;
for (size_t i=0;i<amount;i++) {
int glyph_index = FT_Get_Char_Index( m_ft_face, chars[i] );
if (glyph_index==0 && !m_config->renderMissing())
continue;
FT_Int32 flags = FT_LOAD_DEFAULT;
if (!m_config->antialiased()) {
flags = flags | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO;
} else {
flags = flags | FT_LOAD_TARGET_NORMAL;
}
switch (m_config->hinting()) {
case FontConfig::HintingDisable:
flags = flags | FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
break;
case FontConfig::HintingForceFreetypeAuto:
flags = flags | FT_LOAD_FORCE_AUTOHINT;
break;
case FontConfig::HintingDisableFreetypeAuto:
flags = flags | FT_LOAD_NO_AUTOHINT;
break;
default:
break;
}
error = FT_Load_Glyph( m_ft_face, glyph_index, flags );
if ( error )
continue;
if (m_config->bold()!=0) {
FT_Pos strength = m_config->size()*m_config->bold();
if ( m_ft_face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
FT_Outline_Embolden( &m_ft_face->glyph->outline, strength );
}
if (m_ft_face->glyph->format!=FT_GLYPH_FORMAT_BITMAP) {
error = FT_Render_Glyph( m_ft_face->glyph,
m_config->antialiased() ? FT_RENDER_MODE_NORMAL:FT_RENDER_MODE_MONO );
}
if ( error )
continue;
if (append_bitmap(chars[i])) {
if (use_kerning)
append_kerning(chars[i],chars,amount);
}
}
imagesChanged(m_chars);
imagesChanged();
}
示例4: 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;
/*
//.........这里部分代码省略.........
示例5: ass_font_get_glyph
/**
* \brief Get a glyph
* \param ch character code
**/
FT_Glyph ass_font_get_glyph(void* fontconfig_priv, ass_font_t* font, uint32_t ch, ass_hinting_t hinting)
{
int error;
int index = 0;
int i;
FT_Glyph glyph;
FT_Face face = 0;
int flags = 0;
if (ch < 0x20)
return 0;
if (font->n_faces == 0)
return 0;
for (i = 0; i < font->n_faces; ++i) {
face = font->faces[i];
index = FT_Get_Char_Index(face, ch);
if (index)
break;
}
#ifdef HAVE_FONTCONFIG
if (index == 0) {
int face_idx;
mp_msg(MSGT_ASS, MSGL_INFO, MSGTR_LIBASS_GlyphNotFoundReselectingFont,
ch, font->desc.family, font->desc.bold, font->desc.italic);
face_idx = add_face(fontconfig_priv, font, ch);
face = font->faces[face_idx];
index = FT_Get_Char_Index(face, ch);
if (index == 0) {
mp_msg(MSGT_ASS, MSGL_ERR, MSGTR_LIBASS_GlyphNotFound,
ch, font->desc.family, font->desc.bold, font->desc.italic);
}
}
#endif
switch (hinting) {
case ASS_HINTING_NONE: flags = FT_LOAD_NO_HINTING; break;
case ASS_HINTING_LIGHT: flags = FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT; break;
case ASS_HINTING_NORMAL: flags = FT_LOAD_FORCE_AUTOHINT; break;
case ASS_HINTING_NATIVE: flags = 0; break;
}
error = FT_Load_Glyph(face, index, FT_LOAD_NO_BITMAP | flags);
if (error) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
return 0;
}
#if (FREETYPE_MAJOR > 2) || \
((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR >= 2)) || \
((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 1) && (FREETYPE_PATCH >= 10))
// FreeType >= 2.1.10 required
if (!(face->style_flags & FT_STYLE_FLAG_ITALIC) &&
(font->desc.italic > 55)) {
FT_GlyphSlot_Oblique(face->glyph);
}
#endif
error = FT_Get_Glyph(face->glyph, &glyph);
if (error) {
mp_msg(MSGT_ASS, MSGL_WARN, MSGTR_LIBASS_ErrorLoadingGlyph);
return 0;
}
return glyph;
}
示例6: createGlyph
void font_data::createGlyph(CharacterCode charCode) const
{
if (FT_Load_Glyph(_face, FT_Get_Char_Index(_face, charCode), FT_LOAD_DEFAULT))
{
LogError << "FT_Load_Glyph failed" << std::endl;
throw std::runtime_error("FT_Load_Glyph failed");
}
FT_Glyph glyph;
if (FT_Get_Glyph(_face->glyph, &glyph))
{
LogError << "FT_Get_Glyph failed" << std::endl;
throw std::runtime_error("FT_Get_Glyph failed");
}
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
FT_BitmapGlyph bitmap_glyph(reinterpret_cast<FT_BitmapGlyph>(glyph));
const FT_Bitmap& bitmap = bitmap_glyph->bitmap;
const int width(next_p2(bitmap.width + 1));
const int height(next_p2(bitmap.rows + 1));
const size_t expanded_size(width * height * 2);
GLubyte* expanded_data = new GLubyte[expanded_size];
memset(expanded_data, 0, expanded_size);
for (int j(0); j < height; ++j)
{
for (int i(0); i < width; ++i)
{
expanded_data[2 * (i + j * width)] = expanded_data[2 * (i + j * width) + 1] =
(i >= bitmap.width || j >= bitmap.rows) ?
0 : static_cast<GLubyte>(std::min(static_cast<float>(bitmap.buffer[i + bitmap.width * j]) * 1.5f, 255.0f));
}
}
GlyphData glyphData;
glyphData._width = _face->glyph->advance.x >> 6;
glyphData._texture = new OpenGL::Texture();
glyphData._texture->bind();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
delete[] expanded_data;
expanded_data = NULL;
glyphData._callList = new OpenGL::CallList();
glyphData._callList->startRecording();
glyphData._texture->bind();
const float xl((const float)bitmap_glyph->left);
const float xh(xl + width);
const float yl((const float)h - bitmap_glyph->top);
const float yh(yl + height);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(xl, yl);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(xl, yh);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(xh, yl);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(xh, yh);
glEnd();
glTranslatef(static_cast<float>(glyphData._width), 0.0f, 0.0f);
glyphData._callList->endRecording();
_cachedGlyphs[charCode] = glyphData;
}
示例7: MakeSpace
bool CGLFTFont::MakeSymbol(FT_Face face, uint index, bool blend)
{
GLuint list = m_lists + index;
CGLTexture& texture = m_textures[index];
char Symbol = index + startsymbol;
if ( Symbol == ' ' )
return MakeSpace( index );
uint CharIndex = FT_Get_Char_Index( face, Symbol );
int error = FT_Load_Glyph( face, CharIndex, FT_LOAD_DEFAULT );
if( error != 0 )
return false;
FT_Glyph glyph;
error = FT_Get_Glyph( face->glyph, &glyph );
if( error != 0 )
return false;
//!!******************************
FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
FT_Bitmap& bitmap = bitmap_glyph->bitmap;
//!!***********************
int& bit_width = bitmap.width;
int& bit_height = bitmap.rows;
m_widths[index] = bit_width;
int tex_width = next_p2( bit_width );
int tex_height = next_p2( bit_height );
// Выделим память для данных текстуры.
size_t size = 2 * tex_width * tex_height;
GLubyte* texture_data = new GLubyte[ size ];
memset( texture_data, 0, size );
for(int y = 0; y < bit_height; ++y)
for(int x=0; x < bit_width; ++x)
{
if (blend == false)
{
texture_data[2 * ( x + y*tex_width )] = 0xFF;
if ( bitmap.buffer[x + bit_width*y] < 0x80)
texture_data[2 * (x + y*tex_width) + 1] = 0;
else
texture_data[2 *( x + y*tex_width) + 1] = 0xFF;
}
else
{
texture_data[ 2 * (x + y*tex_width) ] = 0xFF;
texture_data[2 * (x + y*tex_width) + 1] = bitmap.buffer[x + bit_width*y];
}
}
texture.Load( tex_width, tex_height, GL_UNSIGNED_BYTE, texture_data, GL_RGBA, 0 ,0, GL_LUMINANCE_ALPHA );
texture.SetParametr( GL_TEXTURE_MAG_FILTER, GL_LINEAR );
texture.SetParametr( GL_TEXTURE_MIN_FILTER, GL_LINEAR );
delete []texture_data;
glNewList( list, GL_COMPILE );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
texture.Bind();
double xscale = (double)bit_width / (double)tex_width;
double yscale = (double)bit_height / (double)tex_height;
glMatrixMode(GL_MODELVIEW);
int downshift = 0 - (bitmap_glyph->top - bit_height);
if ( downshift > 0 )
{
if ( m_downshift < downshift )
m_downshift = downshift;
glPushMatrix();
glTranslatef(0,-downshift,0);
}
glBegin(GL_QUADS);
glTexCoord2d(0,0);
glVertex2f(0,bitmap.rows);
glTexCoord2d(0,yscale);
glVertex2f(0,0);
glTexCoord2d(xscale,yscale);
glVertex2f(bitmap.width,0);
glTexCoord2d(xscale,0);
glVertex2f(bitmap.width,bitmap.rows);
glEnd();
if ( downshift > 0 )
glPopMatrix();
glTranslatef( bit_width + m_symbolspacer, 0, 0 );
//.........这里部分代码省略.........
示例8: FT_Get_Char_Index
bool Font::insertGlyph(Char character) {
FT_Error error;
FT_UInt glyphIndex = FT_Get_Char_Index(m_face, character);
if(!glyphIndex) {
insertPlaceholderGlyph(character);
return false;
}
error = FT_Load_Glyph(m_face, glyphIndex, FT_LOAD_FORCE_AUTOHINT);
if(error) {
insertPlaceholderGlyph(character);
return false;
}
error = FT_Render_Glyph(m_face->glyph, FT_RENDER_MODE_NORMAL);
if(error) {
insertPlaceholderGlyph(character);
return false;
}
// Fill in info for this glyph.
Glyph & glyph = m_glyphs[character];
glyph.index = glyphIndex;
glyph.size.x = m_face->glyph->bitmap.width;
glyph.size.y = m_face->glyph->bitmap.rows;
glyph.advance.x = float(m_face->glyph->linearHoriAdvance) / 65536.f;
glyph.advance.y = float(m_face->glyph->linearVertAdvance) / 65536.f;
glyph.lsb_delta = m_face->glyph->lsb_delta;
glyph.rsb_delta = m_face->glyph->rsb_delta;
glyph.draw_offset.x = m_face->glyph->bitmap_left;
glyph.draw_offset.y = m_face->glyph->bitmap_top - m_face->glyph->bitmap.rows;
glyph.uv_start = Vec2f_ZERO;
glyph.uv_end = Vec2f_ZERO;
glyph.texture = 0;
// Some glyphs like spaces have a size of 0...
if(glyph.size.x != 0 && glyph.size.y != 0) {
Image imgGlyph;
imgGlyph.create(size_t(glyph.size.x), size_t(glyph.size.y), Image::Format_A8);
FT_Bitmap * srcBitmap = &m_face->glyph->bitmap;
arx_assert(srcBitmap->pitch >= 0);
arx_assert(unsigned(srcBitmap->pitch) == unsigned(srcBitmap->width));
// Copy pixels
unsigned char * src = srcBitmap->buffer;
unsigned char * dst = imgGlyph.getData();
memcpy(dst, src, glyph.size.x * glyph.size.y);
Vec2i offset;
if(!m_textures->insertImage(imgGlyph, glyph.texture, offset)) {
LogWarning << "Could not upload glyph for character U+" << std::hex << character
<< " (" << util::encode<util::UTF8>(character) << ") in font "
<< m_info.name;
insertPlaceholderGlyph(character);
return false;
}
// Compute UV mapping for each glyph.
const float textureSize = float(m_textures->getTextureSize());
glyph.uv_start = Vec2f(offset) / Vec2f(textureSize);
glyph.uv_end = Vec2f(offset + glyph.size) / Vec2f(textureSize);
}
return true;
}
示例9: GetFontFace
const Sprite *GetGlyph(FontSize size, WChar key)
{
FT_Face face = GetFontFace(size);
FT_GlyphSlot slot;
GlyphEntry new_glyph;
GlyphEntry *glyph;
SpriteLoader::Sprite sprite;
int width;
int height;
int x;
int y;
assert(IsPrintable(key));
/* Bail out if no face loaded, or for our special characters */
if (face == NULL || (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END)) {
SpriteID sprite = GetUnicodeGlyph(size, key);
if (sprite == 0) sprite = GetUnicodeGlyph(size, '?');
return GetSprite(sprite, ST_FONT);
}
/* Check for the glyph in our cache */
glyph = GetGlyphPtr(size, key);
if (glyph != NULL && glyph->sprite != NULL) return glyph->sprite;
slot = face->glyph;
bool aa = GetFontAAState(size);
FT_UInt glyph_index = FT_Get_Char_Index(face, key);
if (glyph_index == 0) {
if (key == '?') {
/* The font misses the '?' character. Use sprite font. */
SpriteID sprite = GetUnicodeGlyph(size, key);
Sprite *spr = (Sprite*)GetRawSprite(sprite, ST_FONT, AllocateFont);
assert(spr != NULL);
new_glyph.sprite = spr;
new_glyph.width = spr->width + (size != FS_NORMAL);
SetGlyphPtr(size, key, &new_glyph, false);
return new_glyph.sprite;
} else {
/* Use '?' for missing characters. */
GetGlyph(size, '?');
glyph = GetGlyphPtr(size, '?');
SetGlyphPtr(size, key, glyph, true);
return glyph->sprite;
}
}
FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
FT_Render_Glyph(face->glyph, aa ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
/* Despite requesting a normal glyph, FreeType may have returned a bitmap */
aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
/* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */
width = max(1, slot->bitmap.width + (size == FS_NORMAL));
height = max(1, slot->bitmap.rows + (size == FS_NORMAL));
/* Limit glyph size to prevent overflows later on. */
if (width > 256 || height > 256) usererror("Font glyph is too large");
/* FreeType has rendered the glyph, now we allocate a sprite and copy the image into it */
sprite.AllocateData(width * height);
sprite.width = width;
sprite.height = height;
sprite.x_offs = slot->bitmap_left;
sprite.y_offs = _ascender[size] - slot->bitmap_top;
/* Draw shadow for medium size */
if (size == FS_NORMAL) {
for (y = 0; y < slot->bitmap.rows; y++) {
for (x = 0; x < slot->bitmap.width; x++) {
if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR;
sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
}
}
}
}
for (y = 0; y < slot->bitmap.rows; y++) {
for (x = 0; x < slot->bitmap.width; x++) {
if (aa ? (slot->bitmap.buffer[x + y * slot->bitmap.pitch] > 0) : HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
sprite.data[x + y * sprite.width].m = FACE_COLOUR;
sprite.data[x + y * sprite.width].a = aa ? slot->bitmap.buffer[x + y * slot->bitmap.pitch] : 0xFF;
}
}
}
new_glyph.sprite = BlitterFactoryBase::GetCurrentBlitter()->Encode(&sprite, AllocateFont);
new_glyph.width = slot->advance.x >> 6;
SetGlyphPtr(size, key, &new_glyph);
return new_glyph.sprite;
}
示例10: blf_glyph_search
GlyphBLF *blf_glyph_add(FontBLF *font, unsigned int index, unsigned int c)
{
FT_GlyphSlot slot;
GlyphBLF *g;
FT_Error err;
FT_Bitmap bitmap, tempbitmap;
int sharp = (U.text_render & USER_TEXT_DISABLE_AA);
FT_BBox bbox;
unsigned int key;
g = blf_glyph_search(font->glyph_cache, c);
if (g)
return g;
if (sharp)
err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_MONO);
else
err = FT_Load_Glyph(font->face, (FT_UInt)index, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP); /* Sure about NO_* flags? */
if (err)
return NULL;
/* get the glyph. */
slot = font->face->glyph;
if (sharp) {
err = FT_Render_Glyph(slot, FT_RENDER_MODE_MONO);
/* Convert result from 1 bit per pixel to 8 bit per pixel */
/* Accum errors for later, fine if not interested beyond "ok vs any error" */
FT_Bitmap_New(&tempbitmap);
err += FT_Bitmap_Convert(font->ft_lib, &slot->bitmap, &tempbitmap, 1); /* Does Blender use Pitch 1 always? It works so far */
err += FT_Bitmap_Copy(font->ft_lib, &tempbitmap, &slot->bitmap);
err += FT_Bitmap_Done(font->ft_lib, &tempbitmap);
}
else {
err = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
}
if (err || slot->format != FT_GLYPH_FORMAT_BITMAP)
return NULL;
g = (GlyphBLF *)MEM_callocN(sizeof(GlyphBLF), "blf_glyph_add");
g->c = c;
g->idx = (FT_UInt)index;
g->xoff = -1;
g->yoff = -1;
bitmap = slot->bitmap;
g->width = bitmap.width;
g->height = bitmap.rows;
if (g->width && g->height) {
if (sharp) {
/* Font buffer uses only 0 or 1 values, Blender expects full 0..255 range */
int i;
for (i = 0; i < (g->width * g->height); i++) {
bitmap.buffer[i] = 255 * bitmap.buffer[i];
}
}
g->bitmap = (unsigned char *)MEM_mallocN(g->width * g->height, "glyph bitmap");
memcpy((void *)g->bitmap, (void *)bitmap.buffer, g->width * g->height);
}
g->advance = ((float)slot->advance.x) / 64.0f;
g->pos_x = slot->bitmap_left;
g->pos_y = slot->bitmap_top;
g->pitch = slot->bitmap.pitch;
FT_Outline_Get_CBox(&(slot->outline), &bbox);
g->box.xmin = ((float)bbox.xMin) / 64.0f;
g->box.xmax = ((float)bbox.xMax) / 64.0f;
g->box.ymin = ((float)bbox.yMin) / 64.0f;
g->box.ymax = ((float)bbox.yMax) / 64.0f;
key = blf_hash(g->c);
BLI_addhead(&(font->glyph_cache->bucket[key]), g);
return g;
}
示例11: dbg_msg
CTextRenderer::CGlyph* CTextRenderer::LoadGlyph(CGlyphCache* pCache, CGlyphId GlyphId)
{
if(m_Fonts.size() == 0)
{
dbg_msg("TextRenderer", "No font loaded");
return 0;
}
CFont* pFont = m_Fonts[GlyphId.m_FontId];
if(FT_Set_Pixel_Sizes(pFont->m_FtFace, 0, pCache->m_FontSize) != FT_Err_Ok)
{
dbg_msg("TextRenderer", "Can't set pixel size %d", pCache->m_FontSize);
return 0;
}
if(FT_Load_Glyph(pFont->m_FtFace, GlyphId.m_GlyphCode, FT_LOAD_RENDER|FT_LOAD_NO_BITMAP) != FT_Err_Ok)
{
dbg_msg("TextRenderer", "Can't load glyph %d", GlyphId.m_GlyphCode);
return 0;
}
FT_Bitmap* pBitmap = &pFont->m_FtFace->glyph->bitmap;
int BitmapWidth = pBitmap->width;
int BitmapHeight = pBitmap->rows;
int BBWidth = BitmapWidth+2*s_Margin;
int BBHeight = BitmapHeight+2*s_Margin;
CTextRenderer::CGlyph* pGlyph = pCache->NewGlyph(GlyphId, BBWidth, BBHeight);
pGlyph->m_GlyphId = GlyphId;
pGlyph->m_AdvanceX = (pFont->m_FtFace->glyph->advance.x >> 6);
pGlyph->m_OffsetX = pFont->m_FtFace->glyph->bitmap_left - s_Margin;
pGlyph->m_OffsetY = pFont->m_FtFace->glyph->bitmap_top + s_Margin;
if(pBitmap->pixel_mode == FT_PIXEL_MODE_GRAY)
{
for(int j = 0; j < BitmapHeight; j++)
{
for(int i = 0; i < BitmapWidth; i++)
{
int CacheDataIndex = (j+s_Margin)*pCache->m_Width + (i+s_Margin);
pGlyph->m_pData[CacheDataIndex] = pBitmap->buffer[j*pBitmap->pitch+i];
}
}
}
else if(pBitmap->pixel_mode == FT_PIXEL_MODE_MONO)
{
for(int j = 0; j < BitmapHeight; j++)
{
for(int i = 0; i < BitmapWidth; i++)
{
int CacheDataIndex = (j+s_Margin)*pCache->m_Width + (i+s_Margin);
if(pBitmap->buffer[j*pBitmap->pitch+i/8]&(1<<(7-(i%8))))
pGlyph->m_pData[CacheDataIndex] = 255;
else
pGlyph->m_pData[CacheDataIndex] = 0;
}
}
}
mem_zero(s_aGlyphBuffer, (pGlyph->m_Granularity.x * pCache->m_PPG) * (pGlyph->m_Granularity.y * pCache->m_PPG));
for(int j = s_Margin; j < pGlyph->m_Height-s_Margin; j++)
{
for(int i = s_Margin; i < pGlyph->m_Width-s_Margin; i++)
{
s_aGlyphBuffer[j*(pGlyph->m_Granularity.x * pCache->m_PPG) + i] = pGlyph->m_pData[j*pCache->m_Width + i];
}
}
pCache->UpdateTexture(pGlyph, s_aGlyphBuffer);
return pGlyph;
}
示例12: cache_glyphs
void cache_glyphs(struct ft2_source *srcdata, wchar_t *cache_glyphs)
{
FT_GlyphSlot slot = 0;
FT_UInt glyph_index = 0;
if (!srcdata->font_face || !cache_glyphs)
return;
//slot = srcdata->font_face->glyph;
uint32_t dx = srcdata->texbuf_x, dy = srcdata->texbuf_y;
uint8_t alpha;
int32_t cached_glyphs = 0;
size_t len = wcslen(cache_glyphs);
for (size_t i = 0; i < len; i++) {
FT_Face curFace;
glyph_index = FT_Get_Char_Index_Fallback(srcdata, &curFace,
cache_glyphs[i]);
if (curFace == 0)
goto skip_glyph;
slot = curFace->glyph;
if (src_glyph != NULL)
goto skip_glyph;
FT_Load_Glyph(curFace, glyph_index, FT_LOAD_DEFAULT);
bool isUseFallback = slot->face == srcdata->fallback_face;
bool shouldBolden = ((!isUseFallback && srcdata->fake_bold) || (isUseFallback && srcdata->fallback_fake_bold));
if (slot->format == FT_GLYPH_FORMAT_OUTLINE && shouldBolden)
FT_Outline_EmboldenXY(&slot->outline, 0x80, 0x40);
FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
uint32_t g_w = slot->bitmap.width;
uint32_t g_h = slot->bitmap.rows;
if (srcdata->max_h < g_h) srcdata->max_h = g_h;
if (dx + g_w >= texbuf_w) {
dx = 0;
dy += srcdata->max_h + 1;
}
src_glyph = bzalloc(sizeof(struct glyph_info));
src_glyph->u = (float)dx / (float)texbuf_w;
src_glyph->u2 = (float)(dx + g_w) / (float)texbuf_w;
src_glyph->v = (float)dy / (float)texbuf_h;
src_glyph->v2 = (float)(dy + g_h) / (float)texbuf_h;
src_glyph->w = g_w;
src_glyph->h = g_h;
src_glyph->yoff = slot->bitmap_top;
src_glyph->xoff = slot->bitmap_left;
src_glyph->xadv = slot->advance.x >> 6;
for (uint32_t y = 0; y < g_h; y++) {
for (uint32_t x = 0; x < g_w; x++) {
alpha = slot->bitmap.buffer[glyph_pos];
srcdata->texbuf[buf_pos] =
0x00FFFFFF ^ ((uint32_t)alpha << 24);
}
}
dx += (g_w + 1);
if (dx >= texbuf_w) {
dx = 0;
dy += srcdata->max_h;
}
cached_glyphs++;
skip_glyph:;
}
srcdata->texbuf_x = dx;
srcdata->texbuf_y = dy;
if (cached_glyphs > 0) {
obs_enter_graphics();
if (srcdata->tex != NULL) {
gs_texture_t *tmp_texture = NULL;
tmp_texture = srcdata->tex;
srcdata->tex = NULL;
gs_texture_destroy(tmp_texture);
}
srcdata->tex = gs_texture_create(texbuf_w, texbuf_h,
GS_RGBA, 1, (const uint8_t **)&srcdata->texbuf, 0);
obs_leave_graphics();
}
}
示例13: NOVA_EXP
void CFreeFont::MakeLetter(wchar_t code)
{
// Первая вещь, которую нам надо сделать, это вывести наш символ
// в растр. Это делается набором команд FreeType
// Загрузить глифы для каждого символа.
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, code), FT_LOAD_DEFAULT))
throw NOVA_EXP("CFreeFont::MakeLetter - FT_Load_Glyph failed", BAD_OPERATION);
// Поместить глиф в объект.
FT_Glyph glyph;
if(FT_Get_Glyph(face->glyph, &glyph))
throw NOVA_EXP("CFreeFont::MakeLetter - FT_Get_Glyph failed", BAD_OPERATION);
// Конвертировать глиф в растр.
FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
FT_BitmapGlyph bitmap_glyph = reinterpret_cast<FT_BitmapGlyph>(glyph);
// С помощью этой ссылки, получаем легкий доступ до растра.
FT_Bitmap & bitmap = bitmap_glyph->bitmap;
// Используем нашу вспомогательную функцию для вычисления ширины и высоты
// текстуры для нашего растра.
nInt32 bwidth = NextP2(bitmap.width);
nInt32 bheight = NextP2(bitmap.rows);
// Выделим память для данных текстуры.
//nByte * expanded_data = NULL;
//expanded_data = getmem<nByte>(expanded_data, 2 * bwidth * bheight);
CMemoryBuffer mem;
mem.AllocBuffer(2 * bwidth * bheight);
nByte * expanded_data = (nova::nByte *)mem.GetBegin();
// Поместим данные в расширенный растр.
// Отмечу, что использован двухканальный растр (Один для
// канала яркости и один для альфа), но мы будем назначать
// обоим каналам одно и тоже значение, которое мы
// получим из растра FreeType.
// Мы используем оператор ?: для того чтобы поместить 0 в зону вне растра FreeType.
for(nInt32 j = 0; j < bheight; ++j)
for(nInt32 i = 0; i < bwidth; ++i)
expanded_data[2*(i + j * bwidth)] = expanded_data[2*(i + j * bwidth)+1] =
(i >= bitmap.width || j >= bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
/* GLuint texture;
glGenTextures(1, &texture);
glBindTexture( GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Здесь мы создаем текстуру
// Помните, что используем GL_LUMINANCE_ALPHA, чтобы было два альфа канала данных
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bwidth, bheight, 0,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data);
*/
//nInt32 tid = CTextureManager::GetSingeltonPtr()->AddTexture(GL_TEXTURE_2D,
// expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA);
/* CTexturePtr ptex = CTextureManager::GetSingeltonPtr()->AddTexture(new CTexture(fname.c_str(), GL_TEXTURE_2D));
ptex->SetEnvType(GL_MODULATE);
ptex->CreateTexture(expanded_data, bwidth, bheight, CImageFormats::NF_LUMINANCE_ALPHA, GL_CLAMP);
// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
freemems(expanded_data);
CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
code, ptex);
*/
nstring resnamet;
nstring resnamei("TempFontImage");
resnamet = mName + "_" + CStringUtils::IntTo16xString(static_cast<nInt32>(code));
// Создаем промежуточное изображение в памяти
CImagePtr pImage = CImageManager::GetSingelton().CreateNewImage(resnamei, mName, mem,
bwidth, bheight, 1, CImageFormats::NF_LUMINANCE_ALPHA, CResource::NV_FREE);
// На базе изображения создаем текстуру
CTexturePtr texp = CTextureManager::GetSingelton().CreateNewTexture(resnamet, mName, pImage);
// После создания текстуры, мы больше не нуждаемся в промежуточных данных.
mem.FreeBuffer();
CLetter letter(slot->metrics.horiBearingX >> 6, slot->metrics.horiBearingY >> 6,
slot->metrics.horiAdvance >> 6, bwidth, bheight, bitmap.width, bitmap.rows,
code, texp);
mSize += texp->GetSize();
/// Создаем дисплейный список на букву ///////////////////////////////////////////////
letter.GetDispList().CreateList();
letter.GetDispList().BeginList();
/// //////////////////////////////////////////////////////////////////////////////////
if(!texp.IsNull())
texp->ApplyTexture();
// Вычислим какая часть нашей текстуры будет заполнена пустым пространством.
// Мы рисуем только ту часть текстуры, в которой находится символ, и сохраняем
// информацию в переменных x и y, затем, когда мы рисуем четырехугольник,
// мы будем только ссылаться на ту часть текстуры, в которой непосредственно
// содержится символ.
nReal x = static_cast<nReal>(letter.GetBitmapw()) / static_cast<nReal>(letter.GetWidth()),
//.........这里部分代码省略.........
示例14: ftIterateGlyphs
value ftIterateGlyphs( value font, value callbacks ) {
if( !val_is_object(callbacks) ) {
ft_failure_v("not a callback function object: ", callbacks );
}
// printf("A\n");
field endGlyph = val_id("endGlyph");
field startContour = val_id("startContour");
field endContour = val_id("endContour");
field lineTo = val_id("lineTo");
field curveTo = val_id("curveTo");
// printf("B\n");
if( !val_is_object(font) ) {
ft_failure_v("not a freetype font face: ", font );
}
value __f = val_field( font, val_id("__f") );
if( __f == NULL || !val_is_abstract( __f ) || !val_is_kind( __f, k_ft_face ) ) {
ft_failure_v("not a freetype font face: ", font );
}
FT_Face *face = val_data( __f );
// printf("C\n");
FT_UInt glyph_index;
FT_ULong character;
FT_Outline *outline;
field f_character = val_id("character");
field f_advance = val_id("advance");
character = FT_Get_First_Char( *face, &glyph_index );
// printf("D\n");
while( character != 0 ) {
if( FT_Load_Glyph( *face, glyph_index, FT_LOAD_NO_BITMAP ) ) {
// ignore (TODO report?)
} else if( (*face)->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) {
// ignore (TODO)
} else {
outline = &((*face)->glyph->outline);
int start = 0, end, contour, p;
char control, cubic;
int n,i;
// printf(" 1\n");
for( contour = 0; contour < outline->n_contours; contour++ ) {
end = outline->contours[contour];
n=0;
for( p = start; p<=end; p++ ) {
control = !(outline->tags[p] & 0x01);
cubic = outline->tags[p] & 0x02;
if( p==start ) {
val_ocall2( callbacks, startContour,
alloc_int( outline->points[p-n].x ),
alloc_int( outline->points[p-n].y ) );
}
if( !control && n > 0 ) {
importGlyphPoints( &(outline->points[(p-n)+1]), n-1, callbacks, lineTo, curveTo, cubic );
n=1;
} else {
n++;
}
}
if( n ) {
// special case: repeat first point
FT_Vector points[n+1];
int s=(end-n)+2;
for( i=0; i<n-1; i++ ) {
points[i].x = outline->points[s+i].x;
points[i].y = outline->points[s+i].y;
}
points[n-1].x = outline->points[start].x;
points[n-1].y = outline->points[start].y;
importGlyphPoints( points, n-1, callbacks, lineTo, curveTo, false );
}
start = end+1;
val_ocall0( callbacks, endContour );
}
// printf(" 2\n");
val_ocall2( callbacks, endGlyph, alloc_int( character ), alloc_int( (*face)->glyph->advance.x ) );
// printf(" 3\n");
}
// printf(" E\n");
character = FT_Get_Next_Char( *face, character, &glyph_index );
// printf(" F\n");
}
// printf(" Goo\n");
return val_true;
}
示例15: 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;
//.........这里部分代码省略.........