=========================================================
MS RFC 11: Support for Curved Labels
=========================================================

:Date:  2006/02/09
:Author: Benj Carson
:Contact: benjcarson@digitaljunkies.ca
:Author: Stephen Lime
:Contact: sdlime@comcast.net
:Status: passed

Overview
--------

One of the features most frequently asked for are labels that follow 
along linear features. This RFC describes an initial implementation 
of this feature.

Technical Details
-----------------

The proposed solution has a couple of primary goals:

  * isolate virtually all computations and data storage into a minimum 
    number of functions and structures.
  * integrates easily into the existing labelCacheObj structure and 
    label cache processing routines.

A single, new function- msPolylineLabelPath() serves as the sole computational 
function for this new functionality. Like the existing msPolylineLabelPoint() 
function it takes an input feature and annotation string and computes a 
labeling position.  However, instead of computing a single point (and 
optionally, angle) it computes a label point and angle for each character 
in the annotation string.  The computation results are returned in a new 
structure called a "labelPathObj" that looks like:

::

  typedef struct {
    multipointObj path;
    shapeObj bounds;
    double *angles;
  } labelPathObj;
 
The function will return NULL if a curved label is not appropriate for 
the feature in question so traditional labeling can take place (for 
example, if the feature has only 2 points a curved label is not necessary).  
The curved label's bounding polygon will be calculated in this function 
as well and stored in the "bounds" member of the labelPathObj structure.

In order to get the labelPathObj into the label cache it will be necessary 
to do 2 things:

  * extend labelCacheMemberObj to optionally reference a labelPathObj
  * extend the function msAddLabel to take a labelPathObj in addition 
    to the parameters it already accepts

Since each labelPathObj will contain the boundary for the curved label, 
it will be ready to use with the existing label cache rendering code.

The only addition to the label cache rendering is code to detect when 
a text path should be rendered instead of a traditional label. Driver 
specific code to render a text path will have to be written but in 
general this is trivial and just involves calling the normal text 
rendering code once for each character in the path.

Mapfile Implications
--------------------

It is proposed that we simply extend the labelObj ANGLE parameter. 
Currently it takes an angle (given in degrees) or the keyword AUTO. 
We suggest adding support for the keyword FOLLOW. This would set a new 
labelObj member, anglefollow, to MS_TRUE (and also angleauto to MS_TRUE 
as ANGLE FOLLOW implies ANGLE AUTO if a curved label is not appropriate).

Support for Non-GD Renderers
----------------------------

Presently all MapServer output renders use the contents of the label 
cache, which is basically render agnostic. This will not be the case 
any more. The placement computations necessary to support curved labels 
do leverage font metrics derived from the GD/Freetype interface. It may 
well be possible for the SWF, PDF and SVG renders to leverage even the 
GD-based curved labels, however it is probably best to consider this a 
raster-only output feature in this implementation.  If font metrics 
support for other renderers is developed in the future then this feature 
can be easily extended to support them.

Bug Tracking
------------

Bug 1620 has be setup to track this feature addition.

Voting History
--------------

+1: Lime, Assefa, Nacionales, Warmerdam, Morissette

