示例#1
0
    //------------------------------------------------------------------------
    bool font_engine_freetype_base::prepare_glyph(unsigned glyph_code)
    {
        m_glyph_index = FT_Get_Char_Index(m_cur_face, glyph_code);
        m_last_error = FT_Load_Glyph(m_cur_face, 
                                     m_glyph_index, 
                                     m_hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING);
//                                     m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING);
        if(m_last_error == 0)
        {
            switch(m_glyph_rendering)
            {
            case glyph_ren_native_mono:
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO);
                if(m_last_error == 0)
                {
                    decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, 
                                             m_cur_face->glyph->bitmap_left,
                                             m_flip_y ? -m_cur_face->glyph->bitmap_top : 
                                                         m_cur_face->glyph->bitmap_top,
                                             m_flip_y,
                                             m_scanline_bin,
                                             m_scanlines_bin);
                    m_bounds.x1 = m_scanlines_bin.min_x();
                    m_bounds.y1 = m_scanlines_bin.min_y();
                    m_bounds.x2 = m_scanlines_bin.max_x();
                    m_bounds.y2 = m_scanlines_bin.max_y();
                    m_data_size = m_scanlines_bin.byte_size(); 
                    m_data_type = glyph_data_mono;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    return true;
                }
                break;


            case glyph_ren_native_gray8:
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL);
                if(m_last_error == 0)
                {
                    decompose_ft_bitmap_gray8(m_cur_face->glyph->bitmap, 
                                              m_cur_face->glyph->bitmap_left,
                                              m_flip_y ? -m_cur_face->glyph->bitmap_top : 
                                                          m_cur_face->glyph->bitmap_top,
                                              m_flip_y,
                                              m_rasterizer,
                                              m_scanline_aa,
                                              m_scanlines_aa);
                    m_bounds.x1 = m_scanlines_aa.min_x();
                    m_bounds.y1 = m_scanlines_aa.min_y();
                    m_bounds.x2 = m_scanlines_aa.max_x();
                    m_bounds.y2 = m_scanlines_aa.max_y();
                    m_data_size = m_scanlines_aa.byte_size(); 
                    m_data_type = glyph_data_gray8;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    return true;
                }
                break;


            case glyph_ren_outline:
                if(m_last_error == 0)
                {
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        if(decompose_ft_outline(m_cur_face->glyph->outline,
                                                m_flip_y, 
                                                m_affine,
                                                m_path32))
                        {
                            rect_d bnd  = m_path32.bounding_rect();
                            m_data_size = m_path32.byte_size();
                            m_data_type = glyph_data_outline;
                            m_bounds.x1 = int(floor(bnd.x1));
                            m_bounds.y1 = int(floor(bnd.y1));
                            m_bounds.x2 = int(ceil(bnd.x2));
                            m_bounds.y2 = int(ceil(bnd.y2));
                            m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                            m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                            m_affine.transform(&m_advance_x, &m_advance_y);
                            return true;
                        }
                    }
                    else
                    {
                        m_path16.remove_all();
                        if(decompose_ft_outline(m_cur_face->glyph->outline,
                                                m_flip_y, 
                                                m_affine,
                                                m_path16))
                        {
                            rect_d bnd  = m_path16.bounding_rect();
                            m_data_size = m_path16.byte_size();
                            m_data_type = glyph_data_outline;
                            m_bounds.x1 = int(floor(bnd.x1));
                            m_bounds.y1 = int(floor(bnd.y1));
                            m_bounds.x2 = int(ceil(bnd.x2));
                            m_bounds.y2 = int(ceil(bnd.y2));
                            m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                            m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                            m_affine.transform(&m_advance_x, &m_advance_y);
                            return true;
                        }
                    }
                }
                return false;

            case glyph_ren_agg_mono:
                if(m_last_error == 0)
                {
                    m_rasterizer.reset();
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path32);
                        m_rasterizer.add_path(m_curves32);
                    }
                    else
                    {
                        m_path16.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path16);
                        m_rasterizer.add_path(m_curves16);
                    }
                    m_scanlines_bin.prepare(1); // Remove all 
                    render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin);
                    m_bounds.x1 = m_scanlines_bin.min_x();
                    m_bounds.y1 = m_scanlines_bin.min_y();
                    m_bounds.x2 = m_scanlines_bin.max_x();
                    m_bounds.y2 = m_scanlines_bin.max_y();
                    m_data_size = m_scanlines_bin.byte_size(); 
                    m_data_type = glyph_data_mono;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    m_affine.transform(&m_advance_x, &m_advance_y);
                    return true;
                }
                return false;


            case glyph_ren_agg_gray8:
                if(m_last_error == 0)
                {
                    m_rasterizer.reset();
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path32);
                        m_rasterizer.add_path(m_curves32);
                    }
                    else
                    {
                        m_path16.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path16);
                        m_rasterizer.add_path(m_curves16);
                    }
                    m_scanlines_aa.prepare(1); // Remove all 
                    render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa);
                    m_bounds.x1 = m_scanlines_aa.min_x();
                    m_bounds.y1 = m_scanlines_aa.min_y();
                    m_bounds.x2 = m_scanlines_aa.max_x();
                    m_bounds.y2 = m_scanlines_aa.max_y();
                    m_data_size = m_scanlines_aa.byte_size(); 
                    m_data_type = glyph_data_gray8;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    m_affine.transform(&m_advance_x, &m_advance_y);
                    return true;
                }
                return false;
            }
        }
        return false;
    }
示例#2
0
    //------------------------------------------------------------------------
    bool font_engine_freetype_base::prepare_glyph(unsigned glyph_code)
    {
        /* FT_ENCODING_MS_SYMBOL hack inspired from GD's gdft.c:  */
        /* I do not know the significance of the constant 0xf000. */
        /* It was determined by inspection of the character codes */
        /* stored in Microsoft font symbol.ttf                    */
        if (m_cur_face->charmap &&
            m_cur_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
            glyph_code |= 0xf000;

        m_glyph_index = FT_Get_Char_Index(m_cur_face, glyph_code);
        m_last_error = FT_Load_Glyph(m_cur_face, 
                                     m_glyph_index, 
                                     m_hinting ? FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP : FT_LOAD_NO_HINTING|FT_LOAD_NO_BITMAP);
//                                     m_hinting ? FT_LOAD_FORCE_AUTOHINT : FT_LOAD_NO_HINTING);
        if(m_last_error == 0)
        {
            switch(m_glyph_rendering)
            {
            case glyph_ren_native_mono:
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_MONO);
                if(m_last_error == 0)
                {
                    decompose_ft_bitmap_mono(m_cur_face->glyph->bitmap, 
                                             m_cur_face->glyph->bitmap_left,
                                             m_flip_y ? -m_cur_face->glyph->bitmap_top : 
                                                         m_cur_face->glyph->bitmap_top,
                                             m_flip_y,
                                             m_scanline_bin,
                                             m_scanlines_bin);
                    m_bounds.x1 = m_scanlines_bin.min_x();
                    m_bounds.y1 = m_scanlines_bin.min_y();
                    m_bounds.x2 = m_scanlines_bin.max_x() + 1;
                    m_bounds.y2 = m_scanlines_bin.max_y() + 1;
                    m_data_size = m_scanlines_bin.byte_size(); 
                    m_data_type = glyph_data_mono;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    return true;
                }
                break;


            case glyph_ren_native_gray8:
                m_last_error = FT_Render_Glyph(m_cur_face->glyph, FT_RENDER_MODE_NORMAL);
                if(m_last_error == 0)
                {
                    decompose_ft_bitmap_gray8(m_cur_face->glyph->bitmap, 
                                              m_cur_face->glyph->bitmap_left,
                                              m_flip_y ? -m_cur_face->glyph->bitmap_top : 
                                                          m_cur_face->glyph->bitmap_top,
                                              m_flip_y,
                                              m_rasterizer,
                                              m_scanline_aa,
                                              m_scanlines_aa);
                    m_bounds.x1 = m_scanlines_aa.min_x();
                    m_bounds.y1 = m_scanlines_aa.min_y();
                    m_bounds.x2 = m_scanlines_aa.max_x() + 1;
                    m_bounds.y2 = m_scanlines_aa.max_y() + 1;
                    m_data_size = m_scanlines_aa.byte_size(); 
                    m_data_type = glyph_data_gray8;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    return true;
                }
                break;


            case glyph_ren_outline:
                if(m_last_error == 0)
                {
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        if(decompose_ft_outline(m_cur_face->glyph->outline,
                                                m_flip_y, 
                                                m_affine,
                                                m_path32))
                        {
                            rect_d bnd  = m_path32.bounding_rect();
                            m_data_size = m_path32.byte_size();
                            m_data_type = glyph_data_outline;
                            m_bounds.x1 = int(floor(bnd.x1));
                            m_bounds.y1 = int(floor(bnd.y1));
                            m_bounds.x2 = int(ceil(bnd.x2));
                            m_bounds.y2 = int(ceil(bnd.y2));
                            m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                            m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                            m_affine.transform(&m_advance_x, &m_advance_y);
                            return true;
                        }
                    }
                    else
                    {
                        m_path16.remove_all();
                        if(decompose_ft_outline(m_cur_face->glyph->outline,
                                                m_flip_y, 
                                                m_affine,
                                                m_path16))
                        {
                            rect_d bnd  = m_path16.bounding_rect();
                            m_data_size = m_path16.byte_size();
                            m_data_type = glyph_data_outline;
                            m_bounds.x1 = int(floor(bnd.x1));
                            m_bounds.y1 = int(floor(bnd.y1));
                            m_bounds.x2 = int(ceil(bnd.x2));
                            m_bounds.y2 = int(ceil(bnd.y2));
                            m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                            m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                            m_affine.transform(&m_advance_x, &m_advance_y);
                            return true;
                        }
                    }
                }
                return false;

            case glyph_ren_agg_mono:
                if(m_last_error == 0)
                {
                    m_rasterizer.reset();
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path32);
                        m_rasterizer.add_path(m_curves32);
                    }
                    else
                    {
                        m_path16.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path16);
                        m_rasterizer.add_path(m_curves16);
                    }
                    m_scanlines_bin.prepare(); // Remove all 
                    render_scanlines(m_rasterizer, m_scanline_bin, m_scanlines_bin);
                    m_bounds.x1 = m_scanlines_bin.min_x();
                    m_bounds.y1 = m_scanlines_bin.min_y();
                    m_bounds.x2 = m_scanlines_bin.max_x() + 1;
                    m_bounds.y2 = m_scanlines_bin.max_y() + 1;
                    m_data_size = m_scanlines_bin.byte_size(); 
                    m_data_type = glyph_data_mono;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    m_affine.transform(&m_advance_x, &m_advance_y);
                    return true;
                }
                return false;


            case glyph_ren_agg_gray8:
                if(m_last_error == 0)
                {
                    m_rasterizer.reset();
                    if(m_flag32)
                    {
                        m_path32.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path32);
                        m_rasterizer.add_path(m_curves32);
                    }
                    else
                    {
                        m_path16.remove_all();
                        decompose_ft_outline(m_cur_face->glyph->outline,
                                             m_flip_y, 
                                             m_affine,
                                             m_path16);
                        m_rasterizer.add_path(m_curves16);
                    }
                    m_scanlines_aa.prepare(); // Remove all 
                    render_scanlines(m_rasterizer, m_scanline_aa, m_scanlines_aa);
                    m_bounds.x1 = m_scanlines_aa.min_x();
                    m_bounds.y1 = m_scanlines_aa.min_y();
                    m_bounds.x2 = m_scanlines_aa.max_x() + 1;
                    m_bounds.y2 = m_scanlines_aa.max_y() + 1;
                    m_data_size = m_scanlines_aa.byte_size(); 
                    m_data_type = glyph_data_gray8;
                    m_advance_x = int26p6_to_dbl(m_cur_face->glyph->advance.x);
                    m_advance_y = int26p6_to_dbl(m_cur_face->glyph->advance.y);
                    m_affine.transform(&m_advance_x, &m_advance_y);
                    return true;
                }
                return false;
            }
        }
        return false;
    }