コード例 #1
0
ファイル: font.cpp プロジェクト: Anubisko/enigma2
inline FT_Error fontRenderClass::getGlyphImage(FTC_Image_Desc *font, FT_ULong glyph_index, FT_Glyph *glyph, FT_Glyph *borderglyph, int bordersize)
#endif
{
	FT_Glyph image;
	FT_Error err = FTC_ImageCache_Lookup(imageCache, font, glyph_index, &image, NULL);
	if (err) return err;

	if (glyph)
	{
		err = FT_Glyph_Copy(image, glyph);
		if (err) return err;
	}

	if (borderglyph && bordersize)
	{
		err = FT_Glyph_Copy(image, borderglyph);
		if (err) return err;
		if (bordersize != strokerRadius)
		{
			strokerRadius = bordersize;
			FT_Stroker_Set(stroker, strokerRadius, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
		}
		err = FT_Glyph_Stroke(borderglyph, stroker, 1);
	}
	return err;
}
コード例 #2
0
void text_renderer<T>::render_id(int feature_id, pixel_position pos, double min_radius)
{
    FT_Error  error;
    FT_Vector start;
    unsigned height = pixmap_.height();

    start.x =  static_cast<FT_Pos>(pos.x * (1 << 6));
    start.y =  static_cast<FT_Pos>((height - pos.y) * (1 << 6));

    // now render transformed glyphs
    typename glyphs_t::iterator itr;
    for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr)
    {
        stroker_.init(std::max(itr->properties->halo_radius, min_radius));
        FT_Glyph g;
        error = FT_Glyph_Copy(itr->image, &g);
        if (!error)
        {
            FT_Glyph_Transform(g,0,&start);
            FT_Glyph_Stroke(&g,stroker_.get(),1);
            error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1);
            //error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_MONO,0,1);
            if ( ! error )
            {

                FT_BitmapGlyph bit = (FT_BitmapGlyph)g;
                render_bitmap_id(&bit->bitmap, feature_id,
                                 bit->left,
                                 height - bit->top);
            }
        }
        FT_Done_Glyph(g);
    }
}
コード例 #3
0
void text_renderer<T>::render(pixel_position pos)
{
    FT_Error  error;
    FT_Vector start;
    unsigned height = pixmap_.height();

    start.x =  static_cast<FT_Pos>(pos.x * (1 << 6));
    start.y =  static_cast<FT_Pos>((height - pos.y) * (1 << 6));

    // now render transformed glyphs
    typename glyphs_t::iterator itr;
    for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr)
    {
        double halo_radius = itr->properties->halo_radius;
        //make sure we've got reasonable values.
        if (halo_radius <= 0.0 || halo_radius > 1024.0) continue;
        stroker_.init(halo_radius);
        FT_Glyph g;
        error = FT_Glyph_Copy(itr->image, &g);
        if (!error)
        {
            FT_Glyph_Transform(g,0,&start);
            FT_Glyph_Stroke(&g,stroker_.get(),1);
            error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1);
            if ( ! error )
            {

                FT_BitmapGlyph bit = (FT_BitmapGlyph)g;
                render_bitmap(&bit->bitmap, itr->properties->halo_fill.rgba(),
                              bit->left,
                              height - bit->top, itr->properties->text_opacity);
            }
        }
        FT_Done_Glyph(g);
    }
    //render actual text
    for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr)
    {

        FT_Glyph_Transform(itr->image,0,&start);

        error = FT_Glyph_To_Bitmap( &(itr->image),FT_RENDER_MODE_NORMAL,0,1);
        if ( ! error )
        {

            FT_BitmapGlyph bit = (FT_BitmapGlyph)itr->image;
            render_bitmap(&bit->bitmap, itr->properties->fill.rgba(),
                          bit->left,
                          height - bit->top, itr->properties->text_opacity);
        }
    }
}
コード例 #4
0
ファイル: FreeType.cpp プロジェクト: ukinau/Chisa
std::vector<Handler<BitmapGlyph> > FreeType::lookupBitmap(Font& font, float size, std::vector<unsigned int> const& ucs4, float& ascent, float& descent, float& height)
{
	Font::RawFaceSession rfs(font);
	FT_Face face = rfs.face();
	FT_Face face__;
	FTC_ScalerRec scaler;
	{
		scaler.face_id = face;
		scaler.width = 0;
		scaler.height = FLOAT_TO_26_6( size );
		scaler.pixel = 0;
		scaler.x_res=72; //XXX
		scaler.y_res=72; //XXX
	}

	FTC_Manager_LookupFace(this->cache_, face, &face__);
	{
		FT_Size size;
		FTC_Manager_LookupSize(this->cache_, &scaler, &size);
		ascent = FLOAT_FROM_26_6(size->metrics.ascender);
		descent = FLOAT_FROM_26_6(size->metrics.descender);
		height = FLOAT_FROM_26_6(size->metrics.height);
	}
	std::vector<Handler<BitmapGlyph> > ret;
	ret.reserve(ucs4.size());
	for(unsigned int const& u : ucs4) {
		unsigned int const gindex = FTC_CMapCache_Lookup(this->cmap_, face, font.unicodeCharmapIndex(), u);
		FT_Glyph glyph;
		{
			FT_Glyph glyph_orig;
			FTC_ImageCache_LookupScaler(this->image_, &scaler, 0, gindex, &glyph_orig, nullptr);
			FT_Glyph_Copy(glyph_orig, &glyph);
		}
		if(glyph->format != FT_GLYPH_FORMAT_BITMAP ) {
			FT_Vector_ vec;
			vec.x = 0;
			vec.y = 0;
			FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, &vec, 1);
		}
		ret.push_back( Handler<BitmapGlyph>(new BitmapGlyph(reinterpret_cast<FT_BitmapGlyph>(glyph))) );
	}
	return ret;
}
コード例 #5
0
ファイル: renderer.cpp プロジェクト: oviano/gdi2ft
const bool GDI2FT_RENDERER::generate_outline_glyph( FT_Glyph* glyph, WORD glyph_index, const FTC_Scaler scaler, FT_F26Dot6 embolden, bool is_italic ) const
/* --------------------------------------------------------------------------------
-------------------------------------------------------------------------------- */
{
	FT_Glyph cached_glyph;

	{
		GDI2FT_MUTEX mutex( GDI2FT_MUTEX::MUTEX_FREETYPE );

		if( FTC_ImageCache_LookupScaler( ft_glyph_cache, scaler, FT_LOAD_NO_BITMAP | FT_LOAD_FORCE_AUTOHINT | FT_LOAD_CROP_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH | FT_LOAD_TARGET_LIGHT, glyph_index, &cached_glyph, NULL ) != 0 )
			return NULL;
	}

	if( cached_glyph->format != FT_GLYPH_FORMAT_OUTLINE )
		return NULL;

	const bool oblique = ( ( context->outline_metrics->otmTextMetrics.tmItalic != 0 ) && !is_italic );

	if( oblique || embolden )
	{
		FT_Glyph_Copy( cached_glyph, glyph );
		FT_Outline* glyph_outline = &( reinterpret_cast<FT_OutlineGlyph>( *glyph )->outline );

		if( oblique )
		{
			FT_Matrix oblique_mat = { static_cast<FT_Pos>( 65536 ), static_cast<FT_Pos>( 19661 ), 0, static_cast<FT_Pos>( 65536 ) };
			FT_Outline_Transform( glyph_outline, &oblique_mat );
		}

		if( embolden )
			FT_Outline_Embolden( glyph_outline, embolden );

		return true;
	}
	else
		*glyph = cached_glyph;

	return false;
}
コード例 #6
0
ファイル: ft.cpp プロジェクト: nixz/covise
void FT::drawString(ft_pixmap *pixmap, ft_string *string)
{
    FT_Vector where;
    ft_char *glyph;
    int n, error;

    where.x = -string->bbox.xMin + 1;
    where.y = string->bbox.yMax;
    glyph = string->glyphs;

    for (n = 0; n < string->num_glyphs; ++n, ++glyph)
    {
        FT_Glyph image;
        FT_Vector vec; /* 26.6 */
        FT_BitmapGlyph bit;

        // make copy to transform
        if (!glyph->image)
        {
            fprintf(stderr, "no image\n");
            continue;
        }
        error = FT_Glyph_Copy(glyph->image, &image);
        if (error)
        {
            fprintf(stderr, "couldn't copy image\n");
            continue;
        }

        /* transform it */
        vec = glyph->pos;
        FT_Vector_Transform(&vec, &string->transform);

        bit = (FT_BitmapGlyph)image;
        drawBitmap(pixmap, bit, where);
        FT_Done_Glyph(image);
    }
}
コード例 #7
0
ファイル: renderer.cpp プロジェクト: Airphrame/mapnik
void agg_text_renderer<T>::render(glyph_positions const& pos)
{
    glyphs_.clear();
    prepare_glyphs(pos);
    FT_Error  error;
    FT_Vector start;
    FT_Vector start_halo;
    int height = pixmap_.height();
    pixel_position const& base_point = pos.get_base_point();

    start.x =  static_cast<FT_Pos>(base_point.x * (1 << 6));
    start.y =  static_cast<FT_Pos>((height - base_point.y) * (1 << 6));
    start_halo = start;
    start.x += transform_.tx * 64;
    start.y += transform_.ty * 64;
    start_halo.x += halo_transform_.tx * 64;
    start_halo.y += halo_transform_.ty * 64;

    FT_Matrix halo_matrix;
    halo_matrix.xx = halo_transform_.sx  * 0x10000L;
    halo_matrix.xy = halo_transform_.shx * 0x10000L;
    halo_matrix.yy = halo_transform_.sy  * 0x10000L;
    halo_matrix.yx = halo_transform_.shy * 0x10000L;

    FT_Matrix matrix;
    matrix.xx = transform_.sx  * 0x10000L;
    matrix.xy = transform_.shx * 0x10000L;
    matrix.yy = transform_.sy  * 0x10000L;
    matrix.yx = transform_.shy * 0x10000L;

    // default formatting
    double halo_radius = 0;
    color black(0,0,0);
    unsigned fill = black.rgba();
    unsigned halo_fill = black.rgba();
    double text_opacity = 1.0;
    double halo_opacity = 1.0;

    for (auto const& glyph : glyphs_)
    {
        halo_fill = glyph.properties.halo_fill.rgba();
        halo_opacity = glyph.properties.halo_opacity;
        halo_radius = glyph.properties.halo_radius * scale_factor_;
        // make sure we've got reasonable values.
        if (halo_radius <= 0.0 || halo_radius > 1024.0) continue;
        FT_Glyph g;
        error = FT_Glyph_Copy(glyph.image, &g);
        if (!error)
        {
            FT_Glyph_Transform(g, &halo_matrix, &start_halo);
            if (rasterizer_ == HALO_RASTERIZER_FULL)
            {
                stroker_->init(halo_radius);
                FT_Glyph_Stroke(&g, stroker_->get(), 1);
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (!error)
                {
                    FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                    composite_bitmap(pixmap_,
                                     &bit->bitmap,
                                     halo_fill,
                                     bit->left,
                                     height - bit->top,
                                     halo_opacity,
                                     halo_comp_op_);
                }
            }
            else
            {
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (!error)
                {
                    FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                    render_halo(&bit->bitmap,
                                halo_fill,
                                bit->left,
                                height - bit->top,
                                halo_radius,
                                halo_opacity,
                                halo_comp_op_);
                }
            }
        }
        FT_Done_Glyph(g);
    }

    // render actual text
    for (auto & glyph : glyphs_)
    {
        fill = glyph.properties.fill.rgba();
        text_opacity = glyph.properties.text_opacity;
        FT_Glyph_Transform(glyph.image, &matrix, &start);
        error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1);
        if (!error)
        {
            FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image);
            composite_bitmap(pixmap_,
                             &bit->bitmap,
                             fill,
                             bit->left,
                             height - bit->top,
                             text_opacity,
                             comp_op_);
        }
        FT_Done_Glyph(glyph.image);
    }

}
コード例 #8
0
ファイル: font_freetype.c プロジェクト: Ever-Never/libaroma
/*
 * Function    : libaroma_font_glyph_draw
 * Return Value: byte
 * Descriptions: draw glyph into canvas
 */
byte libaroma_font_glyph_draw(
  LIBAROMA_CANVASP dest,
  LIBAROMA_GLYPH aglyph_param,
  int x,
  int y,
  word color,
  byte flags,
  byte opacity
) {
  _LIBAROMA_FONT_SLOT_CACHEP aglyph =
    (_LIBAROMA_FONT_SLOT_CACHEP) aglyph_param;
  if (!aglyph) {
    return 0;
  }
  if (aglyph->glyph==NULL) {
    return 0;
  }
  if (dest == NULL) {
    dest = libaroma_fb()->canvas;
  }
  /* thread safe lock */
  _libaroma_font_lock(1);
  
  /* copy & render */
  FT_Glyph fglyph=NULL;
  fglyph=NULL;
  int cnt=0;
  if (FT_Glyph_Copy(aglyph->glyph, &fglyph)!=0){
    _libaroma_font_lock(0);
    return 0;
  }
  if (cnt>0){
    printf("[FT] FC: %i %i\n",cnt,aglyph->codepoint);
  }
  /* italic transform */
  if (flags & _LIBAROMA_TEXTCHUNK_ITALIC) {
    FT_Matrix matrix;
    matrix.xx = 0x10000L;
    matrix.xy = 0x5000L;
    matrix.yx = 0;
    matrix.yy = 0x10000L;
    FT_Glyph_Transform(fglyph, &matrix, NULL);
  }
  
  /* embolden */
  if (flags & _LIBAROMA_TEXTCHUNK_BOLD) {
    FT_Outline_Embolden(
      &((FT_OutlineGlyph) fglyph)->outline,
      aglyph->size * 2
    );
  }
  
  /* convert glyph to bitmap glyph */
  if (FT_Glyph_To_Bitmap(&fglyph, _LIBAROMA_FONT_RENDER_FLAG, 0, 1)!=0){
    /* release glyph */
    printf("[FT] FR:%i\n",aglyph->codepoint);
    FT_Done_Glyph(fglyph);
    _libaroma_font_lock(0);
    return 0;
  }
    
  /* as bitmap glyph */
  FT_BitmapGlyph bit = (FT_BitmapGlyph) fglyph;
  
  /* prepare locations */
  /*int yy;*/
  typeof(bit->bitmap.rows) yy;
  int xpos = x + bit->left;
  int xstart = 0;
  
  if (xpos < 0) {
    xstart = 0 - xpos;
    xpos = 0;
  }
  
  /* loop */
#ifndef LIBAROMA_CONFIG_NOFONT_SUBPIXEL
  int draw_w  = (bit->bitmap.width / 3) - xstart;
  if (draw_w + xpos > dest->w) {
    draw_w = dest->w - xpos;
  }
  if (draw_w > 0) {
    wordp tmp_dst = NULL;
    if (opacity != 0xff) {
      tmp_dst = (wordp) malloc(draw_w * 2);
    }
    for (yy = 0; yy < bit->bitmap.rows; yy++) {
      /* drawing positions */
      int yglp = (yy - bit->top);
      int ypos = (y + yglp) * dest->l;
      
      /* check position */
      if ((ypos+draw_w>(dest->l*dest->h)) || (ypos<0)) {
        continue;
      }
      
      /* source * destination pointers */
      int ysrc = yy * bit->bitmap.pitch;
      bytep src_line  = bit->bitmap.buffer + ysrc + (xstart * 3);
      wordp dest_line = dest->data + ypos + xpos;
      
      /* draw line */
      if (opacity == 0xff) {
        libaroma_alpha_multi_line(
          draw_w, dest_line, dest_line, color, src_line);
      }
      else {
        libaroma_alpha_multi_line(
          draw_w, tmp_dst, dest_line, color, src_line);
        libaroma_alpha_const(
          draw_w, dest_line, dest_line, tmp_dst, opacity);
      }
    }
    if (tmp_dst) {
      free(tmp_dst);
    }
  }
#else
  int draw_w  = bit->bitmap.width - xstart;
  if (draw_w + xpos > dest->w) {
    draw_w = dest->w - xpos;
  }
  if (draw_w > 0) {
    wordp tmp_dst = NULL;
    if (opacity != 0xff) {
      tmp_dst = (wordp) malloc(draw_w * 2);
    }
    /* line */
    for (yy = 0; yy < bit->bitmap.rows; yy++) {
      /* drawing positions */
      int yglp = (yy - bit->top);
      int ypos = (y + yglp) * dest->l;
      /* check position */
      if ((ypos+draw_w>(dest->l*dest->h)) || (ypos<0)) {
        continue;
      }
      /* source & destination pointers */
      int ysrc = yy * bit->bitmap.pitch;
      bytep src_line  = bit->bitmap.buffer + ysrc + xstart;
      wordp dest_line = dest->data + ypos + xpos;
      /* draw line */
      if (opacity == 0xff) {
        libaroma_alpha_mono(
          draw_w, dest_line, dest_line, color, src_line);
      }
      else {
        libaroma_alpha_mono(
          draw_w, tmp_dst, dest_line, color, src_line);
        libaroma_alpha_const(
          draw_w, dest_line, dest_line, tmp_dst, opacity);
      }
    }
    if (tmp_dst) {
      free(tmp_dst);
    }
  }
  
#endif
  /* release glyph */
  FT_Done_Glyph(fglyph);
  _libaroma_font_lock(0);
  return 1;
} /* End of libaroma_font_glyph_draw */
コード例 #9
0
ファイル: renderer.cpp プロジェクト: FlavioFalcao/mapnik
void agg_text_renderer<T>::render(glyph_positions const& pos)
{
    glyphs_.clear();
    prepare_glyphs(pos);
    FT_Error  error;
    FT_Vector start;
    int height = pixmap_.height();
    pixel_position const& base_point = pos.get_base_point();

    start.x =  static_cast<FT_Pos>(base_point.x * (1 << 6));
    start.y =  static_cast<FT_Pos>((height - base_point.y) * (1 << 6));

    //render halo
    double halo_radius = 0;
    char_properties_ptr format;
    for (auto const& glyph : glyphs_)
    {
        if (glyph.properties)
        {
            format = glyph.properties;
            // Settings have changed.
            halo_radius = glyph.properties->halo_radius * scale_factor_;
        }
        // make sure we've got reasonable values.
        if (halo_radius <= 0.0 || halo_radius > 1024.0) continue;
        FT_Glyph g;
        error = FT_Glyph_Copy(glyph.image, &g);
        if (!error)
        {
            FT_Glyph_Transform(g,0,&start);
            if (rasterizer_ == HALO_RASTERIZER_FULL)
            {
                stroker_->init(halo_radius);
                FT_Glyph_Stroke(&g, stroker_->get(), 1);
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (!error)
                {
                    FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                    composite_bitmap(pixmap_,
                                     &bit->bitmap,
                                     format->halo_fill.rgba(),
                                     bit->left,
                                     height - bit->top,
                                     format->text_opacity,
                                     comp_op_);
                }
            }
            else
            {
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (!error)
                {
                    FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                    render_halo(&bit->bitmap,
                                format->halo_fill.rgba(),
                                bit->left,
                                height - bit->top,
                                halo_radius,
                                format->text_opacity,
                                comp_op_);
                }
            }
        }
        FT_Done_Glyph(g);
    }

    // render actual text
    for (auto & glyph : glyphs_)
    {
        if (glyph.properties)
        {
            format = glyph.properties;
        }
        FT_Glyph_Transform(glyph.image, 0, &start);
        error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL,0,1);
        if (!error)
        {
            FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image);
            composite_bitmap(pixmap_,
                             &bit->bitmap,
                             format->fill.rgba(),
                             bit->left,
                             height - bit->top,
                             format->text_opacity,
                             comp_op_);
        }
    }
}
コード例 #10
0
static void _alfont_cache_glyph(ALFONT_FONT *f, int glyph_number) {
  /* if glyph not cached yet */
  if (!f->cached_glyphs[glyph_number].is_cached) {
    FT_Glyph new_glyph;
    /* load the font glyph */
    FT_Load_Glyph(f->face, glyph_number, FT_LOAD_DEFAULT);
    FT_Get_Glyph(f->face->glyph, &new_glyph);

    /* ok, this glyph is now cached */
    f->cached_glyphs[glyph_number].is_cached = 1;
    f->cached_glyphs[glyph_number].mono_available = 0;
    f->cached_glyphs[glyph_number].aa_available = 0;

    /* render the mono bmp */
    {
      FT_Bitmap *ft_bmp;
      FT_Glyph glyph;
      FT_BitmapGlyph bmp_glyph;

      FT_Glyph_Copy(new_glyph, &glyph);

      /* only render glyph if it is not already a bitmap */
      if (glyph->format != ft_glyph_format_bitmap)
        FT_Glyph_To_Bitmap(&glyph, ft_render_mode_mono, NULL, 1);

      /* the FT rendered bitmap */
      bmp_glyph = (FT_BitmapGlyph)glyph;
      ft_bmp = &bmp_glyph->bitmap;

      /* save only if the bitmap is really 1 bit */
      if (ft_bmp->pixel_mode == ft_pixel_mode_mono) {
        int memsize;

        f->cached_glyphs[glyph_number].mono_available = 1;

        /* set width, height, left, top */
        f->cached_glyphs[glyph_number].width = ft_bmp->width;
        f->cached_glyphs[glyph_number].height = ft_bmp->rows;
        f->cached_glyphs[glyph_number].left = bmp_glyph->left;
        f->cached_glyphs[glyph_number].top = bmp_glyph->top;

        /* allocate bitmap */
        memsize = ft_bmp->width * ft_bmp->rows * sizeof(unsigned char);
        if (memsize > 0)
          f->cached_glyphs[glyph_number].bmp = malloc(memsize);
        else
          f->cached_glyphs[glyph_number].bmp = NULL;

        /* monochrome drawing */
        if (memsize > 0) {
          unsigned char *outbmp_p = f->cached_glyphs[glyph_number].bmp;
          unsigned char *bmp_p;
          int bmp_x, bmp_y, bit;

          /* copy the FT character bitmap to ours */
          bmp_p = ft_bmp->buffer;
          for (bmp_y = 0; bmp_y < ft_bmp->rows; bmp_y++) {
            unsigned char *next_bmp_p;
            next_bmp_p = bmp_p + ft_bmp->pitch;
            bit = 7;
            for (bmp_x = 0; bmp_x < ft_bmp->width; bmp_x++) {
              *outbmp_p = *bmp_p & (1 << bit);
              outbmp_p++;

              if (bit == 0) {
                bit = 7;
                bmp_p++;
              }
              else
                bit--;
            }
            bmp_p = next_bmp_p;
          }
        }
      }

      FT_Done_Glyph(glyph);
    }


    /* render the aa bmp */
    {
      FT_Bitmap *ft_bmp;
      FT_Glyph glyph;
      FT_BitmapGlyph bmp_glyph;
    
      FT_Glyph_Copy(new_glyph, &glyph);

      /* only render glyph if it is not already a bitmap */
      if (glyph->format != ft_glyph_format_bitmap)
        FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, NULL, 1);

      /* the FT rendered bitmap */
      bmp_glyph = (FT_BitmapGlyph)glyph;
      ft_bmp = &bmp_glyph->bitmap;

      /* save only if the bitmap is really 8 bit */
      if (ft_bmp->pixel_mode == ft_pixel_mode_grays) {
        int memsize;

        f->cached_glyphs[glyph_number].aa_available = 1;

        /* set width, height, left, top */
        f->cached_glyphs[glyph_number].aawidth = ft_bmp->width;
        f->cached_glyphs[glyph_number].aaheight = ft_bmp->rows;
        f->cached_glyphs[glyph_number].aaleft = bmp_glyph->left;
        f->cached_glyphs[glyph_number].aatop = bmp_glyph->top;

        /* allocate bitmap */
        memsize = ft_bmp->width * ft_bmp->rows * sizeof(unsigned char);
        if (memsize > 0)
          f->cached_glyphs[glyph_number].aabmp = malloc(memsize);
        else
          f->cached_glyphs[glyph_number].aabmp = NULL;

        /* aa drawing */
        if (memsize > 0) {
          unsigned char *outbmp_p = f->cached_glyphs[glyph_number].aabmp;
          unsigned char *bmp_p;
          int bmp_y;
          unsigned char mul = 256 / ft_bmp->num_grays;
          /* we set it to 0 because it is faster to test for false */
          if (mul == 1)
            mul = 0;

          /* copy the FT character bitmap to ours */
          bmp_p = ft_bmp->buffer;
          for (bmp_y = 0; bmp_y < ft_bmp->rows; bmp_y++) {
            unsigned char *next_bmp_p;
            next_bmp_p = bmp_p + ft_bmp->pitch;
            memcpy(outbmp_p, bmp_p, ft_bmp->width * sizeof(unsigned char));

            /* we have to change our pixels if the numgrays is not 256 */
            if (mul) {
              unsigned char *p = outbmp_p;
              unsigned char *p_end = p + ft_bmp->width;
              for (; p < p_end; p++)
                *p *= mul;
            }

            outbmp_p += ft_bmp->width;
            bmp_p = next_bmp_p;
          }
        }
      }

      FT_Done_Glyph(glyph);
    }

    f->cached_glyphs[glyph_number].advancex = f->face->glyph->advance.x >> 6;
    f->cached_glyphs[glyph_number].advancey = f->face->glyph->advance.y >> 6;

    /* delete the glyph */
    FT_Done_Glyph(new_glyph);
  }
コード例 #11
0
ファイル: renderer.cpp プロジェクト: CartoDB/mapnik
void agg_text_renderer<T>::render(glyph_positions const& pos)
{
    prepare_glyphs(pos);
    FT_Error  error;
    FT_Vector start;
    FT_Vector start_halo;
    int height = pixmap_.height();
    pixel_position const& base_point = pos.get_base_point();

    start.x =  static_cast<FT_Pos>(base_point.x * (1 << 6));
    start.y =  static_cast<FT_Pos>((height - base_point.y) * (1 << 6));
    start_halo = start;
    start.x += transform_.tx * 64;
    start.y += transform_.ty * 64;
    start_halo.x += halo_transform_.tx * 64;
    start_halo.y += halo_transform_.ty * 64;

    FT_Matrix halo_matrix;
    halo_matrix.xx = halo_transform_.sx  * 0x10000L;
    halo_matrix.xy = halo_transform_.shx * 0x10000L;
    halo_matrix.yy = halo_transform_.sy  * 0x10000L;
    halo_matrix.yx = halo_transform_.shy * 0x10000L;

    FT_Matrix matrix;
    matrix.xx = transform_.sx  * 0x10000L;
    matrix.xy = transform_.shx * 0x10000L;
    matrix.yy = transform_.sy  * 0x10000L;
    matrix.yx = transform_.shy * 0x10000L;

    // default formatting
    double halo_radius = 0;
    color black(0,0,0);
    unsigned fill = black.rgba();
    unsigned halo_fill = black.rgba();
    double text_opacity = 1.0;
    double halo_opacity = 1.0;

    for (auto const& glyph : glyphs_)
    {
        halo_fill = glyph.properties.halo_fill.rgba();
        halo_opacity = glyph.properties.halo_opacity;
        halo_radius = glyph.properties.halo_radius * scale_factor_;
        // make sure we've got reasonable values.
        if (halo_radius <= 0.0 || halo_radius > 1024.0) continue;
        FT_Glyph g;
        error = FT_Glyph_Copy(glyph.image, &g);
        if (!error)
        {
            FT_Glyph_Transform(g, &halo_matrix, &start_halo);
            if (rasterizer_ == HALO_RASTERIZER_FULL)
            {
                stroker_->init(halo_radius);
                FT_Glyph_Stroke(&g, stroker_->get(), 1);
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (!error)
                {
                    FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                    if (bit->bitmap.pixel_mode != FT_PIXEL_MODE_BGRA)
                    {
                        composite_bitmap(pixmap_,
                                         &bit->bitmap,
                                         halo_fill,
                                         bit->left,
                                         height - bit->top,
                                         halo_opacity,
                                         halo_comp_op_);
                    }
                }
            }
            else
            {
                error = FT_Glyph_To_Bitmap(&g, FT_RENDER_MODE_NORMAL, 0, 1);
                if (error)
                {
                    continue;
                }
                FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
                if (bit->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
                {
                    pixel_position render_pos(base_point);
                    image_rgba8 glyph_image(render_glyph_image(glyph,
                                                               bit->bitmap,
                                                               transform_,
                                                               render_pos));
                    const constexpr std::size_t pixel_size = sizeof(image_rgba8::pixel_type);
                    render_halo<pixel_size>(glyph_image.bytes(),
                                            glyph_image.width(),
                                            glyph_image.height(),
                                            halo_fill,
                                            render_pos.x, render_pos.y,
                                            halo_radius,
                                            halo_opacity,
                                            halo_comp_op_);
                }
                else
                {
                    render_halo<1>(bit->bitmap.buffer,
                                   bit->bitmap.width,
                                   bit->bitmap.rows,
                                   halo_fill,
                                   bit->left,
                                   height - bit->top,
                                   halo_radius,
                                   halo_opacity,
                                   halo_comp_op_);
                }
            }
        }
        FT_Done_Glyph(g);
    }

    // render actual text
    for (auto & glyph : glyphs_)
    {
        fill = glyph.properties.fill.rgba();
        text_opacity = glyph.properties.text_opacity;

        FT_Glyph_Transform(glyph.image, &matrix, &start);
        error = 0;
        if ( glyph.image->format != FT_GLYPH_FORMAT_BITMAP )
        {
            error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL, 0, 1);
        }
        if (error == 0)
        {
            FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(glyph.image);
            int pixel_mode = bit->bitmap.pixel_mode;
            if (pixel_mode == FT_PIXEL_MODE_BGRA)
            {
                int x = base_point.x + glyph.pos.x;
                int y = base_point.y - glyph.pos.y;
                agg::trans_affine transform(
                    glyph_transform(transform_,
                                    bit->bitmap.rows,
                                    x, y,
                                    -glyph.rot.angle(),
                                    glyph.bbox));
                composite_color_glyph(pixmap_,
                                      bit->bitmap,
                                      transform,
                                      text_opacity,
                                      comp_op_);
            }
            else
            {
                composite_bitmap(pixmap_,
                                 &bit->bitmap,
                                 fill,
                                 bit->left,
                                 height - bit->top,
                                 text_opacity,
                                 comp_op_);
            }
        }
        FT_Done_Glyph(glyph.image);
    }

}