Esempio n. 1
0
    //------------------------------------------------------------------------
    bool font_engine_freetype_base::load_font(const char* font_name, 
                                              unsigned face_index,
                                              glyph_rendering ren_type,
                                              const char* font_mem, 
                                              const long font_mem_size)
    {
        bool ret = false;

        if(m_library_initialized)
        {
            m_last_error = 0;

            int idx = find_face(font_name);
            if(idx >= 0)
            {
                m_cur_face = m_faces[idx];
                m_name     = m_face_names[idx];
            }
            else
            {
                if(m_num_faces >= m_max_faces)
                {
                    delete [] m_face_names[0];
                    FT_Done_Face(m_faces[0]);
                    memcpy(m_faces, 
                           m_faces + 1, 
                           (m_max_faces - 1) * sizeof(FT_Face));
                    memcpy(m_face_names, 
                           m_face_names + 1, 
                           (m_max_faces - 1) * sizeof(char*));
                    m_num_faces = m_max_faces - 1;
                }

                if (font_mem && font_mem_size)
                {
                    m_last_error = FT_New_Memory_Face(m_library, 
                                                      (const FT_Byte*)font_mem, 
                                                      font_mem_size, 
                                                      face_index, 
                                                      &m_faces[m_num_faces]);
                }
                else
                {
                    m_last_error = FT_New_Face(m_library,
                                               font_name,
                                               face_index,
                                               &m_faces[m_num_faces]);
                }

                if(m_last_error == 0)
                {
                    m_face_names[m_num_faces] = new char [strlen(font_name) + 1];
                    strcpy(m_face_names[m_num_faces], font_name);
                    m_cur_face = m_faces[m_num_faces];
                    m_name     = m_face_names[m_num_faces];
                    ++m_num_faces;
                }
                else
                {
                    m_face_names[m_num_faces] = 0;
                    m_cur_face = 0;
                    m_name = 0;
                }
            }


            if(m_last_error == 0)
            {
                ret = true;
                
                switch(ren_type)
                {
                case glyph_ren_native_mono:
                    m_glyph_rendering = glyph_ren_native_mono;
                    break;

                case glyph_ren_native_gray8:
                    m_glyph_rendering = glyph_ren_native_gray8;
                    break;

                case glyph_ren_outline:
                    if(FT_IS_SCALABLE(m_cur_face))
                    {
                        m_glyph_rendering = glyph_ren_outline;
                    }
                    else
                    {
                        m_glyph_rendering = glyph_ren_native_gray8;
                    }
                    break;

                case glyph_ren_agg_mono:
                    if(FT_IS_SCALABLE(m_cur_face))
                    {
                        m_glyph_rendering = glyph_ren_agg_mono;
                    }
                    else
                    {
                        m_glyph_rendering = glyph_ren_native_mono;
                    }
                    break;

                case glyph_ren_agg_gray8:
                    if(FT_IS_SCALABLE(m_cur_face))
                    {
                        m_glyph_rendering = glyph_ren_agg_gray8;
                    }
                    else
                    {
                        m_glyph_rendering = glyph_ren_native_gray8;
                    }
                    break;
                }
                update_signature();
            }
        }

        return ret;
    }
Esempio n. 2
0
EFontFT2::EFontFT2(const EEntry *entry, eint32 faceIndex)
	: EFontEngine(), fFilename(NULL), fFaceIndex(-1), nFaces(-1), fFace(NULL), fScalable(false), fForceFontAliasing(false)
{
	EPath aPath;
	if(entry == NULL || entry->Exists() == false || entry->GetPath(&aPath) != E_OK) return;
	EString filename = aPath.Path();
#ifdef _WIN32
	filename.ReplaceAll("/", "\\");
#endif

	SetRenderMode(E_FONT_RENDER_PIXMAP);

	EAutolock <ELocker> autolock(&etk_ft2_font_locker);
	if(!_etk_ft2_initialized_) return;

	FT_Error error = FT_New_Face(_etk_ft2_library_, filename.String(), faceIndex, &fFace);
	if(error || !fFace)
	{
		ETK_DEBUG("[FONT]: %s --- CAN NOT load face[%s:%d].", __PRETTY_FUNCTION__, aPath.Path(), faceIndex);
		return;
	}

	if(FT_Select_Charmap(fFace, FT_ENCODING_UNICODE))
	{
//		ETK_DEBUG("[FONT]: %s --- font[%s] don't support ENCODING_UNICODE.", __PRETTY_FUNCTION__, aPath.Path());

		if(FT_Select_Charmap(fFace, FT_ENCODING_NONE))
		{
//			ETK_WARNING("[FONT]: %s --- font[%s] don't support unicode at all.", __PRETTY_FUNCTION__, aPath.Path());
			FT_Done_Face(fFace);
			fFace = NULL;
			return;
		}
	}

	fFilename = EStrdup(filename.String());
	fFaceIndex = faceIndex;
	nFaces = fFace->num_faces;

	EString family = fFace->family_name;
	if(family.Length() <= 0)
	{
		family = aPath.Leaf();
		eint32 cFound;
		if((cFound = family.FindFirst('.')) >= 0) family.Remove(cFound, -1);
		if(family.Length() < 0) family = "Unknown";
	}
	SetFamily(family.String());

	EString style = fFace->style_name;
	if(style.Length() <= 0)
	{
		if((fFace->style_flags & FT_STYLE_FLAG_BOLD) && (fFace->style_flags & FT_STYLE_FLAG_ITALIC))
			style = "Bold Italic";
		else if(fFace->style_flags & FT_STYLE_FLAG_BOLD)
			style = "Bold";
		else if(fFace->style_flags & FT_STYLE_FLAG_ITALIC)
			style = "Italic";
		else
			style = "Regular";
	}
	SetStyle(style.String());

	if(FT_IS_SCALABLE(fFace)) fScalable = true;

	if(fFace->num_fixed_sizes > 0)
	{
		float *sizes = new float[(int)fFace->num_fixed_sizes];
		for(int i = 0; i < fFace->num_fixed_sizes; i++) sizes[i] = (float)(fFace->available_sizes[i].height);
		SetFixedSize(sizes, (eint32)fFace->num_fixed_sizes);
		delete[] sizes;
	}

	FT_Done_Face(fFace);
	fFace = NULL;
}
Esempio n. 3
0
// ----------------------------------------------- texture_font_load_glyphs ---
size_t
texture_font_load_glyphs( texture_font_t * self,
                          const wchar_t * charcodes )
{
    assert( self );
    assert( charcodes );

    size_t i, x, y, width, height, depth, w, h;
    FT_Library library;
    FT_Error error;
    FT_Face face;
    FT_Glyph ft_glyph;
    FT_GlyphSlot slot;
    FT_Bitmap ft_bitmap;

    FT_UInt glyph_index;
    texture_glyph_t *glyph;
    ivec4 region;
    size_t missed = 0;
    width  = self->atlas->width;
    height = self->atlas->height;
    depth  = self->atlas->depth;

    if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
    {
        return wcslen(charcodes);
    }

    /* Load each glyph */
    for( i=0; i<wcslen(charcodes); ++i )
    {
        glyph_index = FT_Get_Char_Index( face, charcodes[i] );
        // WARNING: We use texture-atlas depth to guess if user wants
        //          LCD subpixel rendering
        FT_Int32 flags = 0;

        if( self->outline_type > 0 )
        {
            flags |= FT_LOAD_NO_BITMAP;
        }
        else
        {
            flags |= FT_LOAD_RENDER;
        }

        if( !self->hinting )
        {
            flags |= FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
        }
        else
        {
            flags |= FT_LOAD_FORCE_AUTOHINT;
        }


        if( depth == 3 )
        {
            FT_Library_SetLcdFilter( library, FT_LCD_FILTER_LIGHT );
            flags |= FT_LOAD_TARGET_LCD;
            if( self->filtering )
            {
                FT_Library_SetLcdFilterWeights( library, self->lcd_weights );
            }
        }
        error = FT_Load_Glyph( face, glyph_index, flags );

        if( error )
        {
            fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                     __LINE__, FT_Errors[error].code, FT_Errors[error].message );
            FT_Done_FreeType( library );
            return wcslen(charcodes)-i;
        }

        int ft_bitmap_width = 0;
        int ft_bitmap_rows = 0;
        int ft_bitmap_pitch = 0;
        int ft_glyph_top = 0;
        int ft_glyph_left = 0;
        if( self->outline_type == 0 )
        {
            slot            = face->glyph;
            ft_bitmap       = slot->bitmap;
            ft_bitmap_width = slot->bitmap.width;
            ft_bitmap_rows  = slot->bitmap.rows;
            ft_bitmap_pitch = slot->bitmap.pitch;
            ft_glyph_top    = slot->bitmap_top;
            ft_glyph_left   = slot->bitmap_left;
        }
        else
        {
            FT_Stroker stroker;
            error = FT_Stroker_New( library, &stroker );
            if( error )
            {
                fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                        FT_Errors[error].code, FT_Errors[error].message);
                return 0;
            }
            FT_Stroker_Set( stroker,
                            (int)(self->outline_thickness *64),
                            FT_STROKER_LINECAP_ROUND,
                            FT_STROKER_LINEJOIN_ROUND,
                            0);
            error = FT_Get_Glyph( face->glyph, &ft_glyph);
            if( error )
            {
                fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                        FT_Errors[error].code, FT_Errors[error].message);
                return 0;
            }

            if( self->outline_type == 1 )
            {
                error = FT_Glyph_Stroke( &ft_glyph, stroker, 1 );
            }
            else if ( self->outline_type == 2 )
            {
                error = FT_Glyph_StrokeBorder( &ft_glyph, stroker, 0, 1 );
            }
            else if ( self->outline_type == 3 )
            {
                error = FT_Glyph_StrokeBorder( &ft_glyph, stroker, 1, 1 );
            }
            if( error )
            {
                fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                        FT_Errors[error].code, FT_Errors[error].message);
                return 0;
            }
          
            if( depth == 1)
            {
                error = FT_Glyph_To_Bitmap( &ft_glyph, FT_RENDER_MODE_NORMAL, 0, 1);
                if( error )
                {
                    fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                            FT_Errors[error].code, FT_Errors[error].message);
                    return 0;
                }
            }
            else
            {
                error = FT_Glyph_To_Bitmap( &ft_glyph, FT_RENDER_MODE_LCD, 0, 1);
                if( error )
                {
                    fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                            FT_Errors[error].code, FT_Errors[error].message);
                    return 0;
                }
            }
            FT_BitmapGlyph ft_bitmap_glyph = (FT_BitmapGlyph) ft_glyph;
            ft_bitmap       = ft_bitmap_glyph->bitmap;
            ft_bitmap_width = ft_bitmap.width;
            ft_bitmap_rows  = ft_bitmap.rows;
            ft_bitmap_pitch = ft_bitmap.pitch;
            ft_glyph_top    = ft_bitmap_glyph->top;
            ft_glyph_left   = ft_bitmap_glyph->left;
            FT_Stroker_Done(stroker);
        }


        // We want each glyph to be separated by at least one black pixel
        // (for example for shader used in demo-subpixel.c)
        w = ft_bitmap_width/depth + 1;
        h = ft_bitmap_rows + 1;
        region = texture_atlas_get_region( self->atlas, w, h );
        if ( region.x < 0 )
        {
            missed++;
            fprintf( stderr, "Texture atlas is full (line %d)\n",  __LINE__ );
            continue;
        }
        w = w - 1;
        h = h - 1;
        x = region.x;
        y = region.y;
        texture_atlas_set_region( self->atlas, x, y, w, h,
                                  ft_bitmap.buffer, ft_bitmap.pitch );

        glyph = texture_glyph_new( );
        glyph->charcode = charcodes[i];
        glyph->width    = w;
        glyph->height   = h;
        glyph->outline_type = self->outline_type;
        glyph->outline_thickness = self->outline_thickness;
        glyph->offset_x = ft_glyph_left;
        glyph->offset_y = ft_glyph_top;
        glyph->s0       = x/(float)width;
        glyph->t0       = y/(float)height;
        glyph->s1       = (x + glyph->width)/(float)width;
        glyph->t1       = (y + glyph->height)/(float)height;

        // Discard hinting to get advance
        FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
        slot = face->glyph;
        glyph->advance_x = slot->advance.x/64.0;
        glyph->advance_y = slot->advance.y/64.0;

        vector_push_back( self->glyphs, &glyph );

        if( self->outline_type > 0 )
        {
            FT_Done_Glyph( ft_glyph );
        }
    }
    FT_Done_Face( face );
    FT_Done_FreeType( library );
    texture_atlas_upload( self->atlas );
    texture_font_generate_kerning( self );
    return missed;
}
Esempio n. 4
0
void tst_QScriptEngine::malayalam()
{
    {
        FT_Face face = loadFace("AkrutiMal2Normal.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		{ { 0x0d15, 0x0d46, 0x0 },
		  { 0x005e, 0x0034, 0x0 } },
		{ { 0x0d15, 0x0d47, 0x0 },
		  { 0x005f, 0x0034, 0x0 } },
		{ { 0x0d15, 0x0d4b, 0x0 },
		  { 0x005f, 0x0034, 0x0058, 0x0 } },
		{ { 0x0d15, 0x0d48, 0x0 },
		  { 0x0060, 0x0034, 0x0 } },
		{ { 0x0d15, 0x0d4a, 0x0 },
		  { 0x005e, 0x0034, 0x0058, 0x0 } },
		{ { 0x0d30, 0x0d4d, 0x0d15, 0x0 },
		  { 0x009e, 0x0034, 0x0 } },
		{ { 0x0d15, 0x0d4d, 0x0d35, 0x0 },
		  { 0x0034, 0x007a, 0x0 } },
		{ { 0x0d15, 0x0d4d, 0x0d2f, 0x0 },
		  { 0x0034, 0x00a2, 0x0 } },
		{ { 0x0d1f, 0x0d4d, 0x0d1f, 0x0 },
		  { 0x0069, 0x0 } },
		{ { 0x0d26, 0x0d4d, 0x0d26, 0x0 },
		  { 0x0074, 0x0 } },
		{ { 0x0d30, 0x0d4d, 0x0 },
		  { 0x009e, 0x0 } },
		{ { 0x0d30, 0x0d4d, 0x200c, 0x0 },
		  { 0x009e, 0x0 } },
		{ { 0x0d30, 0x0d4d, 0x200d, 0x0 },
		  { 0x009e, 0x0 } },
                { { 0xd15, 0xd46, 0xd3e, 0x0 },
                  { 0x5e, 0x34, 0x58, 0x0 } },
                { { 0xd15, 0xd47, 0xd3e, 0x0 },
                  { 0x5f, 0x34, 0x58, 0x0 } },
                { { 0xd15, 0xd46, 0xd57, 0x0 },
                  { 0x5e, 0x34, 0x65, 0x0 } },
                { { 0xd15, 0xd57, 0x0 },
                  { 0x34, 0x65, 0x0 } },
                { { 0xd1f, 0xd4d, 0xd1f, 0xd41, 0xd4d, 0x0 },
                  { 0x69, 0x5b, 0x64, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Malayalam) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find AkrutiMal2Normal.ttf");
	}
    }

    {
        FT_Face face = loadFace("Rachana.ttf");
        if (face) {
            const ShapeTable shape_table [] = {
                { { 0xd37, 0xd4d, 0xd1f, 0xd4d, 0xd30, 0xd40, 0x0 },
                  { 0x385, 0xa3, 0x0 } },
                { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
                  { 0x2ff, 0x0 } },
                { { 0xd33, 0xd4d, 0xd33, 0x0 },
                  { 0x3f8, 0x0 } },
                { { 0xd2f, 0xd4d, 0xd15, 0xd4d, 0xd15, 0xd41, 0x0 },
                  { 0x2ff, 0x0 } },
                { { 0xd30, 0xd4d, 0x200d, 0xd35, 0xd4d, 0xd35, 0x0 },
                  { 0xf3, 0x350, 0x0 } },

                { {0}, {0} }
            };


            const ShapeTable *s = shape_table;
            while (s->unicode[0]) {
                QVERIFY( shaping(face, s, HB_Script_Malayalam) );
                ++s;
            }

            FT_Done_Face(face);
        } else {
            QSKIP("couln't find Rachana.ttf");
        }
    }

}
Esempio n. 5
0
void tst_QScriptEngine::bengali()
{
    {
        FT_Face face = loadFace("AkaashNormal.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		// Ka
		{ { 0x0995, 0x0 },
		  { 0x0151, 0x0 } },
		// Ka Halant
		{ { 0x0995, 0x09cd, 0x0 },
		  { 0x0151, 0x017d, 0x0 } },
		// Ka Halant Ka
		{ { 0x0995, 0x09cd, 0x0995, 0x0 },
		  { 0x019b, 0x0 } },
		// Ka MatraI
		{ { 0x0995, 0x09bf, 0x0 },
		  { 0x0173, 0x0151, 0x0 } },
		// Ra Halant Ka
		{ { 0x09b0, 0x09cd, 0x0995, 0x0 },
		  { 0x0151, 0x0276, 0x0 } },
		// Ra Halant Ka MatraI
		{ { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
		  { 0x0173, 0x0151, 0x0276, 0x0 } },
		// Ka Nukta
		{ { 0x0995, 0x09bc, 0x0 },
		  { 0x0151, 0x0171, 0x0 } },
		// Ka Halant Ra
		{ { 0x0995, 0x09cd, 0x09b0, 0x0 },
		  { 0x01f4, 0x0 } },
		// Ka Halant Ra Halant Ka
		{ { 0x0995, 0x09cd, 0x09b0, 0x09cd, 0x0995, 0x0 },
		  { 0x025c, 0x0276, 0x0151, 0x0 } },
		// Ya + Halant
		{ { 0x09af, 0x09cd, 0x0 },
		  { 0x016a, 0x017d, 0x0 } },
		// Da Halant Ya -> Da Ya-Phala
		{ { 0x09a6, 0x09cd, 0x09af, 0x0 },
		  { 0x01e5, 0x0 } },
		// A Halant Ya -> A Ya-phala
		{ { 0x0985, 0x09cd, 0x09af, 0x0 },
		  { 0x0145, 0x01cf, 0x0 } },
		// Na Halant Ka
		{ { 0x09a8, 0x09cd, 0x0995, 0x0 },
		  { 0x026f, 0x0151, 0x0 } },
		// Na Halant ZWNJ Ka
		{ { 0x09a8, 0x09cd, 0x200c, 0x0995, 0x0 },
		  { 0x0164, 0x017d, 0x0151, 0x0 } },
		// Na Halant ZWJ Ka
		{ { 0x09a8, 0x09cd, 0x200d, 0x0995, 0x0 },
		  { 0x026f, 0x0151, 0x0 } },
		// Ka Halant ZWNJ Ka
		{ { 0x0995, 0x09cd, 0x200c, 0x0995, 0x0 },
		  { 0x0151, 0x017d, 0x0151, 0x0 } },
		// Ka Halant ZWJ Ka
		{ { 0x0995, 0x09cd, 0x200d, 0x0995, 0x0 },
		  { 0x025c, 0x0151, 0x0 } },
		// Na Halant Ra
		{ { 0x09a8, 0x09cd, 0x09b0, 0x0 },
		  { 0x0207, 0x0 } },
		// Na Halant ZWNJ Ra
		{ { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
		  { 0x0164, 0x017d, 0x016b, 0x0 } },
		// Na Halant ZWJ Ra
		{ { 0x09a8, 0x09cd, 0x200d, 0x09b0, 0x0 },
		  { 0x026f, 0x016b, 0x0 } },
		// Na Halant Ba
		{ { 0x09a8, 0x09cd, 0x09ac, 0x0 },
		  { 0x022f, 0x0 } },
		// Na Halant ZWNJ Ba
		{ { 0x09a8, 0x09cd, 0x200c, 0x09ac, 0x0 },
		  { 0x0164, 0x017d, 0x0167, 0x0 } },
		// Na Halant ZWJ Ba
		{ { 0x09a8, 0x09cd, 0x200d, 0x09ac, 0x0 },
		  { 0x026f, 0x0167, 0x0 } },
		// Na Halant Dha
		{ { 0x09a8, 0x09cd, 0x09a7, 0x0 },
		  { 0x01d3, 0x0 } },
		// Na Halant ZWNJ Dha
		{ { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
		  { 0x0164, 0x017d, 0x0163, 0x0 } },
		// Na Halant ZWJ Dha
		{ { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
		  { 0x026f, 0x0163, 0x0 } },
		// Ra Halant Ka MatraAU
		{ { 0x09b0, 0x09cd, 0x0995, 0x09cc, 0x0 },
		  { 0x0179, 0x0151, 0x0276, 0x017e, 0x0 } },
		// Ra Halant Ba Halant Ba
		{ { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
		  { 0x0232, 0x0276, 0x0 } },
                { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x982, 0x0 },
                  { 0x151, 0x276, 0x172, 0x143, 0x0 } },
                { { 0x9b0, 0x9cd, 0x995, 0x9be, 0x983, 0x0 },
                  { 0x151, 0x276, 0x172, 0x144, 0x0 } }, 
                // test decomposed two parts matras
                { { 0x995, 0x9c7, 0x9be, 0x0 },
                  { 0x179, 0x151, 0x172, 0x0 } },
                { { 0x995, 0x9c7, 0x9d7, 0x0 },
                  { 0x179, 0x151, 0x17e, 0x0 } },
                { { 0x9b0, 0x9cd, 0x9ad, 0x0 },
                  { 0x168, 0x276, 0x0 } },
                { { 0x9f0, 0x9cd, 0x9ad, 0x0 },
                  { 0x168, 0x276, 0x0 } },
                { { 0x9f1, 0x9cd, 0x9ad, 0x0 },
                  { 0x191, 0x17d, 0x168, 0x0 } },

                // Ra ZWJ Halant Ya
                { { 0x09b0, 0x200d, 0x09cd, 0x09af, 0x0 },
                  { 0x016b, 0x01cf, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Bengali) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find AkaashNormal.ttf");
	}
    }
    {
        FT_Face face = loadFace("MuktiNarrow.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		// Ka
		{ { 0x0995, 0x0 },
		  { 0x0073, 0x0 } },
		// Ka Halant
		{ { 0x0995, 0x09cd, 0x0 },
		  { 0x00b9, 0x0 } },
		// Ka Halant Ka
		{ { 0x0995, 0x09cd, 0x0995, 0x0 },
		  { 0x0109, 0x0 } },
		// Ka MatraI
		{ { 0x0995, 0x09bf, 0x0 },
		  { 0x0095, 0x0073, 0x0 } },
		// Ra Halant Ka
		{ { 0x09b0, 0x09cd, 0x0995, 0x0 },
		  { 0x0073, 0x00e1, 0x0 } },
		// Ra Halant Ka MatraI
		{ { 0x09b0, 0x09cd, 0x0995, 0x09bf, 0x0 },
		  { 0x0095, 0x0073, 0x00e1, 0x0 } },
		// MatraI
 		{ { 0x09bf, 0x0 },
		  { 0x0095, 0x01c8, 0x0 } },
		// Ka Nukta
		{ { 0x0995, 0x09bc, 0x0 },
		  { 0x0073, 0x0093, 0x0 } },
		// Ka Halant Ra
		{ { 0x0995, 0x09cd, 0x09b0, 0x0 },
		  { 0x00e5, 0x0 } },
		// Ka Halant Ra Halant Ka
                { { 0x995, 0x9cd, 0x9b0, 0x9cd, 0x995, 0x0 },
                  { 0x234, 0x24e, 0x73, 0x0 } }, 
		// Ya + Halant
		{ { 0x09af, 0x09cd, 0x0 },
		  { 0x00d2, 0x0 } },
		// Da Halant Ya -> Da Ya-Phala
		{ { 0x09a6, 0x09cd, 0x09af, 0x0 },
		  { 0x0084, 0x00e2, 0x0 } },
		// A Halant Ya -> A Ya-phala
		{ { 0x0985, 0x09cd, 0x09af, 0x0 },
		  { 0x0067, 0x00e2, 0x0 } },
		// Na Halant Ka
		{ { 0x09a8, 0x09cd, 0x0995, 0x0 },
		  { 0x0188, 0x0 } },
		// Na Halant ZWNJ Ka
                { { 0x9a8, 0x9cd, 0x200c, 0x995, 0x0 },
                  { 0xcc, 0x73, 0x0 } }, 
		// Na Halant ZWJ Ka
                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
                  { 0x247, 0x73, 0x0 } }, 
		// Ka Halant ZWNJ Ka
                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
                  { 0x247, 0x73, 0x0 } }, 
		// Ka Halant ZWJ Ka
                { { 0x9a8, 0x9cd, 0x200d, 0x995, 0x0 },
                  { 0x247, 0x73, 0x0 } }, 
		// Na Halant Ra
		{ { 0x09a8, 0x09cd, 0x09b0, 0x0 },
		  { 0x00f8, 0x0 } },
		// Na Halant ZWNJ Ra
		{ { 0x09a8, 0x09cd, 0x200c, 0x09b0, 0x0 },
		  { 0xcc, 0x8d, 0x0 } },
		// Na Halant ZWJ Ra
                { { 0x9a8, 0x9cd, 0x200d, 0x9b0, 0x0 },
                  { 0x247, 0x8d, 0x0 } }, 
		// Na Halant Ba
		{ { 0x09a8, 0x09cd, 0x09ac, 0x0 },
		  { 0x0139, 0x0 } },
		// Na Halant ZWNJ Ba
                { { 0x9a8, 0x9cd, 0x200c, 0x9ac, 0x0 },
                  { 0xcc, 0x89, 0x0 } }, 
		// Na Halant ZWJ Ba
                { { 0x9a8, 0x9cd, 0x200d, 0x9ac, 0x0 },
                  { 0x247, 0x89, 0x0 } }, 
		// Na Halant Dha
		{ { 0x09a8, 0x09cd, 0x09a7, 0x0 },
		  { 0x0145, 0x0 } },
		// Na Halant ZWNJ Dha
		{ { 0x09a8, 0x09cd, 0x200c, 0x09a7, 0x0 },
		  { 0xcc, 0x85, 0x0 } },
		// Na Halant ZWJ Dha
		{ { 0x09a8, 0x09cd, 0x200d, 0x09a7, 0x0 },
		  { 0x247, 0x85, 0x0 } },
		// Ra Halant Ka MatraAU
                { { 0x9b0, 0x9cd, 0x995, 0x9cc, 0x0 },
                  { 0x232, 0x73, 0xe1, 0xa0, 0x0 } }, 
		// Ra Halant Ba Halant Ba
		{ { 0x09b0, 0x09cd, 0x09ac, 0x09cd, 0x09ac, 0x0 },
		  { 0x013b, 0x00e1, 0x0 } },

                // Init feature for vowel sign E should only be
                // applied when it's initial character (QTBUG-13620)
                { { 0x09a8, 0x09c7, 0x0 },
                  { 0x0232, 0x0086, 0x0 } },
                { { 0x09a8, 0x09a8, 0x09c7, 0x0 },
                  { 0x0086, 0x009b, 0x0086, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Bengali) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find MuktiNarrow.ttf");
	}
    }
    {
        FT_Face face = loadFace("LikhanNormal.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		{ { 0x09a8, 0x09cd, 0x09af, 0x0 },
                  { 0x01ca, 0x0 } },
		{ { 0x09b8, 0x09cd, 0x09af, 0x0 },
                  { 0x020e, 0x0 } },
		{ { 0x09b6, 0x09cd, 0x09af, 0x0 },
                  { 0x01f4, 0x0 } },
		{ { 0x09b7, 0x09cd, 0x09af, 0x0 },
                  { 0x01fe, 0x0 } },
		{ { 0x09b0, 0x09cd, 0x09a8, 0x09cd, 0x200d, 0x0 },
                  { 0x10b, 0x167, 0x0 } },
                { { 0x9b0, 0x9cd, 0x9ad, 0x0 },
                  { 0xa1, 0x167, 0x0 } },
                { { 0x9f0, 0x9cd, 0x9ad, 0x0 },
                  { 0xa1, 0x167, 0x0 } },
                { { 0x9f1, 0x9cd, 0x9ad, 0x0 },
                  { 0x11c, 0xa1, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Bengali) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find LikhanNormal.ttf");
	}
    }
}
Esempio n. 6
0
Font::~Font()
{
	FT_Done_Face(face);

	glDeleteTextures(1, &textureID);
}
Esempio n. 7
0
static inline void
closeFont (void)
{
  hb_font_destroy (hb_font);
  FT_Done_Face (ft_face);
}
Esempio n. 8
0
/* ------------------------------------------------------------------------- */
void
texture_font_generate_kerning( TextureFont *self )
{
    size_t i, j, k, count;
    FT_Library   library;
    FT_Face      face;
    FT_UInt      glyph_index, prev_index;
    TextureGlyph *glyph, *prev_glyph;
    FT_Vector    kerning;

    /* Load font */
    if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
    {
        return;
    }

    /* For each glyph couple combination, check if kerning is necessary */
    for( i=0; i<self->glyphs->size; ++i )
    {

        glyph = (TextureGlyph *) vector_get( self->glyphs, i );

        /* Remove any old kerning information */
        if( glyph->kerning )
        {
            free( glyph->kerning );
            glyph->kerning = 0;
            glyph->kerning_count = 0;
        }

        /* Count how many kerning pairs we need */
        count = 0;
        glyph_index = FT_Get_Char_Index( face, glyph->charcode );
        for( j=0; j<self->glyphs->size; ++j )
        {
            prev_glyph = (TextureGlyph *) vector_get( self->glyphs, j );
            prev_index = FT_Get_Char_Index( face, prev_glyph->charcode );
            FT_Get_Kerning( face, prev_index, glyph_index, FT_KERNING_UNFITTED, &kerning );
            if( kerning.x != 0.0 )
            {
                count++;
            }
        }
      
        /* No kerning at all */
        if( !count )
        {
            continue;
        }

        /* Store kerning pairs */
        glyph->kerning = (KerningPair *) malloc( count * sizeof(KerningPair) );
        glyph->kerning_count = count;
        k = 0;
        for( j=0; j<self->glyphs->size; ++j )
        {
            prev_glyph = (TextureGlyph *) vector_get( self->glyphs, j );
            prev_index = FT_Get_Char_Index( face, prev_glyph->charcode );
            FT_Get_Kerning( face, prev_index, glyph_index, FT_KERNING_UNFITTED, &kerning );
            if( kerning.x != 0.0 )
            {
                glyph->kerning[k].charcode = prev_glyph->charcode;
                // 64 * 64 because of 26.6 encoding AND the transform matrix used
                // in texture_font_load_face (hres = 64)
                glyph->kerning[k].kerning = kerning.x/ (float)(64.0f*64.0f);
                ++k;
            }
        }
    }

    FT_Done_Face( face );
    FT_Done_FreeType( library );
}
Esempio n. 9
0
/* ------------------------------------------------------------------------- */
size_t
texture_font_cache_glyphs( TextureFont *self,
                           wchar_t * charcodes )
{
    size_t i, x, y, width, height, depth, w, h;
    FT_Library    library;
    FT_Error      error;
    FT_Face       face;
    FT_GlyphSlot  slot;
    FT_UInt       glyph_index;
    TextureGlyph *glyph;
    Region        region;
    unsigned char c;
    size_t        missed = 0;
    width  = self->atlas->width;
    height = self->atlas->height;
    depth  = self->atlas->depth;

    if( !texture_font_load_face( &library, self->filename, self->size, &face ) )
    {
        return wcslen(charcodes);
    }

    /* Load each glyph */
    for( i=0; i<wcslen(charcodes); ++i )
    {
        glyph_index = FT_Get_Char_Index( face, charcodes[i] );

        // WARNING: We use texture-atlas depth to guess if user wants
        //          LCD subpixel rendering
        FT_Int32 flags = FT_LOAD_RENDER;

        if( !self->hinting )
        {
            flags |= FT_LOAD_NO_HINTING | FT_LOAD_NO_AUTOHINT;
        }
        else
        {
            flags |= FT_LOAD_FORCE_AUTOHINT;
        }

        if( depth == 3 )
        {
            FT_Library_SetLcdFilter( library, FT_LCD_FILTER_LIGHT );
            flags |= FT_LOAD_TARGET_LCD;
            if( self->lcd_filter )
            {
                FT_Library_SetLcdFilterWeights( library, self->lcd_weights );
            }
        }
        error = FT_Load_Glyph( face, glyph_index, flags );

        if( error )
        {
            fprintf(stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                    __LINE__, FT_Errors[error].code, FT_Errors[error].message);
            FT_Done_FreeType( library );
            return wcslen(charcodes)-i;
        }
        slot = face->glyph;

        /* Gamma correction (sort of) */
        for( x=0; x<slot->bitmap.width; ++x )
        {
            for( y=0; y<slot->bitmap.rows; ++y )
            {
                c = *(unsigned char *)(slot->bitmap.buffer
                                       + y*slot->bitmap.pitch + x );
                c = (unsigned char) ( pow(c/255.0, self->gamma) * 255);
                *(unsigned char *)(slot->bitmap.buffer
                                   + y*slot->bitmap.pitch + x ) = c;
            }
        }

        // We want each glyph to be separated by at least one black pixel
        // (for example for shader used in demo-subpixel.c)
        w = slot->bitmap.width/depth + 1;
        h = slot->bitmap.rows + 1;
        region = texture_atlas_get_region( self->atlas, w, h );
        if ( region.x < 0 )
        {
            missed++;
            continue;
        }
        w = w - 1;
        h = h - 1;
        x = region.x;
        y = region.y;
        texture_atlas_set_region( self->atlas, x, y, w, h,
                                  slot->bitmap.buffer, slot->bitmap.pitch );

        glyph = texture_glyph_new( );
        glyph->font = self;
        glyph->charcode = charcodes[i];
        glyph->kerning  = 0;
        glyph->width    = w;
        glyph->height   = h;
        glyph->offset_x = slot->bitmap_left;
        glyph->offset_y = slot->bitmap_top;
        glyph->u0       = x/(float)width;
        glyph->v0       = y/(float)height;
        glyph->u1       = (x + glyph->width)/(float)width;
        glyph->v1       = (y + glyph->height)/(float)height;

        /* Discard hinting to get advance */
        FT_Load_Glyph( face, glyph_index, FT_LOAD_RENDER | FT_LOAD_NO_HINTING);
        slot = face->glyph;
        glyph->advance_x    = slot->advance.x/64.0;
        glyph->advance_y    = slot->advance.y/64.0;

        vector_push_back( self->glyphs, glyph );
        texture_glyph_delete( glyph );
    }
    FT_Done_Face( face );
    FT_Done_FreeType( library );
    texture_atlas_upload( self->atlas );
    texture_font_generate_kerning( self );
    return missed;
}
//------------------------------------------------------------------
void ofTrueTypeFont::loadFont(string filename, int fontsize, bool _bAntiAliased, bool _bFullCharacterSet, bool makeContours, float simplifyAmt){

	bMakeContours = makeContours;

	//------------------------------------------------
	if (bLoadedOk == true){

		// we've already been loaded, try to clean up :
		unloadTextures();
	}
	//------------------------------------------------


	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.resize(nCharacters);

	if(bMakeContours){
		charOutlines.clear();
		charOutlines.assign(nCharacters, ofTTFCharacter());
	}

	vector<ofPixels> expanded_data(nCharacters);

	long areaSum=0;

	//--------------------- 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;


		// 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
		// ------------------------- we just set it to 2...
		if (width == 1) width = 2;
		if (height == 1) height = 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 );
			if(simplifyAmt>0)
				charOutlines[i].simplify(simplifyAmt);
			charOutlines[i].getTessellation();
		}


		// -------------------------
		// info about the character:
		cps[i].character		= i;
		cps[i].height 			= face->glyph->bitmap_top;
		cps[i].width 			= face->glyph->bitmap.width;
		cps[i].setWidth 		= face->glyph->advance.x >> 6;
		cps[i].topExtent 		= face->glyph->bitmap.rows;
		cps[i].leftExtent		= face->glyph->bitmap_left;

		int width  = cps[i].width;
		int height = bitmap.rows;


		cps[i].tW				= width;
		cps[i].tH				= height;



		GLint fheight	= cps[i].height;
		GLint bwidth	= cps[i].width;
		GLint top		= cps[i].topExtent - cps[i].height;
		GLint lextent	= cps[i].leftExtent;

		GLfloat	corr, stretch;

		//this accounts for the fact that we are showing 2*visibleBorder extra pixels
		//so we make the size of each char that many pixels bigger
		stretch = 0;//(float)(visibleBorder * 2);

		corr	= (float)(( (fontSize - fheight) + top) - fontSize);

		cps[i].x1		= lextent + bwidth + stretch;
		cps[i].y1		= fheight + corr + stretch;
		cps[i].x2		= (float) lextent;
		cps[i].y2		= -top + corr;


		// Allocate Memory For The Texture Data.
		expanded_data[i].allocate(width, height, 2);
		//-------------------------------- clear data:
		expanded_data[i].set(0,255); // every luminance pixel = 255
		expanded_data[i].set(1,0);


		if (bAntiAlised == true){
			ofPixels bitmapPixels;
			bitmapPixels.setFromExternalPixels(bitmap.buffer,bitmap.width,bitmap.rows,1);
			expanded_data[i].setChannel(1,bitmapPixels);
		} else {
			//-----------------------------------
			// true type packs monochrome info in a
			// 1-bit format, hella funky
			// here we unpack it:
			unsigned char *src =  bitmap.buffer;
			for(int j=0; j <bitmap.rows;j++) {
				unsigned char b=0;
				unsigned char *bptr =  src;
				for(int k=0; k < bitmap.width ; k++){
					expanded_data[i][2*(k+j*width)] = 255;

					if (k%8==0){
						b = (*bptr++);
					}

					expanded_data[i][2*(k+j*width) + 1] = b&0x80 ? 255 : 0;
					b <<= 1;
				}
				src += bitmap.pitch;
			}
			//-----------------------------------
		}

		areaSum += (cps[i].width+border*2)*(cps[i].height+border*2);
	}


	vector<charProps> sortedCopy = cps;
	sort(sortedCopy.begin(),sortedCopy.end(),&compare_cps);

	// pack in a texture, algorithm to calculate min w/h from
	// http://upcommons.upc.edu/pfc/bitstream/2099.1/7720/1/TesiMasterJonas.pdf
	//cout << areaSum << endl;

	bool packed = false;
	float alpha = logf(areaSum)*1.44269;

	int w;
	int h;
	while(!packed){
		w = pow(2,floor((alpha/2.f) + 0.5)); // there doesn't seem to be a round in cmath for windows.
		//w = pow(2,round(alpha/2.f));
		h = w;//pow(2,round(alpha - round(alpha/2.f)));
		int x=0;
		int y=0;
		int maxRowHeight = sortedCopy[0].tH + border*2;
		for(int i=0;i<(int)cps.size();i++){
			if(x+sortedCopy[i].tW + border*2>w){
				x = 0;
				y += maxRowHeight;
				maxRowHeight = sortedCopy[i].tH + border*2;
				if(y + maxRowHeight > h){
					alpha++;
					break;
				}
			}
			x+= sortedCopy[i].tW + border*2;
			if(i==(int)cps.size()-1) packed = true;
		}

	}



	ofPixels atlasPixels;
	atlasPixels.allocate(w,h,2);
	atlasPixels.set(0,255);
	atlasPixels.set(1,0);


	int x=0;
	int y=0;
	int maxRowHeight = sortedCopy[0].tH + border*2;
	for(int i=0;i<(int)cps.size();i++){
		ofPixels & charPixels = expanded_data[sortedCopy[i].character];

		if(x+sortedCopy[i].tW + border*2>w){
			x = 0;
			y += maxRowHeight;
			maxRowHeight = sortedCopy[i].tH + border*2;
		}

		cps[sortedCopy[i].character].t2		= float(x + border)/float(w);
		cps[sortedCopy[i].character].v2		= float(y + border)/float(h);
		cps[sortedCopy[i].character].t1		= float(cps[sortedCopy[i].character].tW + x + border)/float(w);
		cps[sortedCopy[i].character].v1		= float(cps[sortedCopy[i].character].tH + y + border)/float(h);
		charPixels.pasteInto(atlasPixels,x+border,y+border);
		x+= sortedCopy[i].tW + border*2;
	}


	texAtlas.allocate(atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA,false);

	if(bAntiAlised && fontsize>14){
		texAtlas.setTextureMinMagFilter(GL_LINEAR,GL_LINEAR);
	}else{
		texAtlas.setTextureMinMagFilter(GL_NEAREST,GL_NEAREST);
	}

	texAtlas.loadData(atlasPixels.getPixels(),atlasPixels.getWidth(),atlasPixels.getHeight(),GL_LUMINANCE_ALPHA);

	// ------------- close the library and typeface
	FT_Done_Face(face);
	FT_Done_FreeType(library);
  	bLoadedOk = true;
}
Esempio n. 11
0
XeTeXFontMgr::NameCollection*
XeTeXFontMgr_FC::readNames(FcPattern* pat)
{
	NameCollection*	names = new NameCollection;

	char*	pathname;
	if (FcPatternGetString(pat, FC_FILE, 0, (FcChar8**)&pathname) != FcResultMatch)
		return names;
	int index;
	if (FcPatternGetInteger(pat, FC_INDEX, 0, &index) != FcResultMatch)
		return names;

	FT_Face face;
	if (FT_New_Face(gFreeTypeLibrary, pathname, index, &face) != 0)
		return names;

	const char* name = FT_Get_Postscript_Name(face);
	if (name == NULL)
		return names;
	names->psName = name;

	// for sfnt containers, we'll read the name table ourselves, not rely on Fontconfig
	if (FT_IS_SFNT(face)) {
		std::list<std::string>	familyNames;
		std::list<std::string>	subFamilyNames;
		FT_SfntName	nameRec;
		for (index = 0; index < FT_Get_Sfnt_Name_Count(face); ++index) {
			char*	utf8name = NULL;
			if (FT_Get_Sfnt_Name(face, index, &nameRec) != 0)
				continue;
			switch (nameRec.name_id) {
				case kFontFullName:
				case kFontFamilyName:
				case kFontStyleName:
				case kPreferredFamilyName:
				case kPreferredSubfamilyName:
					{
						bool	preferredName = false;
						if (nameRec.platform_id == TT_PLATFORM_MACINTOSH
								&& nameRec.encoding_id == TT_MAC_ID_ROMAN && nameRec.language_id == 0) {
							utf8name = convertToUtf8(macRomanConv, nameRec.string, nameRec.string_len);
							preferredName = true;
						}
						else if ((nameRec.platform_id == TT_PLATFORM_APPLE_UNICODE)
								|| (nameRec.platform_id == TT_PLATFORM_MICROSOFT))
							utf8name = convertToUtf8(utf16beConv, nameRec.string, nameRec.string_len);

						if (utf8name != NULL) {
							std::list<std::string>*	nameList = NULL;
							switch (nameRec.name_id) {
								case kFontFullName:
									nameList = &names->fullNames;
									break;
								case kFontFamilyName:
									nameList = &names->familyNames;
									break;
								case kFontStyleName:
									nameList = &names->styleNames;
									break;
								case kPreferredFamilyName:
									nameList = &familyNames;
									break;
								case kPreferredSubfamilyName:
									nameList = &subFamilyNames;
									break;
							}
							if (preferredName)
								prependToList(nameList, utf8name);
							else
								appendToList(nameList, utf8name);
						}
					}
					break;
			}
		}
		if (familyNames.size() > 0)
			names->familyNames = familyNames;
		if (subFamilyNames.size() > 0)
			names->styleNames = subFamilyNames;
	}
	else {
		index = 0;
		while (FcPatternGetString(pat, FC_FULLNAME, index++, (FcChar8**)&name) == FcResultMatch)
			appendToList(&names->fullNames, name);
		index = 0;
		while (FcPatternGetString(pat, FC_FAMILY, index++, (FcChar8**)&name) == FcResultMatch)
			appendToList(&names->familyNames, name);
		index = 0;
		while (FcPatternGetString(pat, FC_STYLE, index++, (FcChar8**)&name) == FcResultMatch)
			appendToList(&names->styleNames, name);

		if (names->fullNames.size() == 0) {
			std::string fullName(names->familyNames.front());
			if (names->styleNames.size() > 0) {
				fullName += " ";
				fullName += names->styleNames.front();
			}
			names->fullNames.push_back(fullName);
		}
	}

	FT_Done_Face(face);

	return names;
}
Esempio n. 12
0
int
main( int     argc,
      char**  argv )
{
  FT_Library    library;
  FT_Face       face;

  FT_GlyphSlot  slot;
  FT_Matrix     matrix;                 /* transformation matrix */
  FT_Vector     pen;                    /* untransformed origin  */
  FT_Error      error;

  char*         filename;
//  char*         text;

  double        angle;
  int           target_height;
  int           n, num_chars;

  wchar_t *chinese_str = L"ол╣Щ1g";
  unsigned int *p = (unsigned int *)chinese_str;
  int i;

  printf("Uniocde: \n");
  for (i = 0; i < wcslen(chinese_str); i++)
  {
  	printf("0x%x ", p[i]);
  }
  printf("\n");
//  return 0;


  if ( argc != 2 )
  {
    fprintf ( stderr, "usage: %s font\n", argv[0] );
    exit( 1 );
  }

  filename      = argv[1];                           /* first argument     */
//  text          = argv[2];                           /* second argument    */
  num_chars     = wcslen(chinese_str);
  angle         = ( 0.0 / 360 ) * 3.14159 * 2;      /* use 0 degrees     */
  target_height = HEIGHT;

  error = FT_Init_FreeType( &library );              /* initialize library */
  /* error handling omitted */

  error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */
  /* error handling omitted */

  /* use 20pt at 100dpi */
  error = FT_Set_Char_Size( face, 20 * 64, 0,
                            100, 0 );                /* set character size */
  /* error handling omitted */

  slot = face->glyph;

  /* set up matrix */
  matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
  matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
  matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
  matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );

  /* the pen position in 26.6 cartesian space coordinates; */
  /* start at (0,40) relative to the upper left corner  */
  pen.x = 0 * 64;
  pen.y = ( target_height - 40 ) * 64;

  for ( n = 0; n < num_chars; n++ )
  {
    /* set transformation */
    FT_Set_Transform( face, &matrix, &pen );

    /* load glyph image into the slot (erase previous one) */
    error = FT_Load_Char( face, chinese_str[n], FT_LOAD_RENDER );
    if ( error )
      continue;                 /* ignore errors */

    /* now, draw to our target surface (convert position) */
    draw_bitmap( &slot->bitmap,
                 slot->bitmap_left,
                 target_height - slot->bitmap_top );

    /* increment pen position */
    pen.x += slot->advance.x;
    pen.y += slot->advance.y;
  }

  show_image();

  FT_Done_Face    ( face );
  FT_Done_FreeType( library );

  return 0;
}
Esempio n. 13
0
void FreeTypeLib::freeFace(FT_Face* face) {
    FT_Done_Face(*face);
    delete face;
}
Esempio n. 14
0
		//-----------------------------------------------------------------//
		~ftimg() {
			for(face_map_it it = face_map_.begin(); it != face_map_.end(); ++it) {
				FT_Done_Face(it->second.face_);
			}
			FT_Done_FreeType(library_);
		}
Esempio n. 15
0
SFMLGfx::~SFMLGfx()
{
	FT_Done_Face(font);
	FT_Done_FreeType(freetypeHandle);
}
Esempio n. 16
0
void TTFLibrary::closeFont(FT_Face &face) {
	assert(_initialized);

	FT_Done_Face(face);
}
Esempio n. 17
0
static FT_Face LoadFace( filter_t *p_filter, const char *psz_fontfile, int i_idx,
                  const text_style_t *p_style )
{
    filter_sys_t *p_sys = p_filter->p_sys;
    char *psz_key = NULL;

    int i_font_size  = ConvertToLiveSize( p_filter, p_style );
    int i_font_width = p_style->i_style_flags & STYLE_HALFWIDTH ?
                       i_font_size / 2 : i_font_size;

    if( asprintf( &psz_key, "%s - %d - %d - %d",
                  psz_fontfile, i_idx,
                  i_font_size, i_font_width ) < 0 )
        return NULL;

    FT_Face p_face = vlc_dictionary_value_for_key( &p_sys->face_map, psz_key );
    if( p_face != kVLCDictionaryNotFound )
        goto done;

    if( psz_fontfile[0] == ':' && psz_fontfile[1] == '/' )
    {
        int i_attach = atoi( psz_fontfile + 2 );
        if( i_attach < 0 || i_attach >= p_sys->i_font_attachments )
        {
            msg_Err( p_filter, "LoadFace: Invalid font attachment index" );
            p_face = NULL;
        }
        else
        {
            input_attachment_t *p_attach = p_sys->pp_font_attachments[ i_attach ];
            if( FT_New_Memory_Face( p_sys->p_library, p_attach->p_data,
                                    p_attach->i_data, i_idx, &p_face ) )
                p_face = NULL;
        }
    }
    else
        if( FT_New_Face( p_sys->p_library, psz_fontfile, i_idx, &p_face ) )
        {
            msg_Err( p_filter, "LoadFace: Error creating face for %s", psz_key );
            p_face = NULL;
        }

    if( !p_face )
        goto done;

    if( FT_Select_Charmap( p_face, ft_encoding_unicode ) )
    {
        /* We've loaded a font face which is unhelpful for actually
         * rendering text - fallback to the default one.
         */
        msg_Err( p_filter, "LoadFace: Error selecting charmap for %s", psz_key );
        FT_Done_Face( p_face );
        p_face = NULL;
        goto done;
    }

    if( FT_Set_Pixel_Sizes( p_face, i_font_width, i_font_size ) )
    {
        msg_Err( p_filter,
                 "LoadFace: Failed to set font size for %s", psz_key );
        FT_Done_Face( p_face );
        p_face = NULL;
        goto done;
    }

    vlc_dictionary_insert( &p_sys->face_map, psz_key, p_face );

done:
    free( psz_key );
    return p_face;
}
void DemoEntityManager::CreateOpenGlFont()
{
	FT_Library  library;
	FT_Error error = FT_Init_FreeType (&library);
	if ( !error )
	{
		char fileName[2048];
		//GetWorkingFileName ("arial.ttf", fileName);
		//GetWorkingFileName ("calibri.ttf", fileName);
		GetWorkingFileName ("courbd.ttf", fileName);
				

		FT_Face face[96];   
		int withInPixels = 12;
		int heightInPixels = 16;

		int width = 0;
		int height = 0;
		for (int ch = 0; ch < 96; ch ++) {
			// Load The Glyph For Our Character.
			error = FT_New_Face( library, fileName, 0, &face[ch] );
			dAssert (!error);

			FT_Face bitmap = face[ch];   

			error = FT_Set_Char_Size(bitmap, withInPixels * 64, heightInPixels * 64, 96, 96);
			dAssert (!error);

			FT_UInt index = FT_Get_Char_Index( face[ch], ch + ' ');
			//FT_UInt index = FT_Get_Char_Index (bitmap, 'A');

			error = FT_Load_Glyph (bitmap, index, FT_LOAD_DEFAULT );
			dAssert (!error);

			error = FT_Render_Glyph (bitmap->glyph, FT_RENDER_MODE_NORMAL); 
			dAssert (!error);

			const FT_Glyph_Metrics& metrics = bitmap->glyph->metrics;
			int w = metrics.width / 64;
			int h = metrics.height / 64;

			width += w;
			height = (height > h) ? height : h;
		}

		int imageWidth = TwosPower (width);
		int imageHeight = TwosPower (height);

		char* const image = new char[2 * imageWidth * imageHeight];
		memset (image, 0, 2 * imageWidth * imageHeight);

		int maxWidth = 0;
		int imageBase = 0;
		
		for (int ch = 0; ch < 96; ch ++) {
			FT_Face bitmap = face[ch];   
			FT_GlyphSlot slot = bitmap->glyph;

			const FT_Glyph_Metrics& metrics = slot->metrics;
			int w = metrics.width / 64;
			int h = metrics.height / 64;

			maxWidth = (w > maxWidth) ? w : maxWidth;
			if (w) {
				const unsigned char* const buffer = slot->bitmap.buffer;
				int pitch =  slot->bitmap.pitch;

				int posit = imageBase;
				for (int j = 0; j < h; j ++) {
					for (int i = 0; i < w; i ++) {
						int color = buffer[j * pitch + i];
						image[posit + i * 2 + 0] = color;
						image[posit + i * 2 + 1] = color;
					}
					posit += imageWidth * 2;
				}
				imageBase += w * 2;
			}
		}

		// make th open gl display list here
	    m_fontImage = LoadImage("fontTexture", image, imageWidth, imageHeight, m_luminace);

		m_font = glGenLists(96);
		glBindTexture(GL_TEXTURE_2D, m_fontImage);

		imageBase = 0;
		for (int ch = 0; ch < 96; ch ++) {
			FT_Face bitmap = face[ch];   
			FT_GlyphSlot slot = bitmap->glyph;
			const FT_Glyph_Metrics& metrics = slot->metrics;

			glNewList(m_font + ch, GL_COMPILE);
			glPushMatrix();
//			glTranslatef(slot->bitmap_left, 64 - slot->bitmap_top, 0);
			glTranslatef(slot->bitmap_left, - slot->bitmap_top, 0);

			dFloat w = dFloat (metrics.width / 64);
			dFloat h = dFloat (metrics.height / 64);

			if (w) {
				dFloat u0 = dFloat (imageBase) / imageWidth;
				dFloat u1 = dFloat (imageBase + w - 1.0f) / imageWidth;

				dFloat v0 = 0.0f;
				dFloat v1 = (h - 1.0f) / imageHeight;

				glBegin(GL_QUADS);

				glTexCoord2d (u0, v0); 
				glVertex2i(0, 0);

				glTexCoord2d (u0, v1); 
				glVertex2i(0, h - 1);

				glTexCoord2d (u1, v1); 
				glVertex2i (w - 1, h - 1);

				glTexCoord2d (u1, v0); 
				glVertex2i (w - 1, 0);
				glEnd();

				imageBase += w;
			}
			glPopMatrix();
			
			//glTranslatef(maxWidth, 0, 0);
			glTranslatef(metrics.horiAdvance / 64, 0, 0);

			glEndList();
			FT_Done_Face(bitmap);
		}

		delete[] image; 

		// destroy the free type library	
		FT_Done_FreeType (library);
	}
}
Esempio n. 19
0
void FreeTypeFont::doClose() {
    CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Done_Face(ftFont) == 0);
    _data = nullptr;
    ftFont = nullptr;
}
Esempio n. 20
0
 static void ReleaseFont(FT_Face face)
 {
   assert(face);
   FT_Done_Face(face);
 };
Esempio n. 21
0
void tst_QScriptEngine::kannada()
{
    {
        FT_Face face = loadFace("Sampige.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		{ { 0x0ca8, 0x0ccd, 0x0ca8, 0x0 },
		  { 0x0049, 0x00ba, 0x0 } },
		{ { 0x0ca8, 0x0ccd, 0x0ca1, 0x0 },
		  { 0x0049, 0x00b3, 0x0 } },
		{ { 0x0caf, 0x0cc2, 0x0 },
		  { 0x004f, 0x005d, 0x0 } },
		{ { 0x0ce0, 0x0 },
		  { 0x006a, 0x0 } },
		{ { 0x0ce6, 0x0ce7, 0x0ce8, 0x0 },
		  { 0x006b, 0x006c, 0x006d, 0x0 } },
		{ { 0x0cb5, 0x0ccb, 0x0 },
		  { 0x015f, 0x0067, 0x0 } },
		{ { 0x0cb0, 0x0ccd, 0x0cae, 0x0 },
		  { 0x004e, 0x0082, 0x0 } },
		{ { 0x0cb0, 0x0ccd, 0x0c95, 0x0 },
		  { 0x0036, 0x0082, 0x0 } },
		{ { 0x0c95, 0x0ccd, 0x0cb0, 0x0 },
		  { 0x0036, 0x00c1, 0x0 } },
		{ { 0x0cb0, 0x0ccd, 0x200d, 0x0c95, 0x0 },
		  { 0x0050, 0x00a7, 0x0 } },

                // Kaphala
                { { 0x0cb0, 0x200d, 0x0ccd, 0x0c95, 0x0 },
                  { 0x0050, 0x00a7, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Kannada) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find Sampige.ttf");
	}
    }
    {
        FT_Face face = loadFace("tunga.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		{ { 0x0cb7, 0x0cc6, 0x0 },
		  { 0x00b0, 0x006c, 0x0 } },
		{ { 0x0cb7, 0x0ccd, 0x0 },
		  { 0x0163, 0x0 } },
                { { 0xc95, 0xcbf, 0xcd5, 0x0 },
                  { 0x114, 0x73, 0x0 } },
                { { 0xc95, 0xcc6, 0xcd5, 0x0 },
                  { 0x90, 0x6c, 0x73, 0x0 } },
                { { 0xc95, 0xcc6, 0xcd6, 0x0 },
                  { 0x90, 0x6c, 0x74, 0x0 } },
                { { 0xc95, 0xcc6, 0xcc2, 0x0 },
                  { 0x90, 0x6c, 0x69, 0x0 } },
                { { 0xc95, 0xcca, 0xcd5, 0x0 },
                  { 0x90, 0x6c, 0x69, 0x73, 0x0 } },


		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Kannada) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find tunga.ttf");
	}
    }
}
Esempio n. 22
0
triebWerk::CFontFace::~CFontFace()
{
    FT_Done_Face(m_Face);
}
Esempio n. 23
0
void tst_QScriptEngine::devanagari()
{
    {
        FT_Face face = loadFace("raghu.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		// Ka
		{ { 0x0915, 0x0 },
		  { 0x0080, 0x0 } },
		// Ka Halant
		{ { 0x0915, 0x094d, 0x0 },
		  { 0x0080, 0x0051, 0x0 } },
		// Ka Halant Ka
		{ { 0x0915, 0x094d, 0x0915, 0x0 },
		  { 0x00c8, 0x0080, 0x0 } },
		// Ka MatraI
		{ { 0x0915, 0x093f, 0x0 },
		  { 0x01d1, 0x0080, 0x0 } },
		// Ra Halant Ka
		{ { 0x0930, 0x094d, 0x0915, 0x0 },
		  { 0x0080, 0x005b, 0x0 } },
		// Ra Halant Ka MatraI
		{ { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
		  { 0x01d1, 0x0080, 0x005b, 0x0 } },
		// MatraI
		{ { 0x093f, 0x0 },
		  { 0x01d4, 0x029c, 0x0 } },
		// Ka Nukta
		{ { 0x0915, 0x093c, 0x0 },
		  { 0x00a4, 0x0 } },
		// Ka Halant Ra
		{ { 0x0915, 0x094d, 0x0930, 0x0 },
		  { 0x0110, 0x0 } },
		// Ka Halant Ra Halant Ka
		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
		  { 0x0158, 0x0080, 0x0 } },
		{ { 0x0930, 0x094d, 0x200d, 0x0 },
		  { 0x00e2, 0x0 } },
		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x200d, 0x0 },
		  { 0x0158, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Devanagari) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find raghu.ttf");
	}
    }

    {
        FT_Face face = loadFace("mangal.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		// Ka
		{ { 0x0915, 0x0 },
		  { 0x0080, 0x0 } },
		// Ka Halant
		{ { 0x0915, 0x094d, 0x0 },
		  { 0x0080, 0x0051, 0x0 } },
		// Ka Halant Ka
		{ { 0x0915, 0x094d, 0x0915, 0x0 },
		  { 0x00c8, 0x0080, 0x0 } },
		// Ka MatraI
		{ { 0x0915, 0x093f, 0x0 },
		  { 0x01d1, 0x0080, 0x0 } },
		// Ra Halant Ka
		{ { 0x0930, 0x094d, 0x0915, 0x0 },
		  { 0x0080, 0x005b, 0x0 } },
		// Ra Halant Ka MatraI
		{ { 0x0930, 0x094d, 0x0915, 0x093f, 0x0 },
		  { 0x01d1, 0x0080, 0x005b, 0x0 } },
		// MatraI
		{ { 0x093f, 0x0 },
		  { 0x01d4, 0x029c, 0x0 } },
		// Ka Nukta
		{ { 0x0915, 0x093c, 0x0 },
		  { 0x00a4, 0x0 } },
		// Ka Halant Ra
		{ { 0x0915, 0x094d, 0x0930, 0x0 },
		  { 0x0110, 0x0 } },
		// Ka Halant Ra Halant Ka
		{ { 0x0915, 0x094d, 0x0930, 0x094d, 0x0915, 0x0 },
		  { 0x0158, 0x0080, 0x0 } },

                { { 0x92b, 0x94d, 0x930, 0x0 },
                  { 0x125, 0x0 } },
                { { 0x92b, 0x93c, 0x94d, 0x930, 0x0 },
                  { 0x149, 0x0 } }, 
		{ {0}, {0} }
	    };

	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Devanagari) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couldn't find mangal.ttf");
	}
    }
}
Esempio n. 24
0
 void tearDownFreetype()
 {
     FT_Done_Face(face);
     FT_Done_FreeType(library);
 }
Esempio n. 25
0
void tst_QScriptEngine::tamil()
{
    {
        FT_Face face = loadFace("akruti1.ttf");
        if (face) {
	    const ShapeTable shape_table [] = {
		{ { 0x0b95, 0x0bc2, 0x0 },
		  { 0x004e, 0x0 } },
		{ { 0x0bae, 0x0bc2, 0x0 },
		  { 0x009e, 0x0 } },
		{ { 0x0b9a, 0x0bc2, 0x0 },
		  { 0x0058, 0x0 } },
		{ { 0x0b99, 0x0bc2, 0x0 },
		  { 0x0053, 0x0 } },
		{ { 0x0bb0, 0x0bc2, 0x0 },
		  { 0x00a8, 0x0 } },
		{ { 0x0ba4, 0x0bc2, 0x0 },
		  { 0x008e, 0x0 } },
		{ { 0x0b9f, 0x0bc2, 0x0 },
		  { 0x0062, 0x0 } },
		{ { 0x0b95, 0x0bc6, 0x0 },
		  { 0x000a, 0x0031, 0x0 } },
		{ { 0x0b95, 0x0bca, 0x0 },
		  { 0x000a, 0x0031, 0x0007, 0x0 } },
		{ { 0x0b95, 0x0bc6, 0x0bbe, 0x0 },
		  { 0x000a, 0x0031, 0x007, 0x0 } },
		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0 },
		  { 0x0049, 0x0 } },
		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0bca, 0x0 },
		  { 0x000a, 0x0049, 0x007, 0x0 } },
		{ { 0x0b95, 0x0bcd, 0x0bb7, 0x0bc6, 0x0bbe, 0x0 },
		  { 0x000a, 0x0049, 0x007, 0x0 } },
		{ { 0x0b9f, 0x0bbf, 0x0 },
		  { 0x005f, 0x0 } },
		{ { 0x0b9f, 0x0bc0, 0x0 },
		  { 0x0060, 0x0 } },
		{ { 0x0bb2, 0x0bc0, 0x0 },
		  { 0x00ab, 0x0 } },
		{ { 0x0bb2, 0x0bbf, 0x0 },
		  { 0x00aa, 0x0 } },
		{ { 0x0bb0, 0x0bcd, 0x0 },
		  { 0x00a4, 0x0 } },
		{ { 0x0bb0, 0x0bbf, 0x0 },
		  { 0x00a5, 0x0 } },
		{ { 0x0bb0, 0x0bc0, 0x0 },
		  { 0x00a6, 0x0 } },
		{ { 0x0b83, 0x0 },
		  { 0x0025, 0x0 } },
		{ { 0x0b83, 0x0b95, 0x0 },
		  { 0x0025, 0x0031, 0x0 } },

		{ {0}, {0} }
	    };


	    const ShapeTable *s = shape_table;
	    while (s->unicode[0]) {
		QVERIFY( shaping(face, s, HB_Script_Tamil) );
		++s;
	    }

            FT_Done_Face(face);
	} else {
	    QSKIP("couln't find akruti1.ttf");
	}
    }
}
Esempio n. 26
0
/* ------------------------------------------------------------------------- */
int main ( int argc, char *argv[] )
{
    FT_Library  library;
    FT_Face     face;
    FT_FaceRec  props;
    FT_Error    error = 0;
    FT_UInt     names;
    FT_CharMap  charmap;
    FX_Kern_0   *kstable;
    TT_OS2      *pOS2;
    TT_Postscript *ppost;
    ULONG       rc;
    BOOL        bDumpUCS = FALSE;
    BOOL        bShowKST = FALSE;
    BOOL        bShowOS2 = FALSE;
    BOOL        bShowPS  = FALSE;
    char        szPID[10];
    char        szEID[32];
    int         i;


    char     *buf;

    if ( argc < 2 ) {
        printf("FONTNAME - Show summary of OpenType font names and other optional information.\n");
        printf("Syntax: FONTNAME <filename> [ options ]\n\n");
        printf("  /D    Dump Unicode and DBCS strings as hex values\n");
        printf("  /K    Show kerning summary (KERN format 0 only)\n");
        printf("  /O    Show OS/2 table\n");
        printf("  /P    Show POST table\n\n");
        printf("NAME and CMAP table information is always shown.\n\n");
        printf("\nNo font file specified.\n");
        return 0;
    }
    for ( i = 2; i < argc; i++ ) {
        if ( strlen( argv[i] ) > 1 ) {
            CHAR cOption = 0;
            if ( argv[i][0] == '/' || argv[i][0] == '-') cOption = argv[i][1];
            switch ( cOption ) {
                case 'd':
                case 'D':
                    bDumpUCS = TRUE;
                    break;
                case 'k':
                case 'K':
                    bShowKST = TRUE;
                    break;
                case 'o':
                case 'O':
                    bShowOS2 = TRUE;
                    break;
                case 'p':
                case 'P':
                    bShowPS = TRUE;
                    break;
                default : break;
            }
        }
    }

    if (( rc = UniCreateUconvObject( L"@endian=big", &uconv )) != ULS_SUCCESS ) {
        printf("Failed to create Unicode conversion object (rc=0x%X).\n");
        printf("Unicode text values will not be shown.\n");
        uconv = NULL;
    }

    error = FT_Init_FreeType( &library );
    if ( error ) {
        printf("An error occurred during library initialization.\n");
        return (int) error;
    }
    printf("FreeType 2 library initialized successfully.\n");

    error = FT_New_Face( library, argv[1], 0, &face );
    if ( error ) {
        if ( error == FT_Err_Unknown_File_Format )
            printf("The file format is unsupported.\n");
        else
            printf("The file \"%s\" could not be loaded.\n", argv[1]);
        goto done;
    }
    printf("Font %s read successfully.\n", face->family_name );

    names = FT_Get_Sfnt_Name_Count( face );
    if ( names ) {

        printf("Names table contains %d entries:\n", names );
        for ( i = 0; i < names; i++ ) {
            FT_SfntName name;
            error = FT_Get_Sfnt_Name( face, i, &name );
            if ( error ) continue;
            printf("%2d: Plat %d, Enc %d, Lang 0x%X, ID %2d ",
                   i, name.platform_id, name.encoding_id, name.language_id, name.name_id );
            if ( name.platform_id == 1 && name.encoding_id == 0 && name.string_len < 100 ) {
                printf(" \"");
                PrintNameString( name.string, name.string_len );
                printf("\"\n");
            }
            else if ( name.platform_id == 3 && name.encoding_id == 1 && uconv && name.string_len < 200 ) {
                printf(" (U)\"");
                if (bDumpUCS)
                    DumpUnicodeString( name.string, name.string_len );
                else
                    PrintUnicodeString( name.string, name.string_len );
                printf("\"\n");
            }
            else if ( name.string_len < 200 && bDumpUCS ) {
                printf(" \"");
                DumpUnicodeString( name.string, name.string_len );
                printf("\"\n");
            }
            else
                printf(" [%d bytes]\n", name.string_len );
        }
    }

    printf("\nINCLUDED CMAPS");
    printf("\n--------------\n");
    for ( i = 0; i < face->num_charmaps; i++ ) {
        charmap = face->charmaps[i];
        switch ( charmap->platform_id ) {
            case 0:
                strcpy( szPID, "Unicode");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "default");     break;
                    case 1:  strcpy( szEID, "1.1");         break;
                    case 3:  strcpy( szEID, "2+");          break;
                    case 4:  strcpy( szEID, "3.1+ UTF-32"); break;
                    default: strcpy( szEID, "unknown");     break;
                }
                break;

            case 1:
                strcpy( szPID, "Macintosh");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "Roman");         break;
                    case 1:  strcpy( szEID, "Japanese");      break;
                    case 2:  strcpy( szEID, "Chinese-T");     break;
                    case 3:  strcpy( szEID, "Korean");        break;
                    case 8:  strcpy( szEID, "symbols");       break;
                    case 25: strcpy( szEID, "Chinese-S");     break;
                    default: strcpy( szEID, "other language");break;
                }
                break;

            case 3:
                strcpy( szPID, "Windows");
                switch ( charmap->encoding_id ) {
                    case 0:  strcpy( szEID, "symbols");           break;
                    case 1:  strcpy( szEID, "Unicode");           break;
                    case 2:  strcpy( szEID, "Shift-JIS (Japan)"); break;
                    case 3:  strcpy( szEID, "GB2312 (China)");    break;
                    case 4:  strcpy( szEID, "Big5 (Taiwan)");     break;
                    case 5:  strcpy( szEID, "Wansung (Korea)");   break;
                    case 6:  strcpy( szEID, "Johab (Korea)");     break;
                    case 10: strcpy( szEID, "UCS-4");             break;
                    default: strcpy( szEID, "unknown");           break;
                }
                break;

            default:
                strcpy( szPID, "unknown");
                strcpy( szEID, "unknown");
                break;
        }
        printf("Platform: %d (%s), Encoding: %d (%s)\n", charmap->platform_id, szPID,
                                                         charmap->encoding_id, szEID );
    }
#if 0
    error = FX_Flush_Stream( face );
    if ( error ) {
        printf("Failed to close stream: 0x%X\n", error );
        FT_Done_Face( face );
        goto done;
    }
    error = FX_Activate_Stream( face );
    if ( error ) {
        printf("Failed to reopen stream: 0x%X\n", error );
        FT_Done_Face( face );
        goto done;
    }
#endif

    if ( bShowKST ) {
        printf("\nKERNING INFORMATION");
        printf("\n-------------------\n");
        error = FX_Get_Kerning_Pairs( face, &kstable );
        switch ( error ) {
            case 0:
                printf("%u kerning pairs defined:\n", kstable->nPairs );
                if ( kstable->nPairs )
                {
                    for ( i = 0; i < kstable->nPairs; i++ ) {
                        printf("   %X / %X (%d)\n",
                               kstable->pairs[i].left,
                               kstable->pairs[i].right,
                               kstable->pairs[i].value );
                    }
                }
                safe_free( kstable );
                break;
            case FT_Err_Table_Missing:
                printf("No kerning table defined.\n");
                break;
            case FX_Err_Invalid_Kerning_Table:
                printf("The kerning table is invalid.\n");
                break;
            case FT_Err_Out_Of_Memory:
                printf("Memory allocation error.\n");
                break;
            case FX_Err_Invalid_Kerning_Table_Format:
                printf("No supported kerning table format found.\n");
                break;
            default: printf("An unknown error (0x%X) was encountered.\n", error );
                     break;
        }
    }

    if ( bShowOS2 ) {
        printf("\nOS/2 TABLE");
        printf("\n----------\n");

        pOS2 = (TT_OS2 *) FT_Get_Sfnt_Table( face, ft_sfnt_os2 );
        if ( pOS2 ) {
            printf("version:             %u\n", pOS2->version );
            printf("xAvgCharWidth:       %d\n", pOS2->xAvgCharWidth );
            printf("usWeightClass:       %u\n", pOS2->usWeightClass );
            printf("usWidthClass:        %u\n", pOS2->usWidthClass );
            printf("fsType:              0x%X\n", pOS2->fsType );
            printf("ySubscriptXSize:     %d\n", pOS2->ySubscriptXSize );
            printf("ySubscriptYSize:     %d\n", pOS2->ySubscriptYSize );
            printf("ySubscriptXOffset:   %d\n", pOS2->ySubscriptXOffset );
            printf("ySubscriptYOffset:   %d\n", pOS2->ySubscriptYOffset );
            printf("ySuperscriptXSize:   %d\n", pOS2->ySuperscriptXSize );
            printf("ySuperscriptYSize:   %d\n", pOS2->ySuperscriptYSize );
            printf("ySuperscriptXOffset: %d\n", pOS2->ySuperscriptXOffset );
            printf("ySuperscriptYOffset: %d\n", pOS2->ySuperscriptYOffset );
            printf("yStrikeoutSize:      %d\n", pOS2->yStrikeoutSize );
            printf("yStrikeoutPosition:  %d\n", pOS2->yStrikeoutPosition );
            printf("sFamilyClass:        %d\n", pOS2->sFamilyClass );
            printf("panose:              []\n");
            printf("ulUnicodeRange1:     0x%X\n", pOS2->ulUnicodeRange1 );
            printf("ulUnicodeRange2:     0x%X\n", pOS2->ulUnicodeRange2 );
            printf("ulUnicodeRange3:     0x%X\n", pOS2->ulUnicodeRange3 );
            printf("ulUnicodeRange4:     0x%X\n", pOS2->ulUnicodeRange4 );
            printf("achVendID:           %c%c%c%c\n", pOS2->achVendID[0], pOS2->achVendID[1], pOS2->achVendID[2], pOS2->achVendID[3] );
            printf("fsSelection:         0x%X\n", pOS2->fsSelection );
            printf("usFirstCharIndex:    %u\n", pOS2->usFirstCharIndex );
            printf("usLastCharIndex:     %u\n", pOS2->usLastCharIndex );
            printf("sTypoAscender:       %d\n", pOS2->sTypoAscender );
            printf("sTypoDescender:      %d\n", pOS2->sTypoDescender );
            printf("sTypoLineGap:        %d\n", pOS2->sTypoLineGap );
            printf("usWinAscent:         %u\n", pOS2->usWinAscent );
            printf("usWinDescent:        %u\n", pOS2->usWinDescent );
        }
        else printf("OS/2 table could not be located.\n");
    }

    if ( bShowPS) {
        printf("\nPOST TABLE");
        printf("\n----------\n");

        ppost = (TT_Postscript *) FT_Get_Sfnt_Table( face, ft_sfnt_post );
        if ( ppost ) {
            printf("FormatType:         0x%X\n", ppost->FormatType );
            printf("italicAngle:        %d\n", ppost->italicAngle );
            printf("underlinePosition:  %d\n", ppost->underlinePosition );
            printf("underlineThickness: %d\n", ppost->underlineThickness );
            printf("isFixedPitch:       %u\n", ppost->isFixedPitch );
            printf("minMemType42:       %u\n", ppost->minMemType42 );
            printf("maxMemType42:       %u\n", ppost->maxMemType42 );
            printf("minMemType1:        %u\n", ppost->minMemType1 );
            printf("maxMemType1:        %u\n", ppost->maxMemType1 );
        }
        else printf("POST table could not be loaded.\n");
    }

    error = FT_Done_Face( face );
done:
    FT_Done_FreeType( library );
    if ( uconv ) UniFreeUconvObject( uconv );
    return (int) error;
}
Esempio n. 27
0
// ------------------------------------------------------- texture_font_new ---
texture_font_t *
texture_font_new( texture_atlas_t * atlas,
                  const char * filename,
                  const float size)
{
    assert( filename );
    assert( size );

    texture_font_t *self = (texture_font_t *) malloc( sizeof(texture_font_t) );
    if( self == NULL)
    {
        fprintf( stderr,
                 "line %d: No more memory for allocating data\n", __LINE__ );
        exit( EXIT_FAILURE );
    }
    self->glyphs = vector_new( sizeof(texture_glyph_t *) );
    self->atlas = atlas;
    self->height = 0;
    self->ascender = 0;
    self->descender = 0;
    self->filename = strdup( filename );
    self->size = size;
    self->outline_type = 0;
    self->outline_thickness = 0.0;
    self->hinting = 1;
    self->filtering = 1;
    // FT_LCD_FILTER_LIGHT   is (0x00, 0x55, 0x56, 0x55, 0x00)
    // FT_LCD_FILTER_DEFAULT is (0x10, 0x40, 0x70, 0x40, 0x10)
    self->lcd_weights[0] = 0x10;
    self->lcd_weights[1] = 0x40;
    self->lcd_weights[2] = 0x70;
    self->lcd_weights[3] = 0x40;
    self->lcd_weights[4] = 0x10;

    /* Get font metrics at high resolution */
    FT_Library library;
    FT_Face face;
    if( !texture_font_load_face( &library, self->filename, self->size*100, &face ) )
    {
        return self;
    }

    // 64 * 64 because of 26.6 encoding AND the transform matrix used
    // in texture_font_load_face (hres = 64)
    self->underline_position = face->underline_position / (float)(64.0f*64.0f) * self->size;
    self->underline_position = round( self->underline_position );
    if( self->underline_position > -2 )
    {
        self->underline_position = -2.0;
    }

    self->underline_thickness = face->underline_thickness / (float)(64.0f*64.0f) * self->size;
    self->underline_thickness = round( self->underline_thickness );
    if( self->underline_thickness < 1 )
    {
        self->underline_thickness = 1.0;
    }

    FT_Size_Metrics metrics = face->size->metrics; 
    self->ascender = (metrics.ascender >> 6) / 100.0;
    self->descender = (metrics.descender >> 6) / 100.0;
    self->height = (metrics.height >> 6) / 100.0;
    self->linegap = self->height - self->ascender + self->descender;
    FT_Done_Face( face );
    FT_Done_FreeType( library );

    /* -1 is a special glyph */
    texture_font_get_glyph( self, -1 );

    return self;
}
Esempio n. 28
0
void
font_release(struct font_context *ctx) {
    FT_Done_Face(ctx->font);
}
Esempio n. 29
0
// ------------------------------------------------- texture_font_load_face ---
int
texture_font_load_face( FT_Library * library,
                        const char * filename,
                        const float size,
                        FT_Face * face )
{
    assert( library );
    assert( filename );
    assert( size );

    size_t hres = 64;
    FT_Error error;
    FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
                         (int)((0.0)      * 0x10000L),
                         (int)((0.0)      * 0x10000L),
                         (int)((1.0)      * 0x10000L) };

    /* Initialize library */
    error = FT_Init_FreeType( library );
    if( error )
    {
        fprintf(stderr, "FT_Error (0x%02x) : %s\n",
                FT_Errors[error].code, FT_Errors[error].message);
        return 0;
    }

    /* Load face */
    error = FT_New_Face( *library, filename, 0, face );
    if( error )
    {
        fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                 __LINE__, FT_Errors[error].code, FT_Errors[error].message);
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Select charmap */
    error = FT_Select_Charmap( *face, FT_ENCODING_UNICODE );
    if( error )
    {
        fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                 __LINE__, FT_Errors[error].code, FT_Errors[error].message );
        FT_Done_Face( *face );
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Set char size */
    error = FT_Set_Char_Size( *face, (int)(size*64), 0, 72*hres, 72 );
    if( error )
    {
        fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                 __LINE__, FT_Errors[error].code, FT_Errors[error].message );
        FT_Done_Face( *face );
        FT_Done_FreeType( *library );
        return 0;
    }

    /* Set transform matrix */
    FT_Set_Transform( *face, &matrix, NULL );

    return 1;
}
Esempio n. 30
0
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 = (u32) 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_default) {
				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_default = 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;
}