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