File indexing completed on 2024-04-14 14:47:09

0001 /********************************************************************************
0002  * Copyright (C) 2011-2015 by Stephen Allewell                                  *
0003  * steve.allewell@gmail.com                                                     *
0004  *                                                                              *
0005  * This program is free software; you can redistribute it and/or modify         *
0006  * it under the terms of the GNU General Public License as published by         *
0007  * the Free Software Foundation; either version 2 of the License, or            *
0008  * (at your option) any later version.                                          *
0009  ********************************************************************************/
0010 
0011 
0012 /**
0013  * @file
0014  * Implement the Symbol class.
0015  */
0016 
0017 
0018 /**
0019  * @page symbol Symbol
0020  * The Symbol encapsulates the QPainterPath with an attribute @ref Symbol::filled() defining if the path is drawn filled
0021  * or not. If the path is drawn as an outline, the @ref Symbol::lineWidth() attribute is used to initialize the pen for
0022  * drawing the path. The end cap style and join style can be set which are added to the pen when drawing the path.
0023  */
0024 
0025 
0026 #include "Symbol.h"
0027 
0028 #include <QDataStream>
0029 
0030 #include "Exceptions.h"
0031 
0032 
0033 /**
0034  * Constructor
0035  *
0036  * The Symbol is initialized with filling enabled and a default pen width of 0.01 with a Qt::SquareCap end and a
0037  * Qt::MiterJoin join type. The pen width is scaled with the painter.
0038  */
0039 Symbol::Symbol()
0040     :   m_filled(true),
0041         m_lineWidth(0.01),
0042         m_capStyle(Qt::SquareCap),
0043         m_joinStyle(Qt::MiterJoin)
0044 {
0045 }
0046 
0047 
0048 /**
0049  * Destructor
0050  */
0051 Symbol::~Symbol()
0052 {
0053 }
0054 
0055 
0056 /**
0057  * Get the QPainterPath for the symbol. The path also incorporates the path fill mode.
0058  *
0059  * @return a QPainterPath
0060  */
0061 QPainterPath Symbol::path() const
0062 {
0063     return m_path;
0064 }
0065 
0066 
0067 /**
0068  * Get the path filled status.
0069  *
0070  * @return @c true if the path is to be drawn filled, @c false if unfilled
0071  */
0072 bool Symbol::filled() const
0073 {
0074     return m_filled;
0075 }
0076 
0077 
0078 /**
0079  * Get the outline path line width.
0080  *
0081  * @return a qreal representing the line width, this is scaled with the painter
0082  */
0083 qreal Symbol::lineWidth() const
0084 {
0085     return m_lineWidth;
0086 }
0087 
0088 
0089 /**
0090  * Get the pen cap style, see the QPen documentation for details on the styles.
0091  *
0092  * @return a Qt::PenCapStyle value
0093  */
0094 Qt::PenCapStyle Symbol::capStyle() const
0095 {
0096     return m_capStyle;
0097 }
0098 
0099 
0100 /**
0101  * Get the pen join style, see the QPen documentation for details on the styles.
0102  *
0103  * @return a Qt::PenJoinStyle value
0104  */
0105 Qt::PenJoinStyle Symbol::joinStyle() const
0106 {
0107     return m_joinStyle;
0108 }
0109 
0110 
0111 /**
0112  * Set the QPainterPath for the symbol.
0113  *
0114  * @param path a const reference to a QPainterPath
0115  */
0116 void Symbol::setPath(const QPainterPath &path)
0117 {
0118     m_path = path;
0119 }
0120 
0121 
0122 /**
0123  * Set the filled status of the path.
0124  *
0125  * @param filled @c true if the path is to be drawn filled, @c false if unfilled
0126  */
0127 void Symbol::setFilled(bool filled)
0128 {
0129     m_filled = filled;
0130 }
0131 
0132 
0133 /**
0134  * Set the line width for the outline paths.
0135  *
0136  * @param width the width of the pen
0137  */
0138 void Symbol::setLineWidth(qreal width)
0139 {
0140     m_lineWidth = width;
0141 }
0142 
0143 
0144 /**
0145  * Set the pen cap style, see the QPen documentation for details on the styles.
0146  *
0147  * @param capStyle a Qt::PenCapStyle value
0148  */
0149 void Symbol::setCapStyle(Qt::PenCapStyle capStyle)
0150 {
0151     m_capStyle = capStyle;
0152 }
0153 
0154 
0155 /**
0156  * Set the pen join style, see the QPen documentation for details on the styles.
0157  *
0158  * @param joinStyle a Qt::PenJoinStyle value
0159  */
0160 void Symbol::setJoinStyle(Qt::PenJoinStyle joinStyle)
0161 {
0162     m_joinStyle = joinStyle;
0163 }
0164 
0165 
0166 /**
0167  * Get a pen based on the parameters of the symbol.
0168  *
0169  * @return a black QPen with the symbols width and end styles
0170  */
0171 QPen Symbol::pen() const
0172 {
0173     QPen p;
0174 
0175     if (!m_filled) {
0176         p.setWidthF(m_lineWidth);
0177         p.setCapStyle(m_capStyle);
0178         p.setJoinStyle(m_joinStyle);
0179     } else {
0180         p.setCosmetic(true);
0181     }
0182 
0183     return p;
0184 }
0185 
0186 
0187 /**
0188  * Get a brush based on the parameters of the symbol.
0189  *
0190  * @return a black brush based on the filled state of the symbol
0191  */
0192 QBrush Symbol::brush() const
0193 {
0194     return QBrush(m_filled ? Qt::SolidPattern : Qt::NoBrush);
0195 }
0196 
0197 
0198 /**
0199  * Stream out a Symbol.
0200  *
0201  * @param stream a reference to the QDataStream to write to
0202  * @param symbol a const reference to the Symbol to stream
0203  *
0204  * @return a reference to the stream
0205  */
0206 QDataStream &operator<<(QDataStream &stream, const Symbol &symbol)
0207 {
0208     stream << symbol.version << symbol.m_path << symbol.m_filled << symbol.m_lineWidth << static_cast<qint32>(symbol.m_capStyle) << static_cast<qint32>(symbol.m_joinStyle);
0209 
0210     if (stream.status() != QDataStream::Ok) {
0211         throw FailedWriteLibrary(stream.status());
0212     }
0213 
0214     return stream;
0215 }
0216 
0217 
0218 /**
0219  * Stream in a Symbol.
0220  *
0221  * @param stream a reference to the QDataStream to read from
0222  * @param symbol a reference to the Symbol to stream
0223  *
0224  * @return a reference to the stream
0225  */
0226 QDataStream &operator>>(QDataStream &stream, Symbol &symbol)
0227 {
0228     qint32 version;
0229     qint32 capStyle;
0230     qint32 joinStyle;
0231     stream >> version;
0232 
0233     switch (version) {
0234     case 100:
0235         stream >> symbol.m_path >> symbol.m_filled >> symbol.m_lineWidth >> capStyle >> joinStyle;
0236         symbol.m_capStyle = static_cast<Qt::PenCapStyle>(capStyle);
0237         symbol.m_joinStyle = static_cast<Qt::PenJoinStyle>(joinStyle);
0238         break;
0239 
0240     default:
0241         throw InvalidSymbolVersion(version);
0242         break;
0243     }
0244 
0245     return stream;
0246 }