Esempio n. 1
0
font_t* bbutil_load_font(const char* path, int point_size, int dpi) {
    FT_Library library;
    FT_Face face;
    int c;
    int i, j;
    font_t* font;

    if (!initialized) {
        fprintf(stderr, "EGL has not been initialized\n");
        return NULL;
    }

    if (!path){
        fprintf(stderr, "Invalid path to font file\n");
        return NULL;
    }

    if(FT_Init_FreeType(&library)) {
        fprintf(stderr, "Error loading Freetype library\n");
        return NULL;
    }
    if (FT_New_Face(library, path,0,&face)) {
        fprintf(stderr, "Error loading font %s\n", path);
        return NULL;
    }

    if(FT_Set_Char_Size ( face, point_size * 64, point_size * 64, dpi, dpi)) {
        fprintf(stderr, "Error initializing character parameters\n");
        return NULL;
    }

    font = (font_t*) malloc(sizeof(font_t));
    font->initialized = 0;

    glGenTextures(1, &(font->font_texture));

    //Let each glyph reside in 32x32 section of the font texture
    int segment_size_x = 0, segment_size_y = 0;
    int num_segments_x = 16;
    int num_segments_y = 8;

    FT_GlyphSlot slot;
    FT_Bitmap bmp;
    int glyph_width, glyph_height;

    //First calculate the max width and height of a character in a passed font
    for(c = 0; c < 128; c++) {
        if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
            fprintf(stderr, "FT_Load_Char failed\n");
            free(font);
            return NULL;
        }

        slot = face->glyph;
        bmp = slot->bitmap;

        //glyph_width = nextp2(bmp.width);
        //glyph_height = nextp2(bmp.rows);

        glyph_width = bmp.width;
        glyph_height = bmp.rows;

        if (glyph_width > segment_size_x) {
            segment_size_x = glyph_width;
        }

        if (glyph_height > segment_size_y) {
            segment_size_y = glyph_height;
        }
    }

    int font_tex_width = nextp2(num_segments_x * segment_size_x);
    int font_tex_height = nextp2(num_segments_y * segment_size_y);

    int bitmap_offset_x = 0, bitmap_offset_y = 0;

    GLubyte* font_texture_data = (GLubyte*) malloc(sizeof(GLubyte) * 2 * font_tex_width * font_tex_height);
    memset((void*)font_texture_data, 0, sizeof(GLubyte) * 2 * font_tex_width * font_tex_height);

    if (!font_texture_data) {
        fprintf(stderr, "Failed to allocate memory for font texture\n");
        free(font);
        return NULL;
    }

    // Fill font texture bitmap with individual bmp data and record appropriate size, texture coordinates and offsets for every glyph
    for(c = 0; c < 128; c++) {
        if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
            fprintf(stderr, "FT_Load_Char failed\n");
            free(font);
            return NULL;
        }

        slot = face->glyph;
        bmp = slot->bitmap;

        glyph_width = nextp2(bmp.width);
        glyph_height = nextp2(bmp.rows);

        div_t temp = div(c, num_segments_x);

        bitmap_offset_x = segment_size_x * temp.rem;
        bitmap_offset_y = segment_size_y * temp.quot;

        for (j = 0; j < glyph_height; j++) {
            for (i = 0; i < glyph_width; i++) {
                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 0] =
                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 1] =
                    (i >= bmp.width || j >= bmp.rows)? 0 : bmp.buffer[i + bmp.width * j];
            }
        }

        font->advance[c] = (float)(slot->advance.x >> 6);
        font->tex_x1[c] = (float)bitmap_offset_x / (float) font_tex_width;
        font->tex_x2[c] = (float)(bitmap_offset_x + bmp.width) / (float)font_tex_width;
        font->tex_y1[c] = (float)bitmap_offset_y / (float) font_tex_height;
        font->tex_y2[c] = (float)(bitmap_offset_y + bmp.rows) / (float)font_tex_height;
        font->width[c] = bmp.width;
        font->height[c] = bmp.rows;
        font->offset_x[c] = (float)slot->bitmap_left;
        font->offset_y[c] =  (float)((slot->metrics.horiBearingY-face->glyph->metrics.height) >> 6);
    }

    glBindTexture(GL_TEXTURE_2D, font->font_texture);
    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_LUMINANCE_ALPHA, font_tex_width, font_tex_height, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, font_texture_data);

    int err = glGetError();

    free(font_texture_data);

    FT_Done_Face(face);
    FT_Done_FreeType(library);

    if (err != 0) {
        fprintf(stderr, "GL Error 0x%x", err);
        free(font);
        return NULL;
    }

    font->initialized = 1;
    return font;
}
int OpenGLView::loadTexture(const char* filename, int* width, int* height, float* tex_x, float* tex_y, unsigned int *tex) {
    int i;
    GLuint format;
    //header for testing if it is a png
    png_byte header[8];

    if (!tex) {
        return EXIT_FAILURE;
    }

    //open file as binary
    FILE *fp = fopen(filename, "rb");
    if (!fp) {
        return EXIT_FAILURE;
    }

    //read the header
    fread(header, 1, 8, fp);

    //test if png
    int is_png = !png_sig_cmp(header, 0, 8);
    if (!is_png) {
        fclose(fp);
        return EXIT_FAILURE;
    }

    //create png struct
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr) {
        fclose(fp);
        return EXIT_FAILURE;
    }

    //create png info struct
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
        fclose(fp);
        return EXIT_FAILURE;
    }

    //create png info struct
    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
        fclose(fp);
        return EXIT_FAILURE;
    }

    //setup error handling (required without using custom error handlers above)
    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(fp);
        return EXIT_FAILURE;
    }

    //init png reading
    png_init_io(png_ptr, fp);

    //let libpng know you already read the first 8 bytes
    png_set_sig_bytes(png_ptr, 8);

    // read all the info up to the image data
    png_read_info(png_ptr, info_ptr);

    //variables to pass to get info
    int bit_depth, color_type;
    png_uint_32 image_width, image_height;

    // get info about png
    png_get_IHDR(png_ptr, info_ptr, &image_width, &image_height, &bit_depth, &color_type, NULL, NULL, NULL);

    switch (color_type)
    {
        case PNG_COLOR_TYPE_RGBA:
            format = GL_RGBA;
            break;
        case PNG_COLOR_TYPE_RGB:
            format = GL_RGB;
            break;
        default:
            fprintf(stderr,"Unsupported PNG color type (%d) for texture: %s", (int)color_type, filename);
            fclose(fp);
            png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
            return EXIT_FAILURE;
    }

    // Update the png info struct.
    png_read_update_info(png_ptr, info_ptr);

    // Row size in bytes.
    int rowbytes = png_get_rowbytes(png_ptr, info_ptr);

    // Allocate the image_data as a big block, to be given to opengl
    png_byte *image_data = (png_byte*) malloc(sizeof(png_byte) * rowbytes * image_height);

    if (!image_data) {
        //clean up memory and close stuff
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        fclose(fp);
        return EXIT_FAILURE;
    }

    //row_pointers is for pointing to image_data for reading the png with libpng
    png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * image_height);
    if (!row_pointers) {
        //clean up memory and close stuff
        png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
        free(image_data);
        fclose(fp);
        return EXIT_FAILURE;
    }

    // set the individual row_pointers to point at the correct offsets of image_data
    for (i = 0; i < image_height; i++) {
        row_pointers[image_height - 1 - i] = image_data + i * rowbytes;
    }

    //read the png into image_data through row_pointers
    png_read_image(png_ptr, row_pointers);

    int tex_width, tex_height;

    tex_width = nextp2(image_width);
    tex_height = nextp2(image_height);

    glGenTextures(1, tex);
    glBindTexture(GL_TEXTURE_2D, (*tex));
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glTexImage2D(GL_TEXTURE_2D, 0, format, tex_width, tex_height, 0, format, GL_UNSIGNED_BYTE, NULL);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, format, GL_UNSIGNED_BYTE, image_data);

    GLint err = glGetError();

    //clean up memory and close stuff
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    free(image_data);
    free(row_pointers);
    fclose(fp);

    if (err == 0) {
        //Return physical with and height of texture if pointers are not null
        if(width) {
            *width = image_width;
        }
        if (height) {
            *height = image_height;
        }
        //Return modified texture coordinates if pointers are not null
        if(tex_x) {
            *tex_x = ((float) image_width - 0.5f) / ((float)tex_width);
        }
        if(tex_y) {
            *tex_y = ((float) image_height - 0.5f) / ((float)tex_height);
        }
        return EXIT_SUCCESS;
    } else {
        fprintf(stderr, "GL error %i \n", err);
        return EXIT_FAILURE;
    }
}
Esempio n. 3
0
int  zaFont::load_font(char * instr,int len)
{

		char * pin  = NULL;
		char * pout = NULL;
		char *p = NULL;

		char* inbuf = pin ; // m_filepos,  file head
		char* outbuf = pout;

		if (len==0)// utf8,
		{
			int ll= strlen(instr);
			size_t inbytesleft= ll+1;
			size_t outbytesleft = inbytesleft*2;

			pin = (char *)malloc(inbytesleft);
			pout = (char *)malloc(outbytesleft);

			inbuf = pin ; // m_filepos,  file head
			outbuf = pout;

			fprintf(stderr,"zaFont::load_font load begin length  %d\n",ll);
			strcpy(pin,instr);

			iconv_t tt;
			tt = iconv_open("UTF-16LE","UTF-8");
			int ret = iconv(tt,&inbuf,&inbytesleft,&outbuf,&outbytesleft);
			if ( ret < 0)
			{
				fprintf(stderr,"zaFont::load_font load error  errno %d\n",errno);
				throw CException(__FILE__,__LINE__,"zaFont::load_font convert error ,filename %s","NULL");
			}
			fprintf(stderr,"zaFont::load_font sucess.%d--%d:\n",ll*2,outbytesleft);
			iconv_close(tt);
			len = ll*2- outbytesleft;
			p= pout;
		}
		else
			p = instr;

			FT_Library library;
		    FT_Face face;
		    int c;
		    int i, j;
		    font_t* font = NULL;

		    if(FT_Init_FreeType(&library)) {
		        fprintf(stderr, "Error loading Freetype library\n");
		        return NULL;
		    }

		    if (FT_New_Face(library, m_path,0,&face)) {
		        fprintf(stderr, "Error loading font %s\n", m_path);
		        return NULL;
		    }

		    if(FT_Set_Char_Size ( face, m_size * 64, m_size * 64, m_dpi, m_dpi)) {
		        fprintf(stderr, "Error initializing character parameters\n");
		        return NULL;
		    }

		    unsigned int charcode = 0;

for (int cci =0 ; cci < len ; cci +=2)
{

charcode = ((unsigned char)*(p+1))*256+(unsigned char)*p ;
if (charcode == 601)
{
	charcode --;
	charcode ++;
}
if (this->m_map.find(charcode)==m_map.end())
{

		    font = (font_t*) malloc(sizeof(font_t));
		    font->initialized = 0;

		    glGenTextures(1, &(font->font_texture));

		    //Let each glyph reside in 32x32 section of the font texture
		    int segment_size_x = 0, segment_size_y = 0;
		    int num_segments_x = 1;//16
		    int num_segments_y = 1;//8

		    FT_GlyphSlot slot;
		    FT_Bitmap bmp;
		    int glyph_width, glyph_height;

		    //First calculate the max width and height of a character in a passed font
		    for(c = 0; c < 1; c++) {
		    	//
		        if(FT_Load_Char(face,0x4E2D+charcode-0x4E2D , FT_LOAD_RENDER)) {
		            fprintf(stderr, "FT_Load_Char failed\n");
		            free(font);
		            return NULL;
		        }

		        slot = face->glyph;
		        bmp = slot->bitmap;

		        //glyph_width = nextp2(bmp.width);
		        //glyph_height = nextp2(bmp.rows);

		        glyph_width = bmp.width;
		        glyph_height = bmp.rows;

		        if (glyph_width > segment_size_x) {
		            segment_size_x = glyph_width;
		        }

		        if (glyph_width > m_max_x)
		        	m_max_x = glyph_width;

		        if (glyph_height > segment_size_y) {
		            segment_size_y = glyph_height;
		        }

		        if (glyph_height > m_max_y)
		 		     m_max_y = glyph_height;
		    }

		    int font_tex_width = nextp2(num_segments_x * segment_size_x);
		    int font_tex_height = nextp2(num_segments_y * segment_size_y);

		    int bitmap_offset_x = 0, bitmap_offset_y = 0;

		    GLubyte* font_texture_data = (GLubyte*) malloc(sizeof(GLubyte) * 2 * font_tex_width * font_tex_height);
		    memset((void*)font_texture_data, 0, sizeof(GLubyte) * 2 * font_tex_width * font_tex_height);

		    if (!font_texture_data) {
		        fprintf(stderr, "Failed to allocate memory for font texture\n");
		        free(font);
		        return NULL;
		    }

		    // Fill font texture bitmap with individual bmp data and record appropriate size, texture coordinates and offsets for every glyph
		    for(c = 0; c < 1; c++)
		    {
		    	   if(FT_Load_Char(face,0x4E2D+charcode-0x4E2D , FT_LOAD_RENDER)) {
		            fprintf(stderr, "FT_Load_Char failed\n");
		            free(font);
		            return NULL;
		        }

		        slot = face->glyph;
		        bmp = slot->bitmap;

		        glyph_width = nextp2(bmp.width);
		        glyph_height = nextp2(bmp.rows);

		        div_t temp = div(c, num_segments_x);

		        bitmap_offset_x = segment_size_x * temp.rem;
		        bitmap_offset_y = segment_size_y * temp.quot;

		        for (j = 0; j < glyph_height; j++) {
		            for (i = 0; i < glyph_width; i++) {
		                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 0] =
		                font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 1] =
		                    (i >= bmp.width || j >= bmp.rows)? 0 : bmp.buffer[i + bmp.width * j];
		            }
		        }

		        font->advance[c] = (float)(slot->advance.x >> 6);
		        font->tex_x1[c] = (float)bitmap_offset_x / (float) font_tex_width;
		        font->tex_x2[c] = (float)(bitmap_offset_x + bmp.width) / (float)font_tex_width;
		        font->tex_y1[c] = (float)bitmap_offset_y / (float) font_tex_height;
		        font->tex_y2[c] = (float)(bitmap_offset_y + bmp.rows) / (float)font_tex_height;
		        font->width[c] = bmp.width;
		        font->height[c] = bmp.rows;
		        font->offset_x[c] = (float)slot->bitmap_left;
		        font->offset_y[c] =  (float)((slot->metrics.horiBearingY-face->glyph->metrics.height) >> 6);
		    }


		    glBindTexture(GL_TEXTURE_2D, font->font_texture);
		    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_LUMINANCE_ALPHA, font_tex_width, font_tex_height, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, font_texture_data);

		  //  fprintf(stderr, "charcode %d %d\n",charcode, cci);
		    fflush(stderr);
		    free(font_texture_data);
		    font->initialized = 1;
m_map[charcode] = font;
}
p += 2;
}