File indexing completed on 2024-04-21 04:34:01

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  * Get the QPainterPath for the symbol. The path also incorporates the path fill mode.
0050  *
0051  * @return a QPainterPath
0052  */
0053 QPainterPath Symbol::path() const
0054 {
0055     return m_path;
0056 }
0057 
0058 
0059 /**
0060  * Get the path filled status.
0061  *
0062  * @return @c true if the path is to be drawn filled, @c false if unfilled
0063  */
0064 bool Symbol::filled() const
0065 {
0066     return m_filled;
0067 }
0068 
0069 
0070 /**
0071  * Get the outline path line width.
0072  *
0073  * @return a qreal representing the line width, this is scaled with the painter
0074  */
0075 qreal Symbol::lineWidth() const
0076 {
0077     return m_lineWidth;
0078 }
0079 
0080 
0081 /**
0082  * Get the pen cap style, see the QPen documentation for details on the styles.
0083  *
0084  * @return a Qt::PenCapStyle value
0085  */
0086 Qt::PenCapStyle Symbol::capStyle() const
0087 {
0088     return m_capStyle;
0089 }
0090 
0091 
0092 /**
0093  * Get the pen join style, see the QPen documentation for details on the styles.
0094  *
0095  * @return a Qt::PenJoinStyle value
0096  */
0097 Qt::PenJoinStyle Symbol::joinStyle() const
0098 {
0099     return m_joinStyle;
0100 }
0101 
0102 
0103 /**
0104  * Set the QPainterPath for the symbol.
0105  *
0106  * @param path a const reference to a QPainterPath
0107  */
0108 void Symbol::setPath(const QPainterPath &path)
0109 {
0110     m_path = path;
0111 }
0112 
0113 
0114 /**
0115  * Set the filled status of the path.
0116  *
0117  * @param filled @c true if the path is to be drawn filled, @c false if unfilled
0118  */
0119 void Symbol::setFilled(bool filled)
0120 {
0121     m_filled = filled;
0122 }
0123 
0124 
0125 /**
0126  * Set the line width for the outline paths.
0127  *
0128  * @param width the width of the pen
0129  */
0130 void Symbol::setLineWidth(qreal width)
0131 {
0132     m_lineWidth = width;
0133 }
0134 
0135 
0136 /**
0137  * Set the pen cap style, see the QPen documentation for details on the styles.
0138  *
0139  * @param capStyle a Qt::PenCapStyle value
0140  */
0141 void Symbol::setCapStyle(Qt::PenCapStyle capStyle)
0142 {
0143     m_capStyle = capStyle;
0144 }
0145 
0146 
0147 /**
0148  * Set the pen join style, see the QPen documentation for details on the styles.
0149  *
0150  * @param joinStyle a Qt::PenJoinStyle value
0151  */
0152 void Symbol::setJoinStyle(Qt::PenJoinStyle joinStyle)
0153 {
0154     m_joinStyle = joinStyle;
0155 }
0156 
0157 
0158 /**
0159  * Get a pen based on the parameters of the symbol.
0160  *
0161  * @return a black QPen with the symbols width and end styles
0162  */
0163 QPen Symbol::pen() const
0164 {
0165     QPen p;
0166 
0167     if (!m_filled) {
0168         p.setWidthF(m_lineWidth);
0169         p.setCapStyle(m_capStyle);
0170         p.setJoinStyle(m_joinStyle);
0171     } else {
0172         p.setCosmetic(true);
0173     }
0174 
0175     return p;
0176 }
0177 
0178 
0179 /**
0180  * Get a brush based on the parameters of the symbol.
0181  *
0182  * @return a black brush based on the filled state of the symbol
0183  */
0184 QBrush Symbol::brush() const
0185 {
0186     return QBrush(m_filled ? Qt::SolidPattern : Qt::NoBrush);
0187 }
0188 
0189 
0190 /**
0191  * Stream out a Symbol.
0192  *
0193  * @param stream a reference to the QDataStream to write to
0194  * @param symbol a const reference to the Symbol to stream
0195  *
0196  * @return a reference to the stream
0197  */
0198 QDataStream &operator<<(QDataStream &stream, const Symbol &symbol)
0199 {
0200     stream << symbol.version << symbol.m_path << symbol.m_filled << symbol.m_lineWidth << static_cast<qint32>(symbol.m_capStyle) << static_cast<qint32>(symbol.m_joinStyle);
0201 
0202     if (stream.status() != QDataStream::Ok) {
0203         throw FailedWriteLibrary(stream.status());
0204     }
0205 
0206     return stream;
0207 }
0208 
0209 
0210 /**
0211  * Stream in a Symbol.
0212  *
0213  * @param stream a reference to the QDataStream to read from
0214  * @param symbol a reference to the Symbol to stream
0215  *
0216  * @return a reference to the stream
0217  */
0218 QDataStream &operator>>(QDataStream &stream, Symbol &symbol)
0219 {
0220     qint32 version;
0221     qint32 capStyle;
0222     qint32 joinStyle;
0223     stream >> version;
0224 
0225     switch (version) {
0226     case 100:
0227         stream >> symbol.m_path >> symbol.m_filled >> symbol.m_lineWidth >> capStyle >> joinStyle;
0228         symbol.m_capStyle = static_cast<Qt::PenCapStyle>(capStyle);
0229         symbol.m_joinStyle = static_cast<Qt::PenJoinStyle>(joinStyle);
0230         break;
0231 
0232     default:
0233         throw InvalidSymbolVersion(version);
0234         break;
0235     }
0236 
0237     return stream;
0238 }