[mapserver-commits] r9853 - trunk/mapserver
svn at osgeo.org
svn at osgeo.org
Sun Feb 21 18:26:28 EST 2010
Author: tbonfort
Date: 2010-02-21 18:26:27 -0500 (Sun, 21 Feb 2010)
New Revision: 9853
Added:
trunk/mapserver/mapagg2.cpp
Modified:
trunk/mapserver/Makefile.in
trunk/mapserver/mapcairo.c
trunk/mapserver/mapdraw.c
trunk/mapserver/mapoutput.c
trunk/mapserver/maprendering.c
trunk/mapserver/mapserver.h
trunk/mapserver/mapwms.c
Log:
add initial implementation of agg plugin renderer
Modified: trunk/mapserver/Makefile.in
===================================================================
--- trunk/mapserver/Makefile.in 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/Makefile.in 2010-02-21 23:26:27 UTC (rev 9853)
@@ -267,7 +267,7 @@
RM= /bin/rm -f
-OBJS= $(AGG_OBJ) mapogl.o mapoglrenderer.o mapoglcontext.o mapimageio.o mapcairo.o maprendering.o mapgeomtransform.o maprgbapng.o maptemplate.o mapbits.o maphash.o mapshape.o mapxbase.o mapparser.o maplexer.o maptree.o mapsearch.o mapstring.o mapsymbol.o mapfile.o maplegend.o maputil.o mapscale.o mapquery.o maplabel.o maperror.o mapprimitive.o mapproject.o mapraster.o mapsde.o mapogr.o mappostgis.o mapmygis.o maplayer.o mapresample.o mapwms.o mapwmslayer.o maporaclespatial.o mapgml.o mapprojhack.o mapthread.o mapdraw.o mapgd.o mapagg.o mapoutput.o mapgdal.o mapswf.o mapimagemap.o mapows.o mapwfs.o mapwfs11.o mapwfslayer.o mapcontext.o maphttp.o mapdrawgdal.o mappdf.o mapjoin.o mapgraticule.o mapcopy.o mapogcfilter.o mapogcsld.o maptime.o mapwcs.o mapwcs11.o mapcpl.o cgiutil.o maprasterquery.o mapobject.o mapgeos.o classobject.o layerobject.o mapio.o mappool.o mapsvg.o mapregex.o mappluginlayer.o mapogcsos.o mappostgresql.o mapcrypto.o mapowscommon.o maplibxml2.o mapdebug.o mapchart.o maptclutf.o $(EPPL_OBJ)
+OBJS= $(AGG_OBJ) mapogl.o mapoglrenderer.o mapoglcontext.o mapimageio.o mapcairo.o maprendering.o mapgeomtransform.o maprgbapng.o maptemplate.o mapbits.o maphash.o mapshape.o mapxbase.o mapparser.o maplexer.o maptree.o mapsearch.o mapstring.o mapsymbol.o mapfile.o maplegend.o maputil.o mapscale.o mapquery.o maplabel.o maperror.o mapprimitive.o mapproject.o mapraster.o mapsde.o mapogr.o mappostgis.o mapmygis.o maplayer.o mapresample.o mapwms.o mapwmslayer.o maporaclespatial.o mapgml.o mapprojhack.o mapthread.o mapdraw.o mapgd.o mapagg.o mapagg2.o mapoutput.o mapgdal.o mapswf.o mapimagemap.o mapows.o mapwfs.o mapwfs11.o mapwfslayer.o mapcontext.o maphttp.o mapdrawgdal.o mappdf.o mapjoin.o mapgraticule.o mapcopy.o mapogcfilter.o mapogcsld.o maptime.o mapwcs.o mapwcs11.o mapcpl.o cgiutil.o maprasterquery.o mapobject.o mapgeos.o classobject.o layerobject.o mapio.o mappool.o mapsvg.o mapregex.o mappluginlayer.o mapogcsos.o mappostgresql.o mapcrypto.o mapowscommon.o maplibxml2.o mapdebug.o mapchart.o maptclutf.o $(EPPL_OBJ)
EXE_LIST = shp2img shp2pdf legend mapserv shptree shptreevis \
shptreetst scalebar sortshp mapscriptvars tile4ms \
@@ -302,6 +302,9 @@
mapagg.o: mapagg.cpp mapagg.h
$(CXX) -c $(CXXFLAGS) -Wno-uninitialized mapagg.cpp -o mapagg.o
+mapagg2.o: mapagg2.cpp mapagg.h
+ $(CXX) -c $(CXXFLAGS) -Wno-uninitialized mapagg2.cpp -o mapagg2.o
+
php3_mapscript:: $(LIBMAP_STATIC)
cd mapscript/php3; $(MAKE); cd ../..
Added: trunk/mapserver/mapagg2.cpp
===================================================================
--- trunk/mapserver/mapagg2.cpp (rev 0)
+++ trunk/mapserver/mapagg2.cpp 2010-02-21 23:26:27 UTC (rev 9853)
@@ -0,0 +1,561 @@
+/******************************************************************************
+ * $id$
+ *
+ * Project: MapServer
+ * Purpose: AGG rendering and other AGG related functions.
+ * Author: Thomas Bonfort and the MapServer team.
+ *
+ ******************************************************************************
+ * Copyright (c) 1996-2007 Regents of the University of Minnesota.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of this Software or works derived from this Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+#include "mapserver.h"
+#include "mapagg.h"
+#include "renderers/agg/include/agg_color_rgba.h"
+#include "renderers/agg/include/agg_pixfmt_rgba.h"
+#include "renderers/agg/include/agg_renderer_base.h"
+#include "renderers/agg/include/agg_renderer_scanline.h"
+#include "renderers/agg/include/agg_math_stroke.h"
+#include "renderers/agg/include/agg_scanline_p.h"
+#include "renderers/agg/include/agg_scanline_u.h"
+#include "renderers/agg/include/agg_scanline_bin.h"
+#include "renderers/agg/include/agg_rasterizer_scanline_aa.h"
+#include "renderers/agg/include/agg_conv_stroke.h"
+#include "renderers/agg/include/agg_conv_dash.h"
+#include "renderers/agg/include/agg_path_storage.h"
+#include "renderers/agg/include/agg_font_freetype.h"
+#include "renderers/agg/include/agg_conv_contour.h"
+
+#ifdef CPL_MSB
+typedef mapserver::order_argb band_order;
+#else
+typedef mapserver::order_bgra band_order;
+#endif
+
+#define AGG_LINESPACE 1.33
+
+typedef mapserver::int8u band_type;
+typedef mapserver::rgba8 color_type;
+typedef mapserver::pixel32_type pixel_type;
+
+typedef mapserver::blender_rgba_pre<color_type, band_order> blender_pre;
+typedef mapserver::pixfmt_alpha_blend_rgba<blender_pre, mapserver::rendering_buffer, pixel_type> pixel_format;
+typedef mapserver::rendering_buffer rendering_buffer;
+typedef mapserver::renderer_base<pixel_format> renderer_base;
+typedef mapserver::renderer_scanline_aa_solid<renderer_base> renderer_scanline;
+typedef mapserver::rasterizer_scanline_aa<> rasterizer_scanline;
+typedef mapserver::font_engine_freetype_int16 font_engine_type;
+typedef mapserver::font_cache_manager<font_engine_type> font_manager_type;
+typedef mapserver::conv_curve<font_manager_type::path_adaptor_type> font_curve_type;
+
+static color_type AGG_NO_COLOR = color_type(0, 0, 0, 0);
+
+inline static color_type aggColor(colorObj *c) {
+ if (c && MS_VALID_COLOR(*c)) {
+ return mapserver::rgba8_pre(c->red, c->green, c->blue, c->alpha);
+ } else {
+ return color_type(0, 0, 0, 0);
+ }
+}
+
+class AGG2Renderer {
+public:
+
+ AGG2Renderer() : m_fman(m_feng) {
+ }
+
+ band_type* buffer;
+ rendering_buffer m_rendering_buffer;
+ pixel_format m_pixel_format;
+ renderer_base m_renderer_base;
+ renderer_scanline m_renderer_scanline;
+ rasterizer_scanline m_rasterizer_aa;
+ mapserver::scanline_p8 sl_poly; /*packed scanlines, works faster when the area is larger
+ than the perimeter, in number of pixels*/
+ mapserver::scanline_u8 sl_line; /*unpacked scanlines, works faster if the area is roughly
+ equal to the perimeter, in number of pixels*/
+ mapserver::scanline_bin m_sl_bin;
+ font_engine_type m_feng;
+ font_manager_type m_fman;
+};
+
+inline AGG2Renderer *agg2GetRenderer(imageObj *image) {
+ return (AGG2Renderer*) image->img.plugin;
+}
+
+template<class VertexSource>
+static void applyCJC(VertexSource &stroke, int caps, int joins) {
+ switch (joins) {
+ case MS_CJC_NONE:
+ case MS_CJC_ROUND:
+ stroke.line_join(mapserver::round_join);
+ break;
+ case MS_CJC_MITER:
+ stroke.line_join(mapserver::miter_join);
+ break;
+ case MS_CJC_BEVEL:
+ stroke.line_join(mapserver::bevel_join);
+ break;
+ }
+ switch (caps) {
+ case MS_CJC_BUTT:
+ case MS_CJC_NONE:
+ stroke.line_cap(mapserver::butt_cap);
+ break;
+ case MS_CJC_ROUND:
+ stroke.line_cap(mapserver::round_cap);
+ break;
+ case MS_CJC_SQUARE:
+ stroke.line_cap(mapserver::square_cap);
+ break;
+ }
+}
+
+void agg2RenderLine(imageObj *img, shapeObj *p, strokeStyleObj *style) {
+
+ AGG2Renderer *r = agg2GetRenderer(img);
+ line_adaptor lines = line_adaptor(p);
+ 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);
+ applyCJC(stroke, style->linecap, style->linejoin);
+ 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);
+ 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])));
+ }
+ stroke_dash.width(style->width);
+ applyCJC(stroke_dash, style->linecap, style->linejoin);
+ r->m_rasterizer_aa.add_path(stroke_dash);
+ }
+ }
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
+}
+
+void agg2RenderLineTiled(imageObj *img, shapeObj *p, imageObj * tile) {
+
+}
+
+void agg2RenderPolygon(imageObj *img, shapeObj *p, colorObj * color) {
+ AGG2Renderer *r = agg2GetRenderer(img);
+ polygon_adaptor polygons(p);
+ r->m_rasterizer_aa.reset();
+ r->m_rasterizer_aa.filling_rule(mapserver::fill_even_odd);
+ r->m_rasterizer_aa.add_path(polygons);
+ r->m_renderer_scanline.color(aggColor(color));
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_poly, r->m_renderer_scanline);
+}
+
+void agg2RenderPolygonTiled(imageObj *img, shapeObj *p, imageObj * tile) {
+
+}
+
+void agg2RenderGlyphs(imageObj *img, double x, double y,
+ labelStyleObj *style, char *text) {
+ AGG2Renderer *r = agg2GetRenderer(img);
+ if (!r->m_feng.load_font(style->font, 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderGlyphs()", style->font);
+ }
+ r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
+
+ const mapserver::glyph_cache* glyph;
+ int unicode;
+ r->m_feng.hinting(true);
+ r->m_feng.height(style->size);
+ r->m_feng.resolution(96);
+ r->m_feng.flip_y(true);
+ font_curve_type m_curves(r->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);
+ glyph = r->m_fman.glyph(unicode);
+ ;
+ if (glyph) {
+ r->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;
+ }
+ }
+
+ //use a smoother renderer for the shadow
+ /*if (shadowcolor.a) {
+ mapserver::trans_affine_translation tr(shdx, shdy);
+ mapserver::conv_transform<mapserver::path_storage, mapserver::trans_affine> tglyphs(glyphs, tr);
+ mapserver::line_profile_aa prof;
+ prof.width(0.5);
+ renderer_oaa ren_oaa(ren_base, prof);
+ rasterizer_outline_aa rasterizer_smooth(ren_oaa);
+ ren_oaa.color(shadowcolor);
+ rasterizer_smooth.add_path(tglyphs);
+ }*/
+ if (style->outlinewidth && style->outlinecolor.alpha) {
+ color_type outlinecolor = aggColor(&(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.width(style->outlinewidth);
+ r->m_rasterizer_aa.add_path(cc);
+ r->m_renderer_scanline.color(outlinecolor);
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
+ }
+ if (style->color.alpha) {
+ color_type color = aggColor(&(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(color);
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
+ }
+
+}
+
+void agg2RenderGlyphsLine(imageObj *img, labelPathObj *labelpath,
+ labelStyleObj *style, char *text) {
+
+}
+
+void agg2RenderVectorSymbol(imageObj *img, double x, double y,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void* agg2CreateVectorSymbolTile(int width, int height,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void agg2RenderPixmapSymbol(imageObj *img, double x, double y,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void* agg2CreatePixmapSymbolTile(int width, int height,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void agg2RenderEllipseSymbol(imageObj *image, double x, double y,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void* agg2CreateEllipseSymbolTile(int width, int height,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void agg2RenderTruetypeSymbol(imageObj *img, double x, double y,
+ symbolObj *symbol, symbolStyleObj * style) {
+ AGG2Renderer *r = agg2GetRenderer(img);
+ if (!r->m_feng.load_font(symbol->full_font_path, 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2RenderTruetypeSymbol()", symbol->full_font_path);
+ }
+
+ const mapserver::glyph_cache* glyph;
+ int unicode;
+ r->m_feng.hinting(true);
+ r->m_feng.height(style->scale);
+ r->m_feng.resolution(96);
+ r->m_feng.flip_y(true);
+ font_curve_type m_curves(r->m_fman.path_adaptor());
+ double ox = 0, oy = 0;
+ //we're rendering a marker symbol, it has to be centered
+ //on the label point (the default is the lower left of the
+ //text)
+ //this block computes the offset between the lower left corner
+ //of the character and it's center for the given rotaion. this
+ //offset will then be used in the following mapserver::trans_affine_translation
+ msUTF8ToUniChar(symbol->character, &unicode);
+ glyph = r->m_fman.glyph(unicode);
+ ox = glyph->bounds.x1 + (glyph->bounds.x2 - glyph->bounds.x1) / 2.;
+ oy = glyph->bounds.y1 + (glyph->bounds.y2 - glyph->bounds.y1) / 2.;
+ mapserver::trans_affine_rotation(-style->rotation).transform(&ox, &oy);
+ 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 - ox, y - oy);
+ mapserver::path_storage glyphs;
+
+ r->m_fman.init_embedded_adaptors(glyph, x, y);
+ mapserver::conv_transform<font_curve_type, mapserver::trans_affine> trans_c(m_curves, mtx);
+ glyphs.concat_path(trans_c);
+ if (style->outlinecolor.alpha) {
+ color_type outlinecolor = aggColor(&(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.width(style->outlinewidth);
+ r->m_rasterizer_aa.add_path(cc);
+ r->m_renderer_scanline.color(outlinecolor);
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
+ }
+
+ if (style->color.alpha) {
+ r->m_rasterizer_aa.reset();
+ r->m_rasterizer_aa.filling_rule(mapserver::fill_non_zero);
+ r->m_rasterizer_aa.add_path(glyphs);
+ color_type color = aggColor(&(style->color));
+ r->m_renderer_scanline.color(color);
+ mapserver::render_scanlines(r->m_rasterizer_aa, r->sl_line, r->m_renderer_scanline);
+ }
+
+}
+
+void* agg2CreateTruetypeSymbolTile(int width, int height,
+ symbolObj *symbol, symbolStyleObj * style) {
+
+}
+
+void agg2RenderTile(imageObj *img, imageObj *tile, double x, double y) {
+
+}
+
+void agg2GetRasterBuffer(imageObj *img, rasterBufferObj * rb) {
+ AGG2Renderer *r = agg2GetRenderer(img);
+ rb->pixelbuffer = r->buffer;
+ rb->row_step = r->m_rendering_buffer.stride();
+ rb->pixel_step = 4;
+ rb->width = r->m_rendering_buffer.width();
+ rb->height = r->m_rendering_buffer.height();
+ rb->r = &(r->buffer[band_order::R]);
+ rb->g = &(r->buffer[band_order::G]);
+ rb->b = &(r->buffer[band_order::B]);
+ if (img->format->imagemode == MS_IMAGEMODE_RGBA) {
+ rb->a = &(r->buffer[band_order::A]);
+ } else {
+
+ rb->a = NULL;
+ }
+}
+
+void agg2MergeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, double opacity, int dstX, int dstY) {
+
+}
+
+/* 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));
+ AGG2Renderer *r = new AGG2Renderer();
+
+ r->buffer = new band_type[width * height * 4];
+ 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);
+ if (format->imagemode == MS_IMAGEMODE_RGBA) {
+ r->m_renderer_base.clear(AGG_NO_COLOR);
+ } else {
+ r->m_renderer_base.clear(aggColor(bg));
+ }
+ image->img.plugin = (void*) r;
+
+ return image;
+}
+
+int agg2SaveImage(imageObj *img, FILE *fp, outputFormatObj * format) {
+ msSetError(MS_MISCERR, "AGG2 does not support direct image saving", "agg2SaveImage()");
+
+ return MS_FAILURE;
+}
+/*...*/
+
+/* helper functions */
+int agg2GetTruetypeTextBBox(imageObj *img, char *font, double size, char *string,
+ rectObj *rect, double **advances) {
+ AGG2Renderer *r = agg2GetRenderer(img);
+ if (!r->m_feng.load_font(font, 0, mapserver::glyph_ren_outline)) {
+ msSetError(MS_TTFERR, "AGG error loading font (%s)", "agg2GetTruetypeTextBBox()", font);
+ return MS_FAILURE;
+ }
+ r->m_feng.hinting(true);
+ r->m_feng.height(size);
+ r->m_feng.resolution(96);
+ r->m_feng.flip_y(true);
+ int unicode, curGlyph = 1, numglyphs;
+ if (advances) {
+ numglyphs = msGetNumGlyphs(string);
+ }
+ const mapserver::glyph_cache* glyph;
+ string += msUTF8ToUniChar(string, &unicode);
+ glyph = r->m_fman.glyph(unicode);
+ if (glyph) {
+ rect->minx = glyph->bounds.x1;
+ rect->maxx = glyph->bounds.x2;
+ rect->miny = glyph->bounds.y1;
+ rect->maxy = glyph->bounds.y2;
+ } else
+ return MS_FAILURE;
+ if (advances) {
+ *advances = (double*) malloc(numglyphs * sizeof (double));
+ (*advances)[0] = glyph->advance_x;
+ }
+ double fx = glyph->advance_x, fy = glyph->advance_y;
+ while (*string) {
+ if (advances) {
+ if (*string == '\r' || *string == '\n')
+ (*advances)[curGlyph++] = -fx;
+ }
+ if (*string == '\r') {
+ fx = 0;
+ string++;
+ continue;
+ }
+ if (*string == '\n') {
+ fx = 0;
+ fy += ceil(size * AGG_LINESPACE);
+ string++;
+ continue;
+ }
+ string += msUTF8ToUniChar(string, &unicode);
+ glyph = r->m_fman.glyph(unicode);
+ if (glyph) {
+ double t;
+ rect->minx = MS_MIN(rect->minx, fx+glyph->bounds.x1);
+ rect->miny = MS_MIN(rect->miny, fy+glyph->bounds.y1);
+ rect->maxx = MS_MAX(rect->maxx, fx+glyph->bounds.x2);
+ rect->maxy = MS_MAX(rect->maxy, fy+glyph->bounds.y2);
+
+ fx += glyph->advance_x;
+ fy += glyph->advance_y;
+ if (advances) {
+ (*advances)[curGlyph++] = glyph->advance_x;
+ }
+ }
+ }
+ return MS_SUCCESS;
+}
+
+void agg2StartNewLayer(imageObj *img, double opacity) {
+}
+
+void agg2CloseNewLayer(imageObj *img, double opacity) {
+}
+
+void agg2TransformShape(shapeObj *shape, rectObj extend, double cellsize) {
+
+}
+
+void agg2FreeImage(imageObj * image) {
+
+ AGG2Renderer *r = agg2GetRenderer(image);
+ delete r->buffer;
+ delete r;
+ image->img.plugin = NULL;
+}
+
+void agg2FreeTile(imageObj * tile) {
+
+}
+
+void agg2FreeSymbol(symbolObj * symbol) {
+
+}
+
+int msPopulateRendererVTableAGG(rendererVTableObj * renderer) {
+ renderer->supports_transparent_layers = 0;
+ renderer->supports_pixel_buffer = 1;
+ renderer->supports_imagecache = 0;
+
+ renderer->renderLine = &agg2RenderLine;
+
+ renderer->renderPolygon = &agg2RenderPolygon;
+ renderer->renderPolygonTiled = &agg2RenderPolygonTiled;
+ renderer->renderLineTiled = &agg2RenderLineTiled;
+
+ renderer->renderGlyphs = &agg2RenderGlyphs;
+
+ renderer->renderGlyphsLine = &agg2RenderGlyphsLine;
+
+ renderer->renderVectorSymbol = &agg2RenderVectorSymbol;
+
+ renderer->createVectorSymbolTile = &agg2CreateVectorSymbolTile;
+
+ renderer->renderPixmapSymbol = &agg2RenderPixmapSymbol;
+
+ renderer->createPixmapSymbolTile = &agg2CreatePixmapSymbolTile;
+
+ renderer->renderEllipseSymbol = &agg2RenderEllipseSymbol;
+
+ renderer->createEllipseSymbolTile = &agg2CreateEllipseSymbolTile;
+
+ renderer->renderTruetypeSymbol = &agg2RenderTruetypeSymbol;
+
+ renderer->createTruetypeSymbolTile = &agg2CreateTruetypeSymbolTile;
+
+ renderer->renderTile = &agg2RenderTile;
+
+ renderer->getRasterBuffer = &agg2GetRasterBuffer;
+
+ renderer->mergeRasterBuffer = &agg2MergeRasterBuffer;
+ renderer->createImage = &agg2CreateImage;
+ renderer->saveImage = &agg2SaveImage;
+
+ renderer->getTruetypeTextBBox = &agg2GetTruetypeTextBBox;
+
+ renderer->startNewLayer = &agg2StartNewLayer;
+ renderer->closeNewLayer = &agg2CloseNewLayer;
+
+ renderer->transformShape = &msTransformShapeAGG;
+ renderer->freeImage = &agg2FreeImage;
+ renderer->freeTile = &agg2FreeTile;
+ renderer->freeSymbol = &agg2FreeSymbol;
+ return MS_SUCCESS;
+}
Modified: trunk/mapserver/mapcairo.c
===================================================================
--- trunk/mapserver/mapcairo.c 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/mapcairo.c 2010-02-21 23:26:27 UTC (rev 9853)
@@ -478,8 +478,11 @@
cairo_restore(r->cr);
}
- msCairoSetSourceColor(r->cr, &style->color);
- cairo_fill(r->cr);
+ if(MS_VALID_COLOR(style->color)) {
+ msCairoSetSourceColor(r->cr, &style->color);
+ cairo_fill(r->cr);
+ }
+ cairo_new_path(r->cr);
cairo_restore(r->cr);
return;
}
Modified: trunk/mapserver/mapdraw.c
===================================================================
--- trunk/mapserver/mapdraw.c 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/mapdraw.c 2010-02-21 23:26:27 UTC (rev 9853)
@@ -149,6 +149,7 @@
}
else if (MS_RENDERER_PLUGIN(map->outputformat)) {
rendererVTableObj *renderer = map->outputformat->vtable;
+ map->imagecolor.alpha=255;
image = renderer->createImage(map->width, map->height, map->outputformat,&map->imagecolor);
if (image == NULL)
return(NULL);
@@ -156,6 +157,9 @@
image->format->refcount++;
image->width = map->width;
image->height = map->height;
+
+ image->resolution = map->resolution;
+ image->resolutionfactor = map->resolution/map->defresolution;
if (map->web.imagepath)
image->imagepath = strdup(map->web.imagepath);
if (map->web.imageurl)
Modified: trunk/mapserver/mapoutput.c
===================================================================
--- trunk/mapserver/mapoutput.c 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/mapoutput.c 2010-02-21 23:26:27 UTC (rev 9853)
@@ -219,6 +219,14 @@
format->renderer = MS_RENDER_WITH_AGG;
}
#endif
+ if( strcasecmp(driver,"AGG2/PNG") == 0 )
+ {
+ format = msAllocOutputFormat( map, "agg2png", driver );
+ format->mimetype = strdup("image/png; mode=24bit");
+ format->imagemode = MS_IMAGEMODE_RGB;
+ format->extension = strdup("png");
+ format->renderer = MS_RENDER_WITH_AGG2;
+ }
#if defined(USE_CAIRO)
if( strcasecmp(driver,"CAIRO/PNG") == 0 )
@@ -290,6 +298,14 @@
format->renderer = MS_RENDER_WITH_PDF;
}
#endif
+ if( strcasecmp(driver,"agg2png") == 0 )
+ {
+ format = msAllocOutputFormat( map, "agg2png", driver );
+ format->mimetype = strdup("image/png");
+ format->imagemode = MS_IMAGEMODE_RGB;
+ format->extension = strdup("png");
+ format->renderer = MS_RENDER_WITH_AGG2;
+ }
#ifdef USE_GDAL
if( strncasecmp(driver,"gdal/",5) == 0 )
{
@@ -375,6 +391,9 @@
if( msSelectOutputFormat( map, "aggjpeg" ) == NULL )
msCreateDefaultOutputFormat( map, "AGG/JPEG" );
+
+ if( msSelectOutputFormat( map, "agg2png" ) == NULL )
+ msCreateDefaultOutputFormat( map, "AGG2/PNG" );
if( msSelectOutputFormat( map, "cairopng" ) == NULL )
msCreateDefaultOutputFormat( map, "CAIRO/PNG" );
@@ -1044,6 +1063,8 @@
format->vtable = (rendererVTableObj*)malloc(sizeof(rendererVTableObj));
switch(format->renderer) {
+ case MS_RENDER_WITH_AGG2:
+ return msPopulateRendererVTableAGG(format->vtable);
case MS_RENDER_WITH_CAIRO_RASTER:
return msPopulateRendererVTableCairoRaster(format->vtable);
case MS_RENDER_WITH_CAIRO_PDF:
Modified: trunk/mapserver/maprendering.c
===================================================================
--- trunk/mapserver/maprendering.c 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/maprendering.c 2010-02-21 23:26:27 UTC (rev 9853)
@@ -844,17 +844,50 @@
int nReturnVal = -1;
if(image) {
if (MS_RENDERER_PLUGIN(image->format)) {
- rendererVTableObj *renderer = image->format->vtable;
- labelStyleObj s;
- if (!string || !strlen(string))
- return (0); // not errors, just don't want to do anything
+ rendererVTableObj *renderer = image->format->vtable;
+ labelStyleObj s;
+ if (!string || !strlen(string))
+ return (0); // not errors, just don't want to do anything
- computeLabelStyle(&s,label,fontset,scalefactor);
- if (label->type == MS_TRUETYPE) {
- renderer->renderGlyphsLine(image,labelpath,&s,string);
+
+ computeLabelStyle(&s, label, fontset, scalefactor);
+ if (label->type == MS_TRUETYPE) {
+ const char* string_ptr = string;
+ int i;
+ double x, y;
+ char glyph[11];
+ if(MS_VALID_COLOR(s.outlinecolor)) {
+ colorObj storecolor;
+ MS_COPYCOLOR(&storecolor,&(s.color));
+ MS_INIT_COLOR(s.color,-1,-1,-1);
+ for (i = 0; i < labelpath->path.numpoints; i++) {
+ if (msGetNextGlyph(&string_ptr, glyph) == -1)
+ break; /* Premature end of string??? */
+
+ s.rotation = labelpath->angles[i];
+ x = labelpath->path.point[i].x;
+ y = labelpath->path.point[i].y;
+
+ renderer->renderGlyphs(image, x, y, &s, glyph);
+ }
+ MS_INIT_COLOR(s.outlinecolor,-1,-1,-1);
+ MS_COPYCOLOR(&(s.color),&storecolor);
+ string_ptr = string;
}
- }
+ s.outlinewidth = 0;
+ for (i = 0; i < labelpath->path.numpoints; i++) {
+ if (msGetNextGlyph(&string_ptr, glyph) == -1)
+ break; /* Premature end of string??? */
+
+ s.rotation = labelpath->angles[i];
+ x = labelpath->path.point[i].x;
+ y = labelpath->path.point[i].y;
+
+ renderer->renderGlyphs(image, x, y, &s, glyph);
+ }
+ }
+ }
else if( MS_RENDERER_GD(image->format) )
nReturnVal = msDrawTextLineGD(image, string, label, labelpath, fontset, scalefactor);
#ifdef USE_AGG
Modified: trunk/mapserver/mapserver.h
===================================================================
--- trunk/mapserver/mapserver.h 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/mapserver.h 2010-02-21 23:26:27 UTC (rev 9853)
@@ -325,6 +325,7 @@
#define MS_DRIVER_IMAGEMAP(format) (strncasecmp((format)->driver,"imagemap",8)==0)
#define MS_DRIVER_SVG(format) (strncasecmp((format)->driver,"svg",3)==0)
#define MS_DRIVER_AGG(format) (strncasecmp((format)->driver,"agg/",4)==0)
+#define MS_DRIVER_AGG2(format) (strncasecmp((format)->driver,"agg2/",5)==0)
#define MS_DRIVER_CAIRO(format) (strncasecmp((format)->driver,"cairo/",6)==0)
#define MS_DRIVER_OGL(format) (strncasecmp((format)->driver,"ogl/",4)==0)
#define MS_DRIVER_TEMPLATE(format) (strncasecmp((format)->driver,"template",8)==0)
@@ -341,6 +342,7 @@
#define MS_RENDER_WITH_CAIRO_PDF 10
#define MS_RENDER_WITH_CAIRO_SVG 11
#define MS_RENDER_WITH_OGL 12
+#define MS_RENDER_WITH_AGG2 13
#define MS_RENDERER_GD(format) ((format)->renderer == MS_RENDER_WITH_GD)
#define MS_RENDERER_SWF(format) ((format)->renderer == MS_RENDER_WITH_SWF)
@@ -2600,6 +2602,7 @@
MS_DLL_EXPORT int msPopulateRendererVTableCairoSVG( rendererVTableObj *renderer );
MS_DLL_EXPORT int msPopulateRendererVTableCairoPDF( rendererVTableObj *renderer );
MS_DLL_EXPORT int msPopulateRendererVTableOGL( rendererVTableObj *renderer );
+MS_DLL_EXPORT int msPopulateRendererVTableAGG( rendererVTableObj *renderer );
//allocate 50k for starters
#define MS_DEFAULT_BUFFER_ALLOC 50000
Modified: trunk/mapserver/mapwms.c
===================================================================
--- trunk/mapserver/mapwms.c 2010-02-21 22:30:46 UTC (rev 9852)
+++ trunk/mapserver/mapwms.c 2010-02-21 23:26:27 UTC (rev 9853)
@@ -697,6 +697,8 @@
(strncasecmp(format->driver, "GD/", 3) != 0 &&
strncasecmp(format->driver, "GDAL/", 5) != 0 &&
strncasecmp(format->driver, "AGG/", 4) != 0 &&
+ strncasecmp(format->driver, "AGG2/", 5) != 0 &&
+ strncasecmp(format->driver, "CAIRO/", 6) != 0 &&
strncasecmp(format->driver, "SVG", 3) != 0))
{
msSetError(MS_IMGERR,
More information about the mapserver-commits
mailing list