Skip to content

Text Rendering Overview

Hermann Kraus edited this page Oct 10, 2013 · 17 revisions
Clone this wiki locally


This page aims to give an explanation of how all the parts in rendering a TextSymbolizer play together. Only important functions and members are documented here.

Visual representation

  • Black: Class dependencies
  • Dashed: Pointers
  • Solid: Members
  • Red: Rendering dependencies



As its only property contains a pointer to a text_placements object.


(Abstract class) This object handles the management of all TextSymbolizer properties. It can be used as a base class for own objects which implement new processing semantics. Basically this class just makes sure a pointer of the right class is returned by the get_placement_info call.


  • get_placement_info: (Abstract function) Get a text_ placement_info object to use in rendering. The returned object creates a list of settings which is used to try to find a placement and stores all information that is generated by the placement finder.

This function usually is implemented as ```text_placement_info_ptr text_placements_XXX::get_placement_info() const { return text_placement_info_ptr(new text_placement_info_XXX(this)); }

* ```get_all_expressions```: Get a list of all expressions used in any placement. This function is used to collect attributes.

## Members
All properties are grouped into a class ```text_symbolizer_properties``` accessible via public member ```properties```. They are used by subclasses as their default settings.

## Implemented subclasses
* text_placements_dummy Always takes the default value.
* text_placement_simple Parse a simple string and created placement based on this string.
* text_placement_list Take placements from a list

# text_placement_list
_(Abstract class)_
Generate a possible placement and store results of placement_finder. This placement has first to be tested by placement_finder to verify it can actually be used.

## Functions
* Constructor: Takes the parent text_placements object as a parameter to read defaults from it.
* ```next```: _(Abstact function)_ Get next placement. This function is also called before the first placement is tried.
* ```init```: Initialize values used by placement finder. These values are provided by the renderer and can't be derived from TextSymbolizer properties.

## Members:
* ```properties```: Properties actually used by placement finder and renderer. Values in here are modified each time next() is called.
* ```placements```: List of ```text_path```s returned by placement finder. One for each placement. 
* Some values from the renderer.
* Values returned by placement_finder.

# text_path
List of all characters and their positions and formats for a placement. Produced by placement_finder, consumed by the renderer.

# char_properties
Contains all text symbolizer properties which _are_ directly related to text formating.

## Functions
* ```set_values_from_xml```: Load all values and also the ```processor``` object from XML ptree.
* ```to_xml```: Save all values to XML ptree (but does not create a new parent node!).

# text_symbolizer_properties
Contains all text symbolizer properties. Also stores formating information and uses this to produce formated text for a given feature.

## Members
* ```tree_``` (```format_tree()/set_format_tree()```): A tree of ``formating::node``s which contain text and formating information

## Functions
* ```from_xml```: Load all values and also the ```processor``` object from XML ptree.
* ```to_xml```: Save all values to XML ptree (but does not create a new parent node!).
* ```get_all_expressions```: Get a list of all expressions used in any placement. This function is used to collect attributes.
* ```process```: Takes a feature and produces formated text as output. The output ```processed_text``` object has to be created by the caller and passed in for thread safety.

# Rendering in harfbuzz branch
## Renderer code 
Delegates all processing to ```text_symbolizer_helper``` to avoid code duplication in individual renderers. Gets a list of glyphs and their positions. Doesn't have to care about i18n in any way.

Shield symbolizer: Uses ```shield_symbolizer_helper``` and renders shield in addition to text.
## text_symbolizer_helper
Selects starting points for ```placement_finder```. 

Calls ```placement_finder.next_position``` and then repeatedly ```placement_finder.find_point_placement``` or ```placement_finder.find_line_placements```. If there wasn't a placement for every geometry is calls ```next_position``` again to find alternate positions or styles that work. Repeats this process till either ```next_position``` returns false or no unlabeled points remain. 

Shield symbolizer: Calculates bounding box and disables text along line.

No i18n required.
## placement_finder
### next_position
Selects the next style in the ```text_placement_info``` list. Processes the feature into a list of texts with associated styles stored in a text_layout by calling ```text_layout.add_text```. Then it calls ```text_layout.layout``` which updates metrics of the ```text_layout``` objects and converts the text into a list of glyphs. These glyphs are always in left to right order so no special care has to be taken while processing them. **If you are trying to add i18n code to ```placement_finder``` you are doing it wrong!**
Something went wrong with that request. Please try again.