WPSGraphicStyle.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 
00003 /* libwps
00004  * Version: MPL 2.0 / LGPLv2.1+
00005  *
00006  * This Source Code Form is subject to the terms of the Mozilla Public
00007  * License, v. 2.0. If a copy of the MPL was not distributed with this
00008  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009  *
00010  * Major Contributor(s):
00011  * Copyright (C) 2002, 2005 William Lachance (william.lachance@sympatico.ca)
00012  * Copyright (C) 2002, 2004 Marc Maurer (uwog@uwog.net)
00013  *
00014  * For minor contributions see the git repository.
00015  *
00016  * Alternatively, the contents of this file may be used under the terms
00017  * of the GNU Lesser General Public License Version 2.1 or later
00018  * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are
00019  * applicable instead of those above.
00020  *
00021  * For further information visit http://libwps.sourceforge.net
00022 */
00023 #ifndef WPS_GRAPHIC_STYLE
00024 #  define WPS_GRAPHIC_STYLE
00025 #  include <ostream>
00026 #  include <string>
00027 #  include <vector>
00028 
00029 #  include "librevenge/librevenge.h"
00030 #  include "libwps_internal.h"
00031 
00037 class WPSGraphicStyle
00038 {
00039 public:
00041         enum LineCap { C_Butt, C_Square, C_Round };
00043         enum LineJoin { J_Miter, J_Round, J_Bevel };
00045         enum GradientType { G_None, G_Axial, G_Linear, G_Radial, G_Rectangular, G_Square, G_Ellipsoid };
00046 
00048         struct GradientStop
00049         {
00051                 GradientStop(float offset=0.0, WPSColor const &col=WPSColor::black(), float opacity=1.0) :
00052                         m_offset(offset), m_color(col), m_opacity(opacity)
00053                 {
00054                 }
00056                 int cmp(GradientStop const &a) const
00057                 {
00058                         if (m_offset < a.m_offset) return -1;
00059                         if (m_offset > a.m_offset) return 1;
00060                         if (m_color < a.m_color) return -1;
00061                         if (m_color > a.m_color) return 1;
00062                         if (m_opacity < a.m_opacity) return -1;
00063                         if (m_opacity > a.m_opacity) return 1;
00064                         return 0;
00065                 }
00067                 friend std::ostream &operator<<(std::ostream &o, GradientStop const &st)
00068                 {
00069                         o << "offset=" << st.m_offset << ",";
00070                         o << "color=" << st.m_color << ",";
00071                         if (st.m_opacity<1.0)
00072                                 o << "opacity=" << st.m_opacity*100.f << "%,";
00073                         return o;
00074                 }
00076                 float m_offset;
00078                 WPSColor m_color;
00080                 float m_opacity;
00081         };
00086         struct Pattern
00087         {
00089                 Pattern() : m_dim(0,0), m_data(), m_picture(), m_pictureMime(""), m_pictureAverageColor(WPSColor::white())
00090                 {
00091                         m_colors[0]=WPSColor::black();
00092                         m_colors[1]=WPSColor::white();
00093                 }
00095                 Pattern(Vec2i dim, librevenge::RVNGBinaryData const &picture, std::string const &mime, WPSColor const &avColor) :
00096                         m_dim(dim), m_data(), m_picture(picture), m_pictureMime(mime), m_pictureAverageColor(avColor)
00097                 {
00098                         m_colors[0]=WPSColor::black();
00099                         m_colors[1]=WPSColor::white();
00100                 }
00102                 virtual ~Pattern() {}
00104                 bool empty() const
00105                 {
00106                         if (m_dim[0]==0 || m_dim[1]==0) return true;
00107                         if (m_picture.size()) return false;
00108                         if (m_dim[0]!=8 && m_dim[0]!=16 && m_dim[0]!=32) return true;
00109                         return m_data.size()!=size_t((m_dim[0]/8)*m_dim[1]);
00110                 }
00112                 bool getAverageColor(WPSColor &col) const;
00114                 bool getUniqueColor(WPSColor &col) const;
00116                 bool getBinary(librevenge::RVNGBinaryData &data, std::string &type) const;
00117 
00119                 int cmp(Pattern const &a) const
00120                 {
00121                         int diff = m_dim.cmp(a.m_dim);
00122                         if (diff) return diff;
00123                         if (m_data.size() < a.m_data.size()) return -1;
00124                         if (m_data.size() > a.m_data.size()) return 1;
00125                         for (size_t h=0; h < m_data.size(); ++h)
00126                         {
00127                                 if (m_data[h]<a.m_data[h]) return 1;
00128                                 if (m_data[h]>a.m_data[h]) return -1;
00129                         }
00130                         for (int i=0; i<2; ++i)
00131                         {
00132                                 if (m_colors[i] < a.m_colors[i]) return 1;
00133                                 if (m_colors[i] > a.m_colors[i]) return -1;
00134                         }
00135                         if (m_pictureAverageColor < a.m_pictureAverageColor) return 1;
00136                         if (m_pictureAverageColor > a.m_pictureAverageColor) return -1;
00137                         if (m_pictureMime < a.m_pictureMime) return 1;
00138                         if (m_pictureMime > a.m_pictureMime) return -1;
00139                         if (m_picture.size() < a.m_picture.size()) return 1;
00140                         if (m_picture.size() > a.m_picture.size()) return -1;
00141                         const unsigned char *ptr=m_picture.getDataBuffer();
00142                         const unsigned char *aPtr=a.m_picture.getDataBuffer();
00143                         if (!ptr || !aPtr) return 0; // must only appear if the two buffers are empty
00144                         for (unsigned long h=0; h < m_picture.size(); ++h, ++ptr, ++aPtr)
00145                         {
00146                                 if (*ptr < *aPtr) return 1;
00147                                 if (*ptr > *aPtr) return -1;
00148                         }
00149                         return 0;
00150                 }
00152                 friend std::ostream &operator<<(std::ostream &o, Pattern const &pat)
00153                 {
00154                         o << "dim=" << pat.m_dim << ",";
00155                         if (pat.m_picture.size())
00156                         {
00157                                 o << "type=" << pat.m_pictureMime << ",";
00158                                 o << "col[average]=" << pat.m_pictureAverageColor << ",";
00159                         }
00160                         else
00161                         {
00162                                 if (!pat.m_colors[0].isBlack()) o << "col0=" << pat.m_colors[0] << ",";
00163                                 if (!pat.m_colors[1].isWhite()) o << "col1=" << pat.m_colors[1] << ",";
00164                                 o << "[";
00165                                 for (size_t h=0; h < pat.m_data.size(); ++h)
00166                                         o << std::hex << (int) pat.m_data[h] << std::dec << ",";
00167                                 o << "],";
00168                         }
00169                         return o;
00170                 }
00172                 Vec2i m_dim;
00173 
00175                 WPSColor m_colors[2];
00177                 std::vector<unsigned char> m_data;
00178         protected:
00180                 librevenge::RVNGBinaryData m_picture;
00182                 std::string m_pictureMime;
00184                 WPSColor m_pictureAverageColor;
00185         };
00187         WPSGraphicStyle() :  m_lineWidth(1), m_lineDashWidth(), m_lineCap(C_Butt), m_lineJoin(J_Miter), m_lineOpacity(1), m_lineColor(WPSColor::black()),
00188                 m_fillRuleEvenOdd(false), m_surfaceColor(WPSColor::white()), m_surfaceOpacity(0),
00189                 m_shadowColor(WPSColor::black()), m_shadowOpacity(0), m_shadowOffset(1,1),
00190                 m_pattern(),
00191                 m_gradientType(G_None), m_gradientStopList(), m_gradientAngle(0), m_gradientBorder(0), m_gradientPercentCenter(0.5f,0.5f), m_gradientRadius(1),
00192                 m_backgroundColor(WPSColor::white()), m_backgroundOpacity(-1), m_bordersList(), m_frameName(""), m_frameNextName(""),
00193                 m_rotate(0), m_extra("")
00194         {
00195                 m_arrows[0]=m_arrows[1]=false;
00196                 m_flip[0]=m_flip[1]=false;
00197                 m_gradientStopList.push_back(GradientStop(0.0, WPSColor::white()));
00198                 m_gradientStopList.push_back(GradientStop(1.0, WPSColor::black()));
00199         }
00201         static WPSGraphicStyle emptyStyle()
00202         {
00203                 WPSGraphicStyle res;
00204                 res.m_lineWidth=0;
00205                 return res;
00206         }
00208         virtual ~WPSGraphicStyle() { }
00210         bool hasLine() const
00211         {
00212                 return m_lineWidth>0 && m_lineOpacity>0;
00213         }
00215         void setSurfaceColor(WPSColor const &col, float opacity = 1)
00216         {
00217                 m_surfaceColor = col;
00218                 m_surfaceOpacity = opacity;
00219         }
00221         bool hasSurfaceColor() const
00222         {
00223                 return m_surfaceOpacity > 0;
00224         }
00226         void setPattern(Pattern const &pat)
00227         {
00228                 m_pattern=pat;
00229         }
00231         bool hasPattern() const
00232         {
00233                 return !m_pattern.empty();
00234         }
00236         bool hasGradient(bool complex=false) const
00237         {
00238                 return m_gradientType != G_None && (int) m_gradientStopList.size() >= (complex ? 3 : 2);
00239         }
00241         bool hasSurface() const
00242         {
00243                 return hasSurfaceColor() || hasPattern() || hasGradient();
00244         }
00246         void setBackgroundColor(WPSColor const &col, float opacity = 1)
00247         {
00248                 m_backgroundColor = col;
00249                 m_backgroundOpacity = opacity;
00250         }
00252         bool hasBackgroundColor() const
00253         {
00254                 return m_backgroundOpacity > 0;
00255         }
00257         void setShadowColor(WPSColor const &col, float opacity = 1)
00258         {
00259                 m_shadowColor = col;
00260                 m_shadowOpacity = opacity;
00261         }
00263         bool hasShadow() const
00264         {
00265                 return m_shadowOpacity > 0;
00266         }
00268         bool hasBorders() const
00269         {
00270                 return !m_bordersList.empty();
00271         }
00273         bool hasSameBorders() const
00274         {
00275                 if (m_bordersList.empty()) return true;
00276                 if (m_bordersList.size()!=4) return false;
00277                 for (size_t i=1; i<m_bordersList.size(); ++i)
00278                 {
00279                         if (m_bordersList[i]!=m_bordersList[0])
00280                                 return false;
00281                 }
00282                 return true;
00283         }
00285         std::vector<WPSBorder> const &borders() const
00286         {
00287                 return m_bordersList;
00288         }
00290         void resetBorders()
00291         {
00292                 m_bordersList.resize(0);
00293         }
00295         void setBorders(int wh, WPSBorder const &border);
00297         friend std::ostream &operator<<(std::ostream &o, WPSGraphicStyle const &st);
00299         void addTo(librevenge::RVNGPropertyList &pList, bool only1d=false) const;
00301         void addFrameTo(librevenge::RVNGPropertyList &pList) const;
00303         int cmp(WPSGraphicStyle const &a) const;
00304 
00306         float m_lineWidth;
00308         std::vector<float> m_lineDashWidth;
00310         LineCap m_lineCap;
00312         LineJoin m_lineJoin;
00314         float m_lineOpacity;
00316         WPSColor m_lineColor;
00318         bool m_fillRuleEvenOdd;
00320         WPSColor m_surfaceColor;
00322         float m_surfaceOpacity;
00323 
00325         WPSColor m_shadowColor;
00327         float m_shadowOpacity;
00329         Vec2f m_shadowOffset;
00330 
00332         Pattern m_pattern;
00333 
00335         GradientType m_gradientType;
00337         std::vector<GradientStop> m_gradientStopList;
00339         float m_gradientAngle;
00341         float m_gradientBorder;
00343         Vec2f m_gradientPercentCenter;
00345         float m_gradientRadius;
00346 
00348         bool m_arrows[2];
00349 
00350         //
00351         // related to the frame
00352         //
00353 
00355         WPSColor m_backgroundColor;
00357         float m_backgroundOpacity;
00359         std::vector<WPSBorder> m_bordersList;
00361         std::string m_frameName;
00363         std::string m_frameNextName;
00364 
00365         //
00366         // some transformation: must probably be somewhere else
00367         //
00368 
00370         float m_rotate;
00372         bool m_flip[2];
00373 
00375         std::string m_extra;
00376 };
00377 #endif
00378 /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */