[mapserver-commits] r8900 - trunk/docs/development/rfc
svn at osgeo.org
svn at osgeo.org
Sat Apr 11 04:56:51 EDT 2009
Author: tbonfort
Date: 2009-04-11 04:56:50 -0400 (Sat, 11 Apr 2009)
New Revision: 8900
Modified:
trunk/docs/development/rfc/ms-rfc-54.txt
Log:
update
Modified: trunk/docs/development/rfc/ms-rfc-54.txt
===================================================================
--- trunk/docs/development/rfc/ms-rfc-54.txt 2009-04-10 19:09:07 UTC (rev 8899)
+++ trunk/docs/development/rfc/ms-rfc-54.txt 2009-04-11 08:56:50 UTC (rev 8900)
@@ -37,7 +37,13 @@
SVG renderers could be phased out and replaced by the ones natively provided by
cairo.
+.. note::
+ While the current GD renderer could be ported to the API architecture, it
+ probably isn't something we want to do as we would be losing some
+ performance induced by the switching from GD's internal pixel representation
+ to the generic one used by this API.
+
Low Level Rendering API
--------------------------------------------------------------------------------
@@ -49,7 +55,8 @@
Adding a new output driver to mapserver therefore consists in two steps:
-- implementing the low-level rendering functions
+- implementing the low-level rendering functions (depending on the renderer's
+ capabilities and configuration options, not all functions need be implemented)
- creating and registering a new outputformat driver, by making the
renderObj function pointers point to the low-level functions
@@ -99,11 +106,17 @@
imageObj* (*createImage)(int width, int height, outputFormatObj *format,
colorObj* bg);
+.. note::
+
+ Renderer specific creation options would be extracted by each renderer from the
+ outputFormatObj passed to it. (This would be used eg by the PDF renderer for page
+ layout options).
+
Raster Handling Functions
==========================
Raster handling will follow different code paths depending on wether the
-underlying renderer is already natively a raster renderer (eg. GD, AGG) , or if
+underlying renderer is already natively a raster renderer (eg. PNG, JPEG) , or if
it is a vector one (eg. PDF, SVG).
Raster Buffer Structure
@@ -114,8 +127,10 @@
.. code-block:: c
- typedef struct { unsigned int width,height;
+ typedef struct {
+ unsigned int width,height;
+
// pointers to the start of each band in the pixel buffer
unsigned char *a,*r,*g,*b;
@@ -127,10 +142,22 @@
// pointer to the actual pixels (should not be used by the high-level
// code)
+ // TODO: as this memeber is actually private, it should probably be
+ // a void* so that any internal representation can be used
unsigned char *pixelbuffer;
} rasterBufferObj;
+A renderer must provide a function to initialize a rasterBuffer where the pixel
+alignment and the order of the bands best fits its internal representation of a
+raster array.
+
+.. code-block:: c
+
+ void (*initializeRasterBuffer)(rasterBufferObj *buffer, int width, int height);
+
+
+
Handling Raster Layers
~~~~~~~~~~~~~~~~~~~~~~~
@@ -148,13 +175,13 @@
void (*getRasterBuffer)(imageObj *img,rasterBufferObj *rb);
- if the renderer does not use an internal representation that can be
- directly filled by the raster layer code, it must provide a function that
- should merge a given rasterBufferObj:
+ directly filled by the raster layer code, it must provide two functions
+ that will allow the higher level code to merge the created raster:
.. code-block:: c
-
+
void (*mergeRasterBuffer)(imageObj *dest, rasterBufferObj *overlay,
- double opacity, int dstX, int dstY)
+ double opacity, int dstX, int dstY)
@@ -292,6 +319,10 @@
void (*freeSymbol)(symbolObj *symbol);
void (*freeShape)(shapeObj *shape);
+.. note::
+ The freeSymbol and freeShape functions are added here as we will be adding a void*
+ pointer to the symbolObj and shapeObj objects where a renderer can store a private
+ cache containing an implementation specific representation of the object.
High Level Usage of the rendering API
@@ -308,26 +339,92 @@
Depending on whether the renderer can export a raster buffer or not:
- supported: get a raster buffer, eventually apply formatoptions (quantization)
- and pass the buffer to the newly created saving functions
+ and pass the buffer to the MapServer's saving functions
- unsupported: call the renderer's saving function
-Line Drawing
-=============
+Raster Layers
+==============
+MapServer's Raster layer handling will be modified so that it can write to a
+rasterBufferObj and not only to a gdImage.
+
+.. note::
+
+ TODO (FrankW) add some detail here about the changes induced here
+
+.. code-block:: c
+
+ if(renderer->supports_pixel_buffer) {
+ rasterBufferObj buffer;
+ renderer->getRasterBuffer(img,&buffer);
+ msDrawRasterLayer(map,layer,&buffer);
+ }
+ else {
+ rasterBufferObj buffer;
+ renderer->initializeRasterBuffer(&buffer,width,height);
+ msDrawRasterLayer(map,layer,&buffer);
+ renderer->mergeRasterBuffer(img,&buffer,0,0);
+ renderer->freeRasterBuffer(&buffer);
+ }
+
+Symbol Cache and Marker Rendering
+==================================
+
+A symbol cache similar to the actual mapgd.c imagecache will be implemented in
+mapimagecache.c .
+
+.. note::
+
+ As pointed out earlier, it is yet to be decided if the cache will store
+ plain imageOjbs or if we allow renderers to store a specific structure.
+ This could also be a configuration option, with each renderer specifying if
+ it can treat it's own created imageObj as a cache, or if it needs a void*
+ cache. This would keep the code simple for most renderers, while allowing
+ more flexibility for others (the openGL renderer will probably be needing
+ this)
+
+The use of an image cache would be configurable by each renderer via the
+supports_imagecache configuration option, as its use isn't necessarily useful
+depending on the format.
+
+.. code-block:: c
+
+ if(renderer->supports_imagecache) {
+ // this function looks in the global image cache if it finds a tile
+ // corresponding to the current symbol and styling and returns it. If
+ // it wasn't found, it calls the renderer functions to create a new
+ // cache tile and adds it to the global cache.
+ imageObj *tile = getTile(img, symbol, symbolstyle);
+ renderer->renderTile(img, tile, x, y);
+ }
+ else {
+ switch(symbol->type) {
+ case VECTOR:
+ renderer->renderVectorSymbol(img, params...);
+ break;
+ case ELLIPSE:
+ /* ... */
+ }
+ }
+
+Line Rendering
+===============
+
- simple stroke: call the renderer directly
- marker symbols:
- compute positions and orientations along the geometry
- - render a marker symbol with the renderer's marker functions for each of these positions. It probably isn't a good idea
- to use a tile cache if the symbols have to follow line orientation, as rotating
- a cached tile will produce poor results.
+ - render a marker symbol with the renderer's marker functions for each of
+ these positions. It probably isn't a good idea to use a tile cache if the
+ symbols have to follow line orientation, as rotating a cached tile will
+ produce poor results.
- pattern:
- create the pattern's tile (with the renderer's marker functions)
- pass the tile to the renderer
-Polygon drawing
-================
+Polygon Rendering
+==================
- simple fill
- pattern fill:
@@ -340,15 +437,110 @@
- compute the lines corresponding to the hatch
- use the renderer's simple stroking function
-Marker symbol rendering
-========================
+Text Rendering
+===============
-- with cache
-- without cache
+Nothing special to add here, except that the basic preliminary tests (if the
+font is defined, or if the string to render is NULL) and the lookup of the
+system path of the truetype font file will be done once by the high level code
+before calling the renderer drawing function.
+.. note::
+ Raster fonts will not be supported (at least in a first phase) by this
+ rendering API. Only truetype fonts are implemented.
+Image I/O
+--------------------------------------------------------------------------------
+Currently all image I/O is done through the GD library. To raise this dependency,
+the RFC proposes to have mapserver implement image loading and saving by directly
+interfacing the libpng / libjpeg / giflib libraries. The corresponding code will
+be added to a new file "mapimageio.c", and will produce or read rasterBufferObj's.
+These functions will implement the formatoptions that are currently supported.
+Adding new formatoptions would be done by adding the code to these i/o functions,
+and would thus add the support for all the renderers that use this rendering API
+architecture:
+
+- jpeg:
+
+ - quality: 0 - 100
+- png:
+
+ - interlacing: will be set to OFF by default, as the creation is costlier,
+ produces heavier images, and is incompatible with TileCache's
+ metatiling functionality.
+ - compression: could be added to select the quality of zlib compression
+ - quantization: produce palette-based pngs from rgb or rgba imagemodes.
+ - palette: produce palette-based pngs given a precomputed palette. Further
+ enhancements could include automatically producing a palette by looping
+ through the input mapfile to extract the colors and ensure they end up
+ in the final image (this would only be supported for RGB, not RGBA)
+- gif: TBD
+
+.. note::
+
+ The initial implementation of this RFC will not include support for writing
+ GIF images.
+
+.. note::
+
+ The initial implementation of this RFC will not include image loading functions
+ by direct usage of the libjpeg/libpng/giflib libraries. It will instead fallback
+ to GD loading and convert the created gdImage to a rasterBuffer. This can be added
+ in a second phase as it is lower priority, and does not induce a major architectural
+ change.
+
+Miscelaneous
+--------------------------------------------------------------------------------
+
+Drawing some layers as rasters in vector renderers
+===================================================
+
+The current pdf (and SVG?) renderers have the option of switching over to GD for
+some layers, that are then incorporated as a raster image in the final map rather
+than adding each feature in the usual way.
+
+This functionality could probably be kept with this API with the mergeRasterBuffer
+function.
+
+.. note::
+
+ A renderer using this functionality will have to take care as the rasterBuffer
+ that it will be passed will be in the native format of the delegated renderer,
+ and may not be in the exact same format it would have created with a call to
+ initializeRasterBuffer.
+
+Legend
+=======
+
+The legend rendering code will have to be refactored, as it currently produces a
+gdImage. Legend rendering will be handled like a normal imageObj.
+
+.. note::
+
+ TODO: "embed" mode is problematic.
+
+ If postlabelcache is on, then the created
+ imageObj can easily be added to the main image using the renderTile function
+ (for the renderers that support it. the others will probably have noe embedded
+ legend support)
+
+ If postlabelcache is off we have a problem, as the created legend is passed as
+ a pixmap symbol to the main map rendering. This is incompatible with the vector
+ renderers, as the imageObj they have created isn't an array of pixels.
+
+Scalebar
+=========
+
+TBD
+
+Reference Map
+==============
+
+TBD. Should we even still be supporting this ?
+
+
Affected Files
--------------------------------------------------------------------------------
- maprendering.c , mapimageio.c, mapcairo.c (added)
Property changes on: trunk/docs/development/rfc/ms-rfc-54.txt
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Rev URL
More information about the mapserver-commits
mailing list