Beispiel #1
0
int agg2RenderVectorSymbol(imageObj *img, double x, double y,
                           symbolObj *symbol, symbolStyleObj * style)
{
  AGG2Renderer *r = AGG_RENDERER(img);
  double ox = symbol->sizex * 0.5;
  double oy = symbol->sizey * 0.5;

  mapserver::path_storage path = imageVectorSymbol(symbol);
  mapserver::trans_affine mtx;
  mtx *= mapserver::trans_affine_translation(-ox,-oy);
  mtx *= mapserver::trans_affine_scaling(style->scale);
  mtx *= mapserver::trans_affine_rotation(-style->rotation);
  mtx *= mapserver::trans_affine_translation(x, y);
  path.transform(mtx);
  if (style->color) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd);
    r->m_rasterizer_aa.add_path(path);
    r->m_renderer_scanline.color(aggColor(style->color));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline);
  }
  if(style->outlinecolor) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    r->m_renderer_scanline.color(aggColor(style->outlinecolor));
    mapserver::conv_stroke<mapserver::path_storage> stroke(path);
    stroke.width(style->outlinewidth);
    r->m_rasterizer_aa.add_path(stroke);
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline);
  }
  return MS_SUCCESS;
}
Beispiel #2
0
int agg2RenderEllipseSymbol(imageObj *image, double x, double y,
                            symbolObj *symbol, symbolStyleObj * style)
{
  AGG2Renderer *r = AGG_RENDERER(image);
  mapserver::path_storage path;
  mapserver::ellipse ellipse(x,y,symbol->sizex*style->scale/2,symbol->sizey*style->scale/2);
  path.concat_path(ellipse);
  if( style->rotation != 0) {
    mapserver::trans_affine mtx;
    mtx *= mapserver::trans_affine_translation(-x,-y);
    /*agg angles are antitrigonometric*/
    mtx *= mapserver::trans_affine_rotation(-style->rotation);
    mtx *= mapserver::trans_affine_translation(x,y);
    path.transform(mtx);
  }

  if(style->color) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd);
    r->m_rasterizer_aa.add_path(path);
    r->m_renderer_scanline.color(aggColor(style->color));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  if(style->outlinewidth) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    mapserver::conv_stroke<mapserver::path_storage> stroke(path);
    stroke.width(style->outlinewidth);
    r->m_rasterizer_aa.add_path(stroke);
    r->m_renderer_scanline.color(aggColor(style->outlinecolor));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline);
  }
  return MS_SUCCESS;
}
Beispiel #3
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;
}
Beispiel #4
0
int agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style)
{

  AGG2Renderer *r = AGG_RENDERER(img);
  line_adaptor lines = line_adaptor(p);

#ifdef AGG_ALIASED_ENABLED
  r->m_rasterizer_primitives.reset();
  r->m_renderer_primitives.line_color(aggColor(style->color));
  r->m_rasterizer_primitives.add_path(lines);
  return MS_SUCCESS;
#endif

  r->m_rasterizer_aa.reset();
  r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
  r->m_renderer_scanline.color(aggColor(style->color));

  if (style->patternlength <= 0) {
    mapserver::conv_stroke<line_adaptor> stroke(lines);
    stroke.width(style->width);
    if(style->width>1) {
      applyCJC(stroke, style->linecap, style->linejoin);
    } else {
      stroke.inner_join(mapserver::inner_bevel);
      stroke.line_join(mapserver::bevel_join);
    }
    r->m_rasterizer_aa.add_path(stroke);
  } else {
    mapserver::conv_dash<line_adaptor> dash(lines);
    mapserver::conv_stroke<mapserver::conv_dash<line_adaptor> > stroke_dash(dash);
    int patt_length = 0;
    for (int i = 0; i < style->patternlength; i += 2) {
      if (i < style->patternlength - 1) {
        dash.add_dash(MS_MAX(1,MS_NINT(style->pattern[i])),
                      MS_MAX(1,MS_NINT(style->pattern[i + 1])));
        if(style->patternoffset) {
          patt_length += MS_MAX(1,MS_NINT(style->pattern[i])) +
                         MS_MAX(1,MS_NINT(style->pattern[i + 1]));
        }
      }
    }
    if(style->patternoffset > 0) {
      dash.dash_start(patt_length - style->patternoffset);
    }
    stroke_dash.width(style->width);
    if(style->width>1) {
      applyCJC(stroke_dash, style->linecap, style->linejoin);
    } else {
      stroke_dash.inner_join(mapserver::inner_bevel);
      stroke_dash.line_join(mapserver::bevel_join);
    }
    r->m_rasterizer_aa.add_path(stroke_dash);
  }
  mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  return MS_SUCCESS;
}
Beispiel #5
0
int agg2RenderBitmapGlyphs(imageObj *img, double x, double y, labelStyleObj *style, char *text)
{
  typedef mapserver::glyph_raster_bin<color_type> glyph_gen;
  int size = MS_NINT(style->size);
  if(size<0 || size>4) {
    msSetError(MS_RENDERERERR,"invalid bitmap font size", "agg2RenderBitmapGlyphs()");
    return MS_FAILURE;
  }
  AGG2Renderer *r = AGG_RENDERER(img);
  glyph_gen glyph(0);
  mapserver::renderer_raster_htext_solid<renderer_base, glyph_gen> rt(r->m_renderer_base, glyph);
  glyph.font(rasterfonts[size]);
  int numlines=0;
  char **lines;
  /*masking out the out-of-range character codes*/
  int len;
  int cc_start = rasterfonts[size][2];
  int cc_end = cc_start + rasterfonts[size][3];
  if(msCountChars(text,'\n')) {
    if((lines = msStringSplit((const char*)text, '\n', &(numlines))) == NULL)
      return(-1);
  } else {
    lines = &text;
    numlines = 1;
  }
  y -= glyph.base_line();
  for(int n=0; n<numlines; n++) {
    len = strlen(lines[n]);
    for (int i = 0; i < len; i++)
      if (lines[n][i] < cc_start || lines[n][i] > cc_end)
        lines[n][i] = '.';
    if(style->outlinewidth > 0) {
      rt.color(aggColor(style->outlinecolor));
      for(int i=-1; i<=1; i++) {
        for(int j=-1; j<=1; j++) {
          if(i||j) {
            rt.render_text(x+i, y+j, lines[n], true);
          }
        }
      }
    }
    assert(style->color);
    rt.color(aggColor(style->color));
    rt.render_text(x, y, lines[n], true);
    y += glyph.height();
  }
  if(*lines != text)
    msFreeCharArray(lines, numlines);
  return MS_SUCCESS;
  return MS_SUCCESS;
}
Beispiel #6
0
int agg2RenderBitmapGlyphs2(imageObj *img, textPathObj *tp, colorObj *c, colorObj *oc, int ow)
{
  int size = tp->glyph_size;
  size = MS_MAX(0,size);
  size = MS_MIN(4,size);
  AGG2Renderer *r = AGG_RENDERER(img);

  glyph_gen glyph(0);
  mapserver::renderer_raster_htext_solid<renderer_base, glyph_gen> rt(r->m_renderer_base, glyph);
  glyph.font(rasterfonts[size]);
  unsigned int cc_start = rasterfonts[size][2];
  unsigned int cc_end = cc_start + rasterfonts[size][3];
  unsigned int glyph_idx;
  if(oc) {
    rt.color(aggColor(oc));
    for(int n=0; n<tp->numglyphs; n++) {
      glyphObj *g = &tp->glyphs[n];
      /* do some unicode mapping, for now we just replace unsupported characters with "." */
      if(g->glyph->key.codepoint < cc_start || g->glyph->key.codepoint > cc_end) {
        glyph_idx = '.';
      } else {
        glyph_idx = g->glyph->key.codepoint;
      }
      for(int i=-1; i<=1; i++) {
        for(int j=-1; j<=1; j++) {
          if(i||j) {
            rt.render_glyph(g->pnt.x+i , g->pnt.y+j, glyph_idx, true);
          }
        }
      }

    }
  }
  if(c) {
    rt.color(aggColor(c));
    for(int n=0; n<tp->numglyphs; n++) {
      glyphObj *g = &tp->glyphs[n];
      /* do some unicode mapping, for now we just replace unsupported characters with "." */
      if(g->glyph->key.codepoint < cc_start || g->glyph->key.codepoint > cc_end) {
        glyph_idx = '.';
      } else {
        glyph_idx = g->glyph->key.codepoint;
      }
      rt.render_glyph(g->pnt.x , g->pnt.y, glyph_idx, true);
    }
  }
  return MS_SUCCESS;
}
Beispiel #7
0
int agg2RenderTruetypeSymbol(imageObj *img, double x, double y,
                             symbolObj *symbol, symbolStyleObj * style)
{
  AGG2Renderer *r = AGG_RENDERER(img);
  aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(MS_IMAGE_RENDERER(img));
  if(aggLoadFont(cache,symbol->full_font_path,style->scale) == MS_FAILURE)
    return MS_FAILURE;

  int unicode;
  font_curve_type m_curves(cache->m_fman.path_adaptor());

  msUTF8ToUniChar(symbol->character, &unicode);
  const mapserver::glyph_cache* glyph = cache->m_fman.glyph(unicode);
  double ox = (glyph->bounds.x1 + glyph->bounds.x2) / 2.;
  double oy = (glyph->bounds.y1 + glyph->bounds.y2) / 2.;

  mapserver::trans_affine mtx = mapserver::trans_affine_translation(-ox, -oy);
  if(style->rotation)
    mtx *= mapserver::trans_affine_rotation(-style->rotation);
  mtx *= mapserver::trans_affine_translation(x, y);

  mapserver::path_storage glyphs;

  cache->m_fman.init_embedded_adaptors(glyph, 0,0);
  mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
  glyphs.concat_path(trans_c);
  if (style->outlinecolor) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    mapserver::conv_contour<mapserver::path_storage> cc(glyphs);
    cc.auto_detect_orientation(true);
    cc.width(style->outlinewidth + 1);
    r->m_rasterizer_aa.add_path(cc);
    r->m_renderer_scanline.color(aggColor(style->outlinecolor));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }

  if (style->color) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    r->m_rasterizer_aa.add_path(glyphs);
    r->m_renderer_scanline.color(aggColor(style->color));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  return MS_SUCCESS;

}
Beispiel #8
0
int agg2RenderPolygon(imageObj *img, shapeObj *p, colorObj * color)
{
  AGG2Renderer *r = AGG_RENDERER(img);
  polygon_adaptor polygons(p);
  r->m_rasterizer_aa_gamma.reset();
  r->m_rasterizer_aa_gamma.filling_rule(mapserver::fill_even_odd);
  r->m_rasterizer_aa_gamma.add_path(polygons);
  r->m_renderer_scanline.color(aggColor(color));
  mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, r->m_renderer_scanline);
  return MS_SUCCESS;
}
Beispiel #9
0
template<class VertexSource> int renderPolygonHatches(imageObj *img,VertexSource &clipper, colorObj *color)
{
  if(img->format->renderer == MS_RENDER_WITH_AGG) {
    AGG2Renderer *r = AGG_RENDERER(img);
    r->m_rasterizer_aa_gamma.reset();
    r->m_rasterizer_aa_gamma.filling_rule(mapserver::fill_non_zero);
    r->m_rasterizer_aa_gamma.add_path(clipper);
    r->m_renderer_scanline.color(aggColor(color));
    mapserver::render_scanlines(r->m_rasterizer_aa_gamma, r->sl_poly, r->m_renderer_scanline);
  } else {
    shapeObj shape;
    msInitShape(&shape);
    int allocated = 20;
    lineObj line;
    shape.line = &line;
    shape.numlines = 1;
    shape.line[0].point = (pointObj*)msSmallCalloc(allocated,sizeof(pointObj));
    shape.line[0].numpoints = 0;
    double x=0,y=0;
    unsigned int cmd;
    clipper.rewind(0);
    while((cmd = clipper.vertex(&x,&y)) != mapserver::path_cmd_stop) {
      switch(cmd) {
        case mapserver::path_cmd_line_to:
          if(shape.line[0].numpoints == allocated) {
            allocated *= 2;
            shape.line[0].point = (pointObj*)msSmallRealloc(shape.line[0].point, allocated*sizeof(pointObj));
          }
          shape.line[0].point[shape.line[0].numpoints].x = x;
          shape.line[0].point[shape.line[0].numpoints].y = y;
          shape.line[0].numpoints++;
          break;
        case mapserver::path_cmd_move_to:
          shape.line[0].point[0].x = x;
          shape.line[0].point[0].y = y;
          shape.line[0].numpoints = 1;
          break;
        case mapserver::path_cmd_end_poly|mapserver::path_flags_close:
          if(shape.line[0].numpoints > 2) {
            if(UNLIKELY(MS_FAILURE == MS_IMAGE_RENDERER(img)->renderPolygon(img,&shape,color))) {
              free(shape.line[0].point);
              return MS_FAILURE;
            }
          }
          break;
        default:
          assert(0); //WTF?
      }
    }
    free(shape.line[0].point);
  }
  return MS_SUCCESS;
}
Beispiel #10
0
/* image i/o */
imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorObj * bg)
{
  imageObj *image = NULL;
  if (format->imagemode != MS_IMAGEMODE_RGB && format->imagemode != MS_IMAGEMODE_RGBA) {
    msSetError(MS_MISCERR,
               "AGG2 driver only supports RGB or RGBA pixel models.", "agg2CreateImage()");
    return image;
  }
  image = (imageObj *) calloc(1, sizeof (imageObj));
  MS_CHECK_ALLOC(image, sizeof (imageObj), NULL);
  AGG2Renderer *r = new AGG2Renderer();

  r->buffer = (band_type*)malloc(width * height * 4 * sizeof(band_type));
  if (r->buffer == NULL) {
    msSetError(MS_MEMERR, "%s: %d: Out of memory allocating %u bytes.\n", "agg2CreateImage()",
               __FILE__, __LINE__, (unsigned int)(width * height * 4 * sizeof(band_type)));
    free(image);
    return NULL;
  }
  r->m_rendering_buffer.attach(r->buffer, width, height, width * 4);
  r->m_pixel_format.attach(r->m_rendering_buffer);
  r->m_renderer_base.attach(r->m_pixel_format);
  r->m_renderer_scanline.attach(r->m_renderer_base);
  r->default_gamma = atof(msGetOutputFormatOption( format, "GAMMA", "0.75" ));
  if(r->default_gamma <= 0.0 || r->default_gamma >= 1.0) {
    r->default_gamma = 0.75;
  }
  r->gamma_function.set(0,r->default_gamma);
  r->m_rasterizer_aa_gamma.gamma(r->gamma_function);
  if( bg && !format->transparent )
    r->m_renderer_base.clear(aggColor(bg));
  else
    r->m_renderer_base.clear(AGG_NO_COLOR);

  if (!bg || format->transparent || format->imagemode == MS_IMAGEMODE_RGBA ) {
    r->use_alpha = true;
  } else {
    r->use_alpha = false;
  }
  image->img.plugin = (void*) r;

  return image;
}
Beispiel #11
0
int agg2RenderGlyphsLine(imageObj *img, labelPathObj *labelpath, labelStyleObj *style, char *text)
{
  AGG2Renderer *r = AGG_RENDERER(img);
  aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(MS_IMAGE_RENDERER(img));
  if(aggLoadFont(cache,style->fonts[0],style->size) == MS_FAILURE)
    return MS_FAILURE;
  r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);

  const mapserver::glyph_cache* glyph;
  int unicode;
  int curfontidx = 0;
  font_curve_type m_curves(cache->m_fman.path_adaptor());

  mapserver::path_storage glyphs;

  for (int i = 0; i < labelpath->path.numpoints; i++) {
    assert(text);
    mapserver::trans_affine mtx;
    mtx *= mapserver::trans_affine_translation(-labelpath->path.point[i].x,-labelpath->path.point[i].y);
    mtx *= mapserver::trans_affine_rotation(-labelpath->angles[i]);
    mtx *= mapserver::trans_affine_translation(labelpath->path.point[i].x,labelpath->path.point[i].y);
    text += msUTF8ToUniChar(text, &unicode);

    if(curfontidx != 0) {
      if(aggLoadFont(cache,style->fonts[0],style->size) == MS_FAILURE)
        return MS_FAILURE;
      curfontidx = 0;
    }

    glyph = cache->m_fman.glyph(unicode);

    if(!glyph || glyph->glyph_index == 0) {
      int i;
      for(i=1; i<style->numfonts; i++) {
        if(aggLoadFont(cache,style->fonts[i],style->size) == MS_FAILURE)
          return MS_FAILURE;
        curfontidx = i;
        glyph = cache->m_fman.glyph(unicode);
        if(glyph && glyph->glyph_index != 0) {
          break;
        }
      }
    }
    if (glyph) {
      cache->m_fman.init_embedded_adaptors(glyph, labelpath->path.point[i].x,labelpath->path.point[i].y);
      mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
      glyphs.concat_path(trans_c);
    }
  }

  if (style->outlinewidth) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    mapserver::conv_contour<mapserver::path_storage> cc(glyphs);
    cc.width(style->outlinewidth + 1);
    r->m_rasterizer_aa.add_path(cc);
    r->m_renderer_scanline.color(aggColor(style->outlinecolor));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  if (style->color) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    r->m_rasterizer_aa.add_path(glyphs);
    r->m_renderer_scanline.color(aggColor(style->color));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }

  return MS_SUCCESS;
}
Beispiel #12
0
int agg2RenderGlyphs(imageObj *img, double x, double y, labelStyleObj *style, char *text)
{
  AGG2Renderer *r = AGG_RENDERER(img);
  aggRendererCache *cache = (aggRendererCache*)MS_RENDERER_CACHE(MS_IMAGE_RENDERER(img));
  if(aggLoadFont(cache,style->fonts[0],style->size) == MS_FAILURE)
    return MS_FAILURE;
  r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);

  int curfontidx = 0;
  const mapserver::glyph_cache* glyph;
  int unicode;
  font_curve_type m_curves(cache->m_fman.path_adaptor());
  mapserver::trans_affine mtx;
  mtx *= mapserver::trans_affine_translation(-x, -y);
  /*agg angles are antitrigonometric*/
  mtx *= mapserver::trans_affine_rotation(-style->rotation);
  mtx *= mapserver::trans_affine_translation(x, y);

  double fx = x, fy = y;
  const char *utfptr = text;
  mapserver::path_storage glyphs;

  //first render all the glyphs to a path
  while (*utfptr) {
    if (*utfptr == '\r') {
      fx = x;
      utfptr++;
      continue;
    }
    if (*utfptr == '\n') {
      fx = x;
      fy += ceil(style->size * AGG_LINESPACE);
      utfptr++;
      continue;
    }
    utfptr += msUTF8ToUniChar(utfptr, &unicode);
    if(curfontidx != 0) {
      if(aggLoadFont(cache,style->fonts[0],style->size) == MS_FAILURE)
        return MS_FAILURE;
      curfontidx = 0;
    }

    glyph = cache->m_fman.glyph(unicode);

    if(!glyph || glyph->glyph_index == 0) {
      int i;
      for(i=1; i<style->numfonts; i++) {
        if(aggLoadFont(cache,style->fonts[i],style->size) == MS_FAILURE)
          return MS_FAILURE;
        curfontidx = i;
        glyph = cache->m_fman.glyph(unicode);
        if(glyph && glyph->glyph_index != 0) {
          break;
        }
      }
    }


    if (glyph) {
      //cache->m_fman.add_kerning(&fx, &fy);
      cache->m_fman.init_embedded_adaptors(glyph, fx, fy);
      mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
      glyphs.concat_path(trans_c);
      fx += glyph->advance_x;
      fy += glyph->advance_y;
    }
  }

  if (style->outlinewidth) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    mapserver::conv_contour<mapserver::path_storage> cc(glyphs);
    cc.width(style->outlinewidth + 1);
    r->m_rasterizer_aa.add_path(cc);
    r->m_renderer_scanline.color(aggColor(style->outlinecolor));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }
  if (style->color) {
    r->m_rasterizer_aa.reset();
    r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
    r->m_rasterizer_aa.add_path(glyphs);
    r->m_renderer_scanline.color(aggColor(style->color));
    mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
  }

  return MS_SUCCESS;

}