Skip to content
Permalink
Browse files

Implement RFC-113 Layer Compositing Framework (#5071)

  • Loading branch information
tbonfort committed Feb 12, 2015
1 parent 7f20e12 commit 29db335114606f3564e81f3c706f137efdfb3fb2
Showing with 2,809 additions and 2,201 deletions.
  1. +13 −0 CMakeLists.txt
  2. +25 −0 cmake/FindPixman.cmake
  3. +198 −4 mapagg.cpp
  4. +83 −5 mapcairo.c
  5. +5 −1 mapcontext.c
  6. +45 −1 mapcopy.c
  7. +34 −9 mapdraw.c
  8. +1 −1 mapdummyrenderer.c
  9. +131 −5 mapfile.c
  10. +5 −0 mapfile.h
  11. +1 −2 mapkml.cpp
  12. +8 −8 mapkmlrenderer.cpp
  13. +10 −17 maplegend.c
  14. +2,170 −2,130 maplexer.c
  15. +3 −0 maplexer.l
  16. +3 −11 mapogcsld.c
  17. +3 −2 mapscript/php/layer.c
  18. +10 −0 mapscript/swiginc/layer.i
  19. +1 −0 mapserver-config.h.in
  20. +50 −3 mapserver.h
  21. +8 −0 maputil.c
  22. +1 −1 msautotest
  23. +1 −1 renderers/agg/include/agg_pixfmt_rgba.h
@@ -137,6 +137,7 @@ option(WITH_SDE "include ArcSDE support. Add -DSDE_VERSION=91 to use 9.1 arcSDE
option(WITH_EXEMPI "include xmp output metadata support" OFF)
option(WITH_XMLMAPFILE "include native xml mapfile support (requires libxslt/libexslt)" OFF)
option(WITH_V8 "include javacript v8 scripting" OFF)
option(WITH_PIXMAN "use pixman for layer compositing operations" OFF)

option(BUILD_STATIC "Also build a static version of mapserver" OFF)
option(LINK_STATIC_LIBMAPSERVER "Link to static version of libmapserver (also for mapscripts)" OFF)
@@ -333,6 +334,17 @@ if(WITH_PROJ)
endif(NOT PROJ_FOUND)
endif (WITH_PROJ)

if(WITH_PIXMAN)
find_package(Pixman)
if(PIXMAN_FOUND)
include_directories(${PIXMAN_INCLUDE_DIR})
ms_link_libraries(${PIXMAN_LIBRARY})
set (USE_PIXMAN 1)
else(PIXMAN_FOUND)
report_optional_not_found(PIXMAN)
endif(PIXMAN_FOUND)
endif (WITH_PIXMAN)

if(WITH_WMS)
if(USE_PROJ)
set(USE_WMS_SVR 1)
@@ -878,6 +890,7 @@ status_optional_component("SVGCAIRO" "${USE_SVG_CAIRO}" "${SVGCAIRO_LIBRARY}")
status_optional_component("RSVG" "${USE_RSVG}" "${RSVG_LIBRARY}")
status_optional_component("CURL" "${USE_CURL}" "${CURL_LIBRARY}")
status_optional_component("PROJ" "${USE_PROJ}" "${PROJ_LIBRARY}")
status_optional_component("PIXMAN" "${USE_PIXMAN}" "${PIXMAN_LIBRARY}")
status_optional_component("LIBXML2" "${USE_LIBXML2}" "${LIBXML2_LIBRARY}")
status_optional_component("POSTGIS" "${USE_POSTGIS}" "${POSTGRESQL_LIBRARY}")
status_optional_component("GEOS" "${USE_GEOS}" "${GEOS_LIBRARY}")
@@ -0,0 +1,25 @@
FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(PC_PIXMAN pixman)
if(NOT PC_PIXMAN_FOUND)
PKG_CHECK_MODULES(PC_PIXMAN pixman-1)
endif(NOT PC_PIXMAN_FOUND)


FIND_PATH(PIXMAN_INCLUDE_DIR
NAMES pixman.h
HINTS ${PC_PIXMAN_INCLUDEDIR}
${PC_PIXMAN_INCLUDE_DIR}
PATH_SUFFIXES pixman pixman-1
)

FIND_LIBRARY(PIXMAN_LIBRARY
NAMES pixman pixman-1
HINTS ${PC_PIXMAN_LIBDIR}
${PC_PIXMAN_LIBRARY_DIRS}
)

set(PIXMAN_INCLUDE_DIRS ${PIXMAN_INCLUDE_DIR})
set(PIXMAN_LIBRARIES ${PIXMAN_LIBRARY})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PIXMAN DEFAULT_MSG PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
mark_as_advanced(PIXMAN_LIBRARY PIXMAN_INCLUDE_DIR)
@@ -42,16 +42,15 @@
#include "renderers/agg/include/agg_span_pattern_rgba.h"
#include "renderers/agg/include/agg_span_allocator.h"
#include "renderers/agg/include/agg_span_interpolator_linear.h"
#include "renderers/agg/include/agg_span_image_filter_rgba.h"
#include "renderers/agg/include/agg_pattern_filters_rgba.h"
#include "renderers/agg/include/agg_span_image_filter_rgb.h"
#include "renderers/agg/include/agg_image_accessors.h"
#include "renderers/agg/include/agg_conv_stroke.h"
#include "renderers/agg/include/agg_conv_dash.h"
#include "renderers/agg/include/agg_font_freetype.h"
#include "renderers/agg/include/agg_conv_contour.h"
#include "renderers/agg/include/agg_ellipse.h"
#include "renderers/agg/include/agg_gamma_functions.h"
#include "renderers/agg/include/agg_blur.h"

#include "renderers/agg/include/agg_rasterizer_outline_aa.h"
#include "renderers/agg/include/agg_renderer_outline_aa.h"
@@ -64,6 +63,10 @@

#include "renderers/agg/include/agg_conv_clipper.h"

#ifdef USE_PIXMAN
#include <pixman.h>
#endif

#ifdef AGG_ALIASED_ENABLED
#include "renderers/agg/include/agg_renderer_primitives.h"
#include "renderers/agg/include/agg_rasterizer_outline.h"
@@ -78,10 +81,13 @@ typedef mapserver::rgba8 color_type;
typedef mapserver::pixel32_type pixel_type;

typedef mapserver::blender_rgba_pre<color_type, band_order> blender_pre;
typedef mapserver::comp_op_adaptor_rgba_pre<color_type, band_order> compop_blender_pre;

typedef mapserver::pixfmt_alpha_blend_rgba<blender_pre, mapserver::rendering_buffer, pixel_type> pixel_format;
typedef mapserver::pixfmt_custom_blend_rgba<compop_blender_pre, mapserver::rendering_buffer> compop_pixel_format;
typedef mapserver::rendering_buffer rendering_buffer;
typedef mapserver::renderer_base<pixel_format> renderer_base;
typedef mapserver::renderer_base<compop_pixel_format> compop_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;
@@ -136,7 +142,9 @@ class AGG2Renderer
band_type* buffer;
rendering_buffer m_rendering_buffer;
pixel_format m_pixel_format;
compop_pixel_format m_compop_pixel_format;
renderer_base m_renderer_base;
compop_renderer_base m_compop_renderer_base;
renderer_scanline m_renderer_scanline;
#ifdef AGG_ALIASED_ENABLED
renderer_primitives m_renderer_primitives;
@@ -826,7 +834,9 @@ imageObj *agg2CreateImage(int width, int height, outputFormatObj *format, colorO
}
r->m_rendering_buffer.attach(r->buffer, width, height, width * 4);
r->m_pixel_format.attach(r->m_rendering_buffer);
r->m_compop_pixel_format.attach(r->m_rendering_buffer);
r->m_renderer_base.attach(r->m_pixel_format);
r->m_compop_renderer_base.attach(r->m_compop_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) {
@@ -1119,7 +1129,7 @@ int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width,


if(patternlength>1) {
//dash the hatch and render it clipped by the shape
//dash the color-hatch and render it clipped by the shape
mapserver::conv_dash<mapserver::path_storage > dash(hatch);
mapserver::conv_stroke<mapserver::conv_dash<mapserver::path_storage> > stroke(dash);
for (int i=0; i<patternlength; i+=2) {
@@ -1146,10 +1156,194 @@ int msHatchPolygon(imageObj *img, shapeObj *poly, double spacing, double width,
return MS_SUCCESS;
}

#ifdef USE_PIXMAN
static pixman_op_t ms2pixman_compop(CompositingOperation c) {
switch(c) {
case MS_COMPOP_CLEAR:
return PIXMAN_OP_CLEAR;
case MS_COMPOP_SRC:
return PIXMAN_OP_SRC;
case MS_COMPOP_DST:
return PIXMAN_OP_DST;
case MS_COMPOP_SRC_OVER:
return PIXMAN_OP_OVER;
case MS_COMPOP_DST_OVER:
return PIXMAN_OP_OVER_REVERSE;
case MS_COMPOP_SRC_IN:
return PIXMAN_OP_IN;
case MS_COMPOP_DST_IN:
return PIXMAN_OP_IN_REVERSE;
case MS_COMPOP_SRC_OUT:
return PIXMAN_OP_OUT;
case MS_COMPOP_DST_OUT:
return PIXMAN_OP_OUT_REVERSE;
case MS_COMPOP_SRC_ATOP:
return PIXMAN_OP_ATOP;
case MS_COMPOP_DST_ATOP:
return PIXMAN_OP_ATOP_REVERSE;
case MS_COMPOP_XOR:
return PIXMAN_OP_XOR;
case MS_COMPOP_PLUS:
return PIXMAN_OP_ADD;
case MS_COMPOP_MULTIPLY:
return PIXMAN_OP_MULTIPLY;
case MS_COMPOP_SCREEN:
return PIXMAN_OP_SCREEN;
case MS_COMPOP_OVERLAY:
return PIXMAN_OP_OVERLAY;
case MS_COMPOP_DARKEN:
return PIXMAN_OP_DARKEN;
case MS_COMPOP_LIGHTEN:
return PIXMAN_OP_LIGHTEN;
case MS_COMPOP_COLOR_DODGE:
return PIXMAN_OP_COLOR_DODGE;
case MS_COMPOP_COLOR_BURN:
return PIXMAN_OP_COLOR_DODGE;
case MS_COMPOP_HARD_LIGHT:
return PIXMAN_OP_HARD_LIGHT;
case MS_COMPOP_SOFT_LIGHT:
return PIXMAN_OP_SOFT_LIGHT;
case MS_COMPOP_DIFFERENCE:
return PIXMAN_OP_DIFFERENCE;
case MS_COMPOP_EXCLUSION:
return PIXMAN_OP_EXCLUSION;
case MS_COMPOP_INVERT:
case MS_COMPOP_INVERT_RGB:
case MS_COMPOP_MINUS:
case MS_COMPOP_CONTRAST:
default:
return PIXMAN_OP_OVER;
}
}
#else
static mapserver::comp_op_e ms2agg_compop(CompositingOperation c) {
switch(c) {
case MS_COMPOP_CLEAR:
return mapserver::comp_op_clear;
case MS_COMPOP_SRC:
return mapserver::comp_op_src;
case MS_COMPOP_DST:
return mapserver::comp_op_dst;
case MS_COMPOP_SRC_OVER:
return mapserver::comp_op_src_over;
case MS_COMPOP_DST_OVER:
return mapserver::comp_op_dst_over;
case MS_COMPOP_SRC_IN:
return mapserver::comp_op_src_in;
case MS_COMPOP_DST_IN:
return mapserver::comp_op_dst_in;
case MS_COMPOP_SRC_OUT:
return mapserver::comp_op_src_out;
case MS_COMPOP_DST_OUT:
return mapserver::comp_op_dst_out;
case MS_COMPOP_SRC_ATOP:
return mapserver::comp_op_src_atop;
case MS_COMPOP_DST_ATOP:
return mapserver::comp_op_dst_atop;
case MS_COMPOP_XOR:
return mapserver::comp_op_xor;
case MS_COMPOP_PLUS:
return mapserver::comp_op_plus;
case MS_COMPOP_MINUS:
return mapserver::comp_op_minus;
case MS_COMPOP_MULTIPLY:
return mapserver::comp_op_multiply;
case MS_COMPOP_SCREEN:
return mapserver::comp_op_screen;
case MS_COMPOP_OVERLAY:
return mapserver::comp_op_overlay;
case MS_COMPOP_DARKEN:
return mapserver::comp_op_darken;
case MS_COMPOP_LIGHTEN:
return mapserver::comp_op_lighten;
case MS_COMPOP_COLOR_DODGE:
return mapserver::comp_op_color_dodge;
case MS_COMPOP_COLOR_BURN:
return mapserver::comp_op_color_burn;
case MS_COMPOP_HARD_LIGHT:
return mapserver::comp_op_hard_light;
case MS_COMPOP_SOFT_LIGHT:
return mapserver::comp_op_soft_light;
case MS_COMPOP_DIFFERENCE:
return mapserver::comp_op_difference;
case MS_COMPOP_EXCLUSION:
return mapserver::comp_op_exclusion;
case MS_COMPOP_CONTRAST:
return mapserver::comp_op_contrast;
case MS_COMPOP_INVERT:
return mapserver::comp_op_invert;
case MS_COMPOP_INVERT_RGB:
return mapserver::comp_op_invert_rgb;
default:
return mapserver::comp_op_src_over;
}
}
#endif

int aggCompositeRasterBuffer(imageObj *dest, rasterBufferObj *overlay, CompositingOperation comp, int opacity) {
assert(overlay->type == MS_BUFFER_BYTE_RGBA);
AGG2Renderer *r = AGG_RENDERER(dest);
#ifdef USE_PIXMAN
pixman_image_t *si = pixman_image_create_bits(PIXMAN_a8r8g8b8,overlay->width,overlay->height,
(uint32_t*)overlay->data.rgba.pixels,overlay->data.rgba.row_step);
pixman_image_t *bi = pixman_image_create_bits(PIXMAN_a8r8g8b8,dest->width,dest->height,
(uint32_t*)r->buffer,dest->width*4);
pixman_image_t *alpha_mask_i=NULL, *alpha_mask_i_ptr;
pixman_image_set_filter(si,PIXMAN_FILTER_NEAREST, NULL, 0);
unsigned char *alpha_mask = NULL;
if(opacity > 0) {
if(opacity == 100) {
alpha_mask_i_ptr = NULL;
} else {
unsigned char alpha = (unsigned char)(opacity * 2.55);
if(!alpha_mask_i) {
alpha_mask = (unsigned char*)msSmallMalloc(dest->width * dest->height);
alpha_mask_i = pixman_image_create_bits(PIXMAN_a8,dest->width,dest->height,
(uint32_t*)alpha_mask,dest->width);
}
memset(alpha_mask,alpha,dest->width*dest->height);
alpha_mask_i_ptr = alpha_mask_i;
}
pixman_image_composite (ms2pixman_compop(comp), si, alpha_mask_i_ptr, bi,
0, 0, 0, 0, 0, 0, dest->width,dest->height);
}
pixman_image_unref(si);
pixman_image_unref(bi);
if(alpha_mask_i) {
pixman_image_unref(alpha_mask_i);
msFree(alpha_mask);
}
return MS_SUCCESS;
#else
rendering_buffer b(overlay->data.rgba.pixels, overlay->width, overlay->height, overlay->data.rgba.row_step);
pixel_format pf(b);
mapserver::comp_op_e comp_op = ms2agg_compop(comp);
if(comp == mapserver::comp_op_src_over) {
r->m_renderer_base.blend_from(pf,0,0,0,unsigned(opacity * 2.55));
} else {
compop_pixel_format pixf(r->m_rendering_buffer);
compop_renderer_base ren(pixf);
pixf.comp_op(comp_op);
ren.blend_from(pf,0,0,0,unsigned(opacity * 2.55));
}
return MS_SUCCESS;
#endif
}

rasterBufferObj* msApplyFilterToRasterBuffer(const rasterBufferObj *rb, CompositingFilter *filter) {
rasterBufferObj *rbret = (rasterBufferObj*)msSmallCalloc(sizeof(rasterBufferObj),1);
msCopyRasterBuffer(rbret,rb);
rendering_buffer b(rbret->data.rgba.pixels, rbret->width, rbret->height, rbret->data.rgba.row_step);
pixel_format pf(b);
/* for now, we only support a blurring filter */
int radius = atoi(filter->filter);
mapserver::stack_blur_rgba32(pf,radius,radius);
return rbret;
}

int msPopulateRendererVTableAGG(rendererVTableObj * renderer)
{
renderer->supports_transparent_layers = 0;
renderer->compositeRasterBuffer = &aggCompositeRasterBuffer;
renderer->supports_pixel_buffer = 1;
renderer->use_imagecache = 0;
renderer->supports_clipping = 0;

0 comments on commit 29db335

Please sign in to comment.
You can’t perform that action at this time.