MWAWGraphicStyle.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
00002 
00003 /* libmwaw
00004 * Version: MPL 2.0 / LGPLv2+
00005 *
00006 * The contents of this file are subject to the Mozilla Public License Version
00007 * 2.0 (the "License"); you may not use this file except in compliance with
00008 * the License or as specified alternatively below. You may obtain a copy of
00009 * the License at http://www.mozilla.org/MPL/
00010 *
00011 * Software distributed under the License is distributed on an "AS IS" basis,
00012 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013 * for the specific language governing rights and limitations under the
00014 * License.
00015 *
00016 * Major Contributor(s):
00017 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
00018 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
00019 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
00020 * Copyright (C) 2006, 2007 Andrew Ziem
00021 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
00022 *
00023 *
00024 * All Rights Reserved.
00025 *
00026 * For minor contributions see the git repository.
00027 *
00028 * Alternatively, the contents of this file may be used under the terms of
00029 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
00030 * in which case the provisions of the LGPLv2+ are applicable
00031 * instead of those above.
00032 */
00033 #ifndef MWAW_GRAPHIC_STYLE
00034 #  define MWAW_GRAPHIC_STYLE
00035 #  include <ostream>
00036 #  include <string>
00037 #  include <vector>
00038 
00039 #  include "librevenge/librevenge.h"
00040 #  include "libmwaw_internal.hxx"
00041 
00047 class MWAWGraphicStyle
00048 {
00049 public:
00051   enum LineCap { C_Butt, C_Square, C_Round };
00053   enum LineJoin { J_Miter, J_Round, J_Bevel };
00055   enum GradientType { G_None, G_Axial, G_Linear, G_Radial, G_Rectangular, G_Square, G_Ellipsoid };
00056 
00058   struct GradientStop {
00060     GradientStop(float offset=0.0, MWAWColor const &col=MWAWColor::black(), float opacity=1.0) :
00061       m_offset(offset), m_color(col), m_opacity(opacity)
00062     {
00063     }
00065     int cmp(GradientStop const &a) const
00066     {
00067       if (m_offset < a.m_offset) return -1;
00068       if (m_offset > a.m_offset) return 1;
00069       if (m_color < a.m_color) return -1;
00070       if (m_color > a.m_color) return 1;
00071       if (m_opacity < a.m_opacity) return -1;
00072       if (m_opacity > a.m_opacity) return 1;
00073       return 0;
00074     }
00076     friend std::ostream &operator<<(std::ostream &o, GradientStop const &st)
00077     {
00078       o << "offset=" << st.m_offset << ",";
00079       o << "color=" << st.m_color << ",";
00080       if (st.m_opacity<1.0)
00081         o << "opacity=" << st.m_opacity*100.f << "%,";
00082       return o;
00083     }
00085     float m_offset;
00087     MWAWColor m_color;
00089     float m_opacity;
00090   };
00095   struct Pattern {
00097     Pattern() : m_dim(0,0), m_data(), m_picture(), m_pictureMime(""), m_pictureAverageColor(MWAWColor::white())
00098     {
00099       m_colors[0]=MWAWColor::black();
00100       m_colors[1]=MWAWColor::white();
00101     }
00103     Pattern(MWAWVec2i dim, librevenge::RVNGBinaryData const &picture, std::string const &mime, MWAWColor const &avColor) :
00104       m_dim(dim), m_data(), m_picture(picture), m_pictureMime(mime), m_pictureAverageColor(avColor)
00105     {
00106       m_colors[0]=MWAWColor::black();
00107       m_colors[1]=MWAWColor::white();
00108     }
00110     virtual ~Pattern() {}
00112     bool empty() const
00113     {
00114       if (m_dim[0]==0 || m_dim[1]==0) return true;
00115       if (m_picture.size()) return false;
00116       if (m_dim[0]!=8 && m_dim[0]!=16 && m_dim[0]!=32) return true;
00117       return m_data.size()!=size_t((m_dim[0]/8)*m_dim[1]);
00118     }
00120     bool getAverageColor(MWAWColor &col) const;
00122     bool getUniqueColor(MWAWColor &col) const;
00124     bool getBinary(librevenge::RVNGBinaryData &data, std::string &type) const;
00125 
00127     int cmp(Pattern const &a) const
00128     {
00129       int diff = m_dim.cmp(a.m_dim);
00130       if (diff) return diff;
00131       if (m_data.size() < a.m_data.size()) return -1;
00132       if (m_data.size() > a.m_data.size()) return 1;
00133       for (size_t h=0; h < m_data.size(); ++h) {
00134         if (m_data[h]<a.m_data[h]) return 1;
00135         if (m_data[h]>a.m_data[h]) return -1;
00136       }
00137       for (int i=0; i<2; ++i) {
00138         if (m_colors[i] < a.m_colors[i]) return 1;
00139         if (m_colors[i] > a.m_colors[i]) return -1;
00140       }
00141       if (m_pictureAverageColor < a.m_pictureAverageColor) return 1;
00142       if (m_pictureAverageColor > a.m_pictureAverageColor) return -1;
00143       if (m_pictureMime < a.m_pictureMime) return 1;
00144       if (m_pictureMime > a.m_pictureMime) return -1;
00145       if (m_picture.size() < a.m_picture.size()) return 1;
00146       if (m_picture.size() > a.m_picture.size()) return -1;
00147       const unsigned char *ptr=m_picture.getDataBuffer();
00148       const unsigned char *aPtr=a.m_picture.getDataBuffer();
00149       if (!ptr || !aPtr) return 0; // must only appear if the two buffers are empty
00150       for (unsigned long h=0; h < m_picture.size(); ++h, ++ptr, ++aPtr) {
00151         if (*ptr < *aPtr) return 1;
00152         if (*ptr > *aPtr) return -1;
00153       }
00154       return 0;
00155     }
00157     friend std::ostream &operator<<(std::ostream &o, Pattern const &pat)
00158     {
00159       o << "dim=" << pat.m_dim << ",";
00160       if (pat.m_picture.size()) {
00161         o << "type=" << pat.m_pictureMime << ",";
00162         o << "col[average]=" << pat.m_pictureAverageColor << ",";
00163       }
00164       else {
00165         if (!pat.m_colors[0].isBlack()) o << "col0=" << pat.m_colors[0] << ",";
00166         if (!pat.m_colors[1].isWhite()) o << "col1=" << pat.m_colors[1] << ",";
00167         o << "[";
00168         for (size_t h=0; h < pat.m_data.size(); ++h)
00169           o << std::hex << (int) pat.m_data[h] << std::dec << ",";
00170         o << "],";
00171       }
00172       return o;
00173     }
00175     MWAWVec2i m_dim;
00176 
00178     MWAWColor m_colors[2];
00180     std::vector<unsigned char> m_data;
00181   protected:
00183     librevenge::RVNGBinaryData m_picture;
00185     std::string m_pictureMime;
00187     MWAWColor m_pictureAverageColor;
00188   };
00190   MWAWGraphicStyle() :  m_lineWidth(1), m_lineDashWidth(), m_lineCap(C_Butt), m_lineJoin(J_Miter), m_lineOpacity(1), m_lineColor(MWAWColor::black()),
00191     m_fillRuleEvenOdd(false), m_surfaceColor(MWAWColor::white()), m_surfaceOpacity(0),
00192     m_shadowColor(MWAWColor::black()), m_shadowOpacity(0), m_shadowOffset(1,1),
00193     m_pattern(),
00194     m_gradientType(G_None), m_gradientStopList(), m_gradientAngle(0), m_gradientBorder(0), m_gradientPercentCenter(0.5f,0.5f), m_gradientRadius(1),
00195     m_backgroundColor(MWAWColor::white()), m_backgroundOpacity(-1), m_bordersList(), m_frameName(""), m_frameNextName(""),
00196     m_rotate(0), m_extra("")
00197   {
00198     m_arrows[0]=m_arrows[1]=false;
00199     m_flip[0]=m_flip[1]=false;
00200     m_gradientStopList.push_back(GradientStop(0.0, MWAWColor::white()));
00201     m_gradientStopList.push_back(GradientStop(1.0, MWAWColor::black()));
00202   }
00204   static MWAWGraphicStyle emptyStyle()
00205   {
00206     MWAWGraphicStyle res;
00207     res.m_lineWidth=0;
00208     return res;
00209   }
00211   virtual ~MWAWGraphicStyle() { }
00213   bool hasLine() const
00214   {
00215     return m_lineWidth>0 && m_lineOpacity>0;
00216   }
00218   void setSurfaceColor(MWAWColor const &col, float opacity = 1)
00219   {
00220     m_surfaceColor = col;
00221     m_surfaceOpacity = opacity;
00222   }
00224   bool hasSurfaceColor() const
00225   {
00226     return m_surfaceOpacity > 0;
00227   }
00229   void setPattern(Pattern const &pat)
00230   {
00231     m_pattern=pat;
00232   }
00234   bool hasPattern() const
00235   {
00236     return !m_pattern.empty();
00237   }
00239   bool hasGradient(bool complex=false) const
00240   {
00241     return m_gradientType != G_None && (int) m_gradientStopList.size() >= (complex ? 3 : 2);
00242   }
00244   bool hasSurface() const
00245   {
00246     return hasSurfaceColor() || hasPattern() || hasGradient();
00247   }
00249   void setBackgroundColor(MWAWColor const &col, float opacity = 1)
00250   {
00251     m_backgroundColor = col;
00252     m_backgroundOpacity = opacity;
00253   }
00255   bool hasBackgroundColor() const
00256   {
00257     return m_backgroundOpacity > 0;
00258   }
00260   void setShadowColor(MWAWColor const &col, float opacity = 1)
00261   {
00262     m_shadowColor = col;
00263     m_shadowOpacity = opacity;
00264   }
00266   bool hasShadow() const
00267   {
00268     return m_shadowOpacity > 0;
00269   }
00271   bool hasBorders() const
00272   {
00273     return !m_bordersList.empty();
00274   }
00276   bool hasSameBorders() const
00277   {
00278     if (m_bordersList.empty()) return true;
00279     if (m_bordersList.size()!=4) return false;
00280     for (size_t i=1; i<m_bordersList.size(); ++i) {
00281       if (m_bordersList[i]!=m_bordersList[0])
00282         return false;
00283     }
00284     return true;
00285   }
00287   std::vector<MWAWBorder> const &borders() const
00288   {
00289     return m_bordersList;
00290   }
00292   void resetBorders()
00293   {
00294     m_bordersList.resize(0);
00295   }
00297   void setBorders(int wh, MWAWBorder const &border);
00299   friend std::ostream &operator<<(std::ostream &o, MWAWGraphicStyle const &st);
00301   void addTo(librevenge::RVNGPropertyList &pList, bool only1d=false) const;
00303   void addFrameTo(librevenge::RVNGPropertyList &pList) const;
00305   int cmp(MWAWGraphicStyle const &a) const;
00306 
00308   float m_lineWidth;
00310   std::vector<float> m_lineDashWidth;
00312   LineCap m_lineCap;
00314   LineJoin m_lineJoin;
00316   float m_lineOpacity;
00318   MWAWColor m_lineColor;
00320   bool m_fillRuleEvenOdd;
00322   MWAWColor m_surfaceColor;
00324   float m_surfaceOpacity;
00325 
00327   MWAWColor m_shadowColor;
00329   float m_shadowOpacity;
00331   MWAWVec2f m_shadowOffset;
00332 
00334   Pattern m_pattern;
00335 
00337   GradientType m_gradientType;
00339   std::vector<GradientStop> m_gradientStopList;
00341   float m_gradientAngle;
00343   float m_gradientBorder;
00345   MWAWVec2f m_gradientPercentCenter;
00347   float m_gradientRadius;
00348 
00350   bool m_arrows[2];
00351 
00352   //
00353   // related to the frame
00354   //
00355 
00357   MWAWColor m_backgroundColor;
00359   float m_backgroundOpacity;
00361   std::vector<MWAWBorder> m_bordersList;
00363   std::string m_frameName;
00365   std::string m_frameNextName;
00366 
00367   //
00368   // some transformation: must probably be somewhere else
00369   //
00370 
00372   float m_rotate;
00374   bool m_flip[2];
00375 
00377   std::string m_extra;
00378 };
00379 #endif
00380 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: