##// END OF EJS Templates
fixed win32 build
fixed win32 build

File last commit:

r0:1aa783210b8e default
r8:ee188276b590 default
Show More
qcustomplot.cpp
18937 lines | 651.8 KiB | text/x-c | CppLexer
/***************************************************************************
** **
** QCustomPlot, an easy to use, modern plotting widget for Qt **
** Copyright (C) 2011, 2012, 2013 Emanuel Eichhammer **
** **
** This program is free software: you can redistribute it and/or modify **
** it under the terms of the GNU General Public License as published by **
** the Free Software Foundation, either version 3 of the License, or **
** (at your option) any later version. **
** **
** This program is distributed in the hope that it will be useful, **
** but WITHOUT ANY WARRANTY; without even the implied warranty of **
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the **
** GNU General Public License for more details. **
** **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see http://www.gnu.org/licenses/. **
** **
****************************************************************************
** Author: Emanuel Eichhammer **
** Website/Contact: http://www.qcustomplot.com/ **
** Date: 09.12.13 **
** Version: 1.1.1 **
****************************************************************************/
#include "qcustomplot.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// QCPPainter
////////////////////////////////////////////////////////////////////////////////////////////////////
/*! \class QCPPainter
\brief QPainter subclass used internally
This internal class is used to provide some extended functionality e.g. for tweaking position
consistency between antialiased and non-antialiased painting. Further it provides workarounds
for QPainter quirks.
\warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and
restore. So while it is possible to pass a QCPPainter instance to a function that expects a
QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because
it will call the base class implementations of the functions actually hidden by QCPPainter).
*/
/*!
Creates a new QCPPainter instance and sets default values
*/
QCPPainter::QCPPainter() :
QPainter(),
mModes(pmDefault),
mIsAntialiasing(false)
{
// don't setRenderHint(QPainter::NonCosmeticDefautPen) here, because painter isn't active yet and
// a call to begin() will follow
}
/*!
Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just
like the analogous QPainter constructor, begins painting on \a device immediately.
Like \ref begin, this method sets QPainter::NonCosmeticDefaultPen in Qt versions before Qt5.
*/
QCPPainter::QCPPainter(QPaintDevice *device) :
QPainter(device),
mModes(pmDefault),
mIsAntialiasing(false)
{
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions.
if (isActive())
setRenderHint(QPainter::NonCosmeticDefaultPen);
#endif
}
QCPPainter::~QCPPainter()
{
}
/*!
Sets the pen of the painter and applies certain fixes to it, depending on the mode of this
QCPPainter.
\note this function hides the non-virtual base class implementation.
*/
void QCPPainter::setPen(const QPen &pen)
{
QPainter::setPen(pen);
if (mModes.testFlag(pmNonCosmetic))
makeNonCosmetic();
}
/*! \overload
Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of
this QCPPainter.
\note this function hides the non-virtual base class implementation.
*/
void QCPPainter::setPen(const QColor &color)
{
QPainter::setPen(color);
if (mModes.testFlag(pmNonCosmetic))
makeNonCosmetic();
}
/*! \overload
Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of
this QCPPainter.
\note this function hides the non-virtual base class implementation.
*/
void QCPPainter::setPen(Qt::PenStyle penStyle)
{
QPainter::setPen(penStyle);
if (mModes.testFlag(pmNonCosmetic))
makeNonCosmetic();
}
/*! \overload
Works around a Qt bug introduced with Qt 4.8 which makes drawing QLineF unpredictable when
antialiasing is disabled. Thus when antialiasing is disabled, it rounds the \a line to
integer coordinates and then passes it to the original drawLine.
\note this function hides the non-virtual base class implementation.
*/
void QCPPainter::drawLine(const QLineF &line)
{
if (mIsAntialiasing || mModes.testFlag(pmVectorized))
QPainter::drawLine(line);
else
QPainter::drawLine(line.toLine());
}
/*!
Sets whether painting uses antialiasing or not. Use this method instead of using setRenderHint
with QPainter::Antialiasing directly, as it allows QCPPainter to regain pixel exactness between
antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for
AA/Non-AA painting).
*/
void QCPPainter::setAntialiasing(bool enabled)
{
setRenderHint(QPainter::Antialiasing, enabled);
if (mIsAntialiasing != enabled)
{
mIsAntialiasing = enabled;
if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs
{
if (mIsAntialiasing)
translate(0.5, 0.5);
else
translate(-0.5, -0.5);
}
}
}
/*!
Sets the mode of the painter. This controls whether the painter shall adjust its
fixes/workarounds optimized for certain output devices.
*/
void QCPPainter::setModes(QCPPainter::PainterModes modes)
{
mModes = modes;
}
/*!
Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a
device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5,
all pens are non-cosmetic by default, and in Qt4 this render hint must be set to get that
behaviour.
The Constructor \ref QCPPainter(QPaintDevice *device) which directly starts painting also sets
the render hint as appropriate.
\note this function hides the non-virtual base class implementation.
*/
bool QCPPainter::begin(QPaintDevice *device)
{
bool result = QPainter::begin(device);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions.
if (result)
setRenderHint(QPainter::NonCosmeticDefaultPen);
#endif
return result;
}
/*! \overload
Sets the mode of the painter. This controls whether the painter shall adjust its
fixes/workarounds optimized for certain output devices.
*/
void QCPPainter::setMode(QCPPainter::PainterMode mode, bool enabled)
{
if (!enabled && mModes.testFlag(mode))
mModes &= ~mode;
else if (enabled && !mModes.testFlag(mode))
mModes |= mode;
}
/*!
Saves the painter (see QPainter::save). Since QCPPainter adds some new internal state to
QPainter, the save/restore functions are reimplemented to also save/restore those members.
\note this function hides the non-virtual base class implementation.
\see restore
*/
void QCPPainter::save()
{
mAntialiasingStack.push(mIsAntialiasing);
QPainter::save();
}
/*!
Restores the painter (see QPainter::restore). Since QCPPainter adds some new internal state to
QPainter, the save/restore functions are reimplemented to also save/restore those members.
\note this function hides the non-virtual base class implementation.
\see save
*/
void QCPPainter::restore()
{
if (!mAntialiasingStack.isEmpty())
mIsAntialiasing = mAntialiasingStack.pop();
else
qDebug() << Q_FUNC_INFO << "Unbalanced save/restore";
QPainter::restore();
}
/*!
Changes the pen width to 1 if it currently is 0. This function is called in the \ref setPen
overrides when the \ref pmNonCosmetic mode is set.
*/
void QCPPainter::makeNonCosmetic()
{
if (qFuzzyIsNull(pen().widthF()))
{
QPen p = pen();
p.setWidth(1);
QPainter::setPen(p);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// QCPScatterStyle
////////////////////////////////////////////////////////////////////////////////////////////////////
/*! \class QCPScatterStyle
\brief Represents the visual appearance of scatter points
This class holds information about shape, color and size of scatter points. In plottables like
QCPGraph it is used to store how scatter points shall be drawn. For example, \ref
QCPGraph::setScatterStyle takes a QCPScatterStyle instance.
A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a
fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can
be controlled with \ref setSize.
\section QCPScatterStyle-defining Specifying a scatter style
You can set all these configurations either by calling the respective functions on an instance:
\code
QCPScatterStyle myScatter;
myScatter.setShape(QCPScatterStyle::ssCircle);
myScatter.setPen(Qt::blue);
myScatter.setBrush(Qt::white);
myScatter.setSize(5);
customPlot->graph(0)->setScatterStyle(myScatter);
\endcode
Or you can use one of the various constructors that take different parameter combinations, making
it easy to specify a scatter style in a single call, like so:
\code
customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::blue, Qt::white, 5));
\endcode
\section QCPScatterStyle-undefinedpen Leaving the color/pen up to the plottable
There are two constructors which leave the pen undefined: \ref QCPScatterStyle() and \ref
QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref
isPenDefined will return false. It leads to scatter points that inherit the pen from the
plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line
color of the graph (\ref QCPGraph::setPen) will be used by the scatter points. This makes
it very convenient to set up typical scatter settings:
\code
customPlot->graph(0)->setScatterStyle(QCPScatterStyle::ssPlus);
\endcode
Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works
because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly
into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size)
constructor with a default for \a size). In those cases, C++ allows directly supplying a \ref
ScatterShape, where actually a QCPScatterStyle is expected.
\section QCPScatterStyle-custompath-and-pixmap Custom shapes and pixmaps
QCPScatterStyle supports drawing custom shapes and arbitrary pixmaps as scatter points.
For custom shapes, you can provide a QPainterPath with the desired shape to the \ref
setCustomPath function or call the constructor that takes a painter path. The scatter shape will
automatically be set to \ref ssCustom.
For pixmaps, you call \ref setPixmap with the desired QPixmap. Alternatively you can use the
constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap.
Note that \ref setSize does not influence the appearance of the pixmap.
*/
/* start documentation of inline functions */
/*! \fn bool QCPScatterStyle::isNone() const
Returns whether the scatter shape is \ref ssNone.
\see setShape
*/
/*! \fn bool QCPScatterStyle::isPenDefined() const
Returns whether a pen has been defined for this scatter style.
The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those are
\ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen is
left undefined, the scatter color will be inherited from the plottable that uses this scatter
style.
\see setPen
*/
/* end documentation of inline functions */
/*!
Creates a new QCPScatterStyle instance with size set to 6. No shape, pen or brush is defined.
Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited
from the plottable that uses this scatter style.
*/
QCPScatterStyle::QCPScatterStyle() :
mSize(6),
mShape(ssNone),
mPen(Qt::NoPen),
mBrush(Qt::NoBrush),
mPenDefined(false)
{
}
/*!
Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or
brush is defined.
Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited
from the plottable that uses this scatter style.
*/
QCPScatterStyle::QCPScatterStyle(ScatterShape shape, double size) :
mSize(size),
mShape(shape),
mPen(Qt::NoPen),
mBrush(Qt::NoBrush),
mPenDefined(false)
{
}
/*!
Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color,
and size to \a size. No brush is defined, i.e. the scatter point will not be filled.
*/
QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, double size) :
mSize(size),
mShape(shape),
mPen(QPen(color)),
mBrush(Qt::NoBrush),
mPenDefined(true)
{
}
/*!
Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color,
the brush color to \a fill (with a solid pattern), and size to \a size.
*/
QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) :
mSize(size),
mShape(shape),
mPen(QPen(color)),
mBrush(QBrush(fill)),
mPenDefined(true)
{
}
/*!
Creates a new QCPScatterStyle instance with shape set to \a shape, the pen set to \a pen, the
brush to \a brush, and size to \a size.
\warning In some cases it might be tempting to directly use a pen style like <tt>Qt::NoPen</tt> as \a pen
and a color like <tt>Qt::blue</tt> as \a brush. Notice however, that the corresponding call\n
<tt>QCPScatterStyle(QCPScatterShape::ssCircle, Qt::NoPen, Qt::blue, 5)</tt>\n
doesn't necessarily lead C++ to use this constructor in some cases, but might mistake
<tt>Qt::NoPen</tt> for a QColor and use the
\ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size)
constructor instead (which will lead to an unexpected look of the scatter points). To prevent
this, be more explicit with the parameter types. For example, use <tt>QBrush(Qt::blue)</tt>
instead of just <tt>Qt::blue</tt>, to clearly point out to the compiler that this constructor is
wanted.
*/
QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) :
mSize(size),
mShape(shape),
mPen(pen),
mBrush(brush),
mPenDefined(pen.style() != Qt::NoPen)
{
}
/*!
Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape
is set to \ref ssPixmap.
*/
QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) :
mSize(5),
mShape(ssPixmap),
mPen(Qt::NoPen),
mBrush(Qt::NoBrush),
mPixmap(pixmap),
mPenDefined(false)
{
}
/*!
Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The
scatter shape is set to \ref ssCustom.
The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly
different meaning than for built-in scatter points: The custom path will be drawn scaled by a
factor of \a size/6.0. Since the default \a size is 6, the custom path will appear at a its
natural size by default. To double the size of the path for example, set \a size to 12.
*/
QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) :
mSize(size),
mShape(ssCustom),
mPen(pen),
mBrush(brush),
mCustomPath(customPath),
mPenDefined(false)
{
}
/*!
Sets the size (pixel diameter) of the drawn scatter points to \a size.
\see setShape
*/
void QCPScatterStyle::setSize(double size)
{
mSize = size;
}
/*!
Sets the shape to \a shape.
Note that the calls \ref setPixmap and \ref setCustomPath automatically set the shape to \ref
ssPixmap and \ref ssCustom, respectively.
\see setSize
*/
void QCPScatterStyle::setShape(QCPScatterStyle::ScatterShape shape)
{
mShape = shape;
}
/*!
Sets the pen that will be used to draw scatter points to \a pen.
If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after
a call to this function, even if \a pen is <tt>Qt::NoPen</tt>.
\see setBrush
*/
void QCPScatterStyle::setPen(const QPen &pen)
{
mPenDefined = true;
mPen = pen;
}
/*!
Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter
shapes have fillable areas. For example, \ref ssPlus does not while \ref ssCircle does.
\see setPen
*/
void QCPScatterStyle::setBrush(const QBrush &brush)
{
mBrush = brush;
}
/*!
Sets the pixmap that will be drawn as scatter point to \a pixmap.
Note that \ref setSize does not influence the appearance of the pixmap.
The scatter shape is automatically set to \ref ssPixmap.
*/
void QCPScatterStyle::setPixmap(const QPixmap &pixmap)
{
setShape(ssPixmap);
mPixmap = pixmap;
}
/*!
Sets the custom shape that will be drawn as scatter point to \a customPath.
The scatter shape is automatically set to \ref ssCustom.
*/
void QCPScatterStyle::setCustomPath(const QPainterPath &customPath)
{
setShape(ssCustom);
mCustomPath = customPath;
}
/*!
Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an
undefined pen (\ref isPenDefined), sets the pen of \a painter to \a defaultPen instead.
This function is used by plottables (or any class that wants to draw scatters) just before a
number of scatters with this style shall be drawn with the \a painter.
\see drawShape
*/
void QCPScatterStyle::applyTo(QCPPainter *painter, const QPen &defaultPen) const
{
painter->setPen(mPenDefined ? mPen : defaultPen);
painter->setBrush(mBrush);
}
/*!
Draws the scatter shape with \a painter at position \a pos.
This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be
called before scatter points are drawn with \ref drawShape.
\see applyTo
*/
void QCPScatterStyle::drawShape(QCPPainter *painter, QPointF pos) const
{
drawShape(painter, pos.x(), pos.y());
}
/*! \overload
Draws the scatter shape with \a painter at position \a x and \a y.
*/
void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const
{
double w = mSize/2.0;
switch (mShape)
{
case ssNone: break;
case ssDot:
{
painter->drawLine(QPointF(x, y), QPointF(x+0.0001, y));
break;
}
case ssCross:
{
painter->drawLine(QLineF(x-w, y-w, x+w, y+w));
painter->drawLine(QLineF(x-w, y+w, x+w, y-w));
break;
}
case ssPlus:
{
painter->drawLine(QLineF(x-w, y, x+w, y));
painter->drawLine(QLineF( x, y+w, x, y-w));
break;
}
case ssCircle:
{
painter->drawEllipse(QPointF(x , y), w, w);
break;
}
case ssDisc:
{
QBrush b = painter->brush();
painter->setBrush(painter->pen().color());
painter->drawEllipse(QPointF(x , y), w, w);
painter->setBrush(b);
break;
}
case ssSquare:
{
painter->drawRect(QRectF(x-w, y-w, mSize, mSize));
break;
}
case ssDiamond:
{
painter->drawLine(QLineF(x-w, y, x, y-w));
painter->drawLine(QLineF( x, y-w, x+w, y));
painter->drawLine(QLineF(x+w, y, x, y+w));
painter->drawLine(QLineF( x, y+w, x-w, y));
break;
}
case ssStar:
{
painter->drawLine(QLineF(x-w, y, x+w, y));
painter->drawLine(QLineF( x, y+w, x, y-w));
painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707));
painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707));
break;
}
case ssTriangle:
{
painter->drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w));
painter->drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w));
painter->drawLine(QLineF( x, y-0.977*w, x-w, y+0.755*w));
break;
}
case ssTriangleInverted:
{
painter->drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w));
painter->drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w));
painter->drawLine(QLineF( x, y+0.977*w, x-w, y-0.755*w));
break;
}
case ssCrossSquare:
{
painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95));
painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w));
painter->drawRect(QRectF(x-w, y-w, mSize, mSize));
break;
}
case ssPlusSquare:
{
painter->drawLine(QLineF(x-w, y, x+w*0.95, y));
painter->drawLine(QLineF( x, y+w, x, y-w));
painter->drawRect(QRectF(x-w, y-w, mSize, mSize));
break;
}
case ssCrossCircle:
{
painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670));
painter->drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707));
painter->drawEllipse(QPointF(x, y), w, w);
break;
}
case ssPlusCircle:
{
painter->drawLine(QLineF(x-w, y, x+w, y));
painter->drawLine(QLineF( x, y+w, x, y-w));
painter->drawEllipse(QPointF(x, y), w, w);
break;
}
case ssPeace:
{
painter->drawLine(QLineF(x, y-w, x, y+w));
painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707));
painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707));
painter->drawEllipse(QPointF(x, y), w, w);
break;
}
case ssPixmap:
{
painter->drawPixmap(x-mPixmap.width()*0.5, y-mPixmap.height()*0.5, mPixmap);
break;
}
case ssCustom:
{
QTransform oldTransform = painter->transform();
painter->translate(x, y);
painter->scale(mSize/6.0, mSize/6.0);
painter->drawPath(mCustomPath);
painter->setTransform(oldTransform);
break;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////// QCPLayer
////////////////////////////////////////////////////////////////////////////////////////////////////
/*! \class QCPLayer
\brief A layer that may contain objects, to control the rendering order
The Layering system of QCustomPlot is the mechanism to control the rendering order of the
elements inside the plot.
It is based on the two classes QCPLayer and QCPLayerable. QCustomPlot holds an ordered list of
one or more instances of QCPLayer (see QCustomPlot::addLayer, QCustomPlot::layer,
QCustomPlot::moveLayer, etc.). When replotting, QCustomPlot goes through the list of layers
bottom to top and successively draws the layerables of the layers.
A QCPLayer contains an ordered list of QCPLayerable instances. QCPLayerable is an abstract base
class from which almost all visible objects derive, like axes, grids, graphs, items, etc.
Initially, QCustomPlot has five layers: "background", "grid", "main", "axes" and "legend" (in
that order). The top two layers "axes" and "legend" contain the default axes and legend, so they
will be drawn on top. In the middle, there is the "main" layer. It is initially empty and set as
the current layer (see QCustomPlot::setCurrentLayer). This means, all new plottables, items etc.
are created on this layer by default. Then comes the "grid" layer which contains the QCPGrid
instances (which belong tightly to QCPAxis, see \ref QCPAxis::grid). The Axis rect background
shall be drawn behind everything else, thus the default QCPAxisRect instance is placed on the
"background" layer. Of course, the layer affiliation of the individual objects can be changed as
required (\ref QCPLayerable::setLayer).
Controlling the ordering of objects is easy: Create a new layer in the position you want it to
be, e.g. above "main", with QCustomPlot::addLayer. Then set the current layer with
QCustomPlot::setCurrentLayer to that new layer and finally create the objects normally. They will
be placed on the new layer automatically, due to the current layer setting. Alternatively you
could have also ignored the current layer setting and just moved the objects with
QCPLayerable::setLayer to the desired layer after creating them.
It is also possible to move whole layers. For example, If you want the grid to be shown in front
of all plottables/items on the "main" layer, just move it above "main" with
QCustomPlot::moveLayer.
The rendering order within one layer is simply by order of creation or insertion. The item
created last (or added last to the layer), is drawn on top of all other objects on that layer.
When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below
the deleted layer, see QCustomPlot::removeLayer.
*/
/* start documentation of inline functions */
/*! \fn QList<QCPLayerable*> QCPLayer::children() const
Returns a list of all layerables on this layer. The order corresponds to the rendering order:
layerables with higher indices are drawn above layerables with lower indices.
*/