Esempio n. 1
0
int agg2RenderGlyphsPath(imageObj *img, textPathObj *tp, colorObj *c, colorObj *oc, int ow) {
  mapserver::path_storage glyphs;
  mapserver::trans_affine trans;
  AGG2Renderer *r = AGG_RENDERER(img);
  r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
  for(int i=0; i<tp->numglyphs; i++) {
    glyphObj *gl  = tp->glyphs + i;
    trans.reset();
    trans.rotate(-gl->rot);
    trans.translate(gl->pnt.x, gl->pnt.y);
    outline_element *ol = msGetGlyphOutline(gl->face,gl->glyph);
    if(!ol) {
      return MS_FAILURE;
    }
    decompose_ft_outline(ol->outline,true,trans,glyphs);
  }
  mapserver::conv_curve<mapserver::path_storage> m_curves(glyphs);
  if (oc) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    mapserver::conv_contour<mapserver::conv_curve<mapserver::path_storage> > cc(m_curves);
    cc.width(ow + 1);
    r->m_rasterizer_aa.add_path(cc);
    r->m_renderer_scanline.color(aggColor(oc));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  if(c) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    r->m_rasterizer_aa.add_path(m_curves);
    r->m_renderer_scanline.color(aggColor(c));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  return MS_SUCCESS;
}
bool gfx_font_adapter::prepare_glyph(unsigned int code)
{
    if (m_impl->font) {
        m_impl->cur_glyph_index = FT_Get_Char_Index(m_impl->font, code);

        int error = FT_Load_Glyph(m_impl->font, m_impl->cur_glyph_index,
                                 m_impl->hinting ? FT_LOAD_DEFAULT : FT_LOAD_NO_HINTING);

        bool is_sys_bitmap = false;
        if (m_impl->font->glyph->format == FT_GLYPH_FORMAT_BITMAP)
            is_sys_bitmap = true;

        if (error == 0) {
            if (m_impl->antialias && !is_sys_bitmap) {
                if (m_impl->weight == 500) {
                    int strength = 1 << 5;
                    FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                } else if (m_impl->weight == 700) {
                    int strength = 1 << 6;
                    FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                } else if (m_impl->weight == 900) {
                    int strength = 1 << 7;
                    FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                }
                // outline text
                m_impl->cur_data_type = glyph_type_outline;
                m_impl->cur_font_path.remove_all();

                if (decompose_ft_outline(m_impl->font->glyph->outline,
                            m_impl->flip_y, m_impl->matrix, m_impl->cur_font_path))
                {
                    m_impl->cur_bound_rect = get_bounding_rect(m_impl->cur_font_path);
                    m_impl->cur_data_size = m_impl->cur_font_path.total_byte_size()+sizeof(unsigned int);//count data
                    m_impl->cur_advance_x = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.x));
                    m_impl->cur_advance_y = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.y));
                    m_impl->matrix.transform(&m_impl->cur_advance_x, &m_impl->cur_advance_y);
                    return true;
                }
            } else {
                m_impl->cur_data_type = glyph_type_mono;
                if (is_sys_bitmap || !FT_IS_SCALABLE(m_impl->font) || m_impl->matrix.is_identity()) {
                    gfx_scanline_bin sl;
                    error = FT_Render_Glyph(m_impl->font->glyph, FT_RENDER_MODE_MONO);
                    if (error == 0) {
                        decompose_ft_bitmap_mono(m_impl->font->glyph->bitmap,
                           m_impl->font->glyph->bitmap_left, m_impl->flip_y ? -m_impl->font->glyph->bitmap_top :
                           m_impl->font->glyph->bitmap_top, m_impl->flip_y, sl, m_impl->cur_font_scanlines_bin);

                        m_impl->cur_bound_rect = rect(m_impl->cur_font_scanlines_bin.min_x(),
                                m_impl->cur_font_scanlines_bin.min_y(),
                                m_impl->cur_font_scanlines_bin.max_x() + 1,
                                m_impl->cur_font_scanlines_bin.max_y() + 1);
                        m_impl->cur_data_size = m_impl->cur_font_scanlines_bin.byte_size();
                        m_impl->cur_advance_x = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.x));
                        m_impl->cur_advance_y = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.y));
                        return true;
                    }
                } else {
                    if (m_impl->weight == 500) {
                        int strength = 1 << 5;
                        FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                    } else if (m_impl->weight == 700) {
                        int strength = 1 << 6;
                        FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                    } else if (m_impl->weight == 900) {
                        int strength = 1 << 7;
                        FT_Outline_Embolden(&(m_impl->font->glyph->outline), strength);
                    }

                    m_impl->cur_font_path.remove_all();
                    if (decompose_ft_outline(m_impl->font->glyph->outline,
                                m_impl->flip_y, m_impl->matrix, m_impl->cur_font_path))
                    {
                        gfx_rasterizer_scanline_aa<> rasterizer;
                        picasso::conv_curve curves(m_impl->cur_font_path);
                        curves.approximation_scale(4.0);
                        rasterizer.add_path(curves);

                        gfx_scanline_bin sl;
                        m_impl->cur_font_scanlines_bin.prepare(); // Remove all
                        gfx_render_scanlines(rasterizer, sl, m_impl->cur_font_scanlines_bin);
                        m_impl->cur_bound_rect = rect(m_impl->cur_font_scanlines_bin.min_x(),
                                m_impl->cur_font_scanlines_bin.min_y(),
                                m_impl->cur_font_scanlines_bin.max_x() + 1,
                                m_impl->cur_font_scanlines_bin.max_y() + 1);
                        m_impl->cur_data_size = m_impl->cur_font_scanlines_bin.byte_size();
                        m_impl->cur_advance_x = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.x));
                        m_impl->cur_advance_y = FLT_TO_SCALAR(int26p6_to_flt(m_impl->font->glyph->advance.y));
                        m_impl->matrix.transform(&m_impl->cur_advance_x, &m_impl->cur_advance_y);
                        return true;
                    }
                }
            }
        }
    }
    return false;
}
Esempio n. 3
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;
    }
Esempio n. 4
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;
    }