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 "libwpd/libwpd.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     }
00064     int cmp(GradientStop const &a) const {
00065       if (m_offset < a.m_offset) return -1;
00066       if (m_offset > a.m_offset) return 1;
00067       if (m_color < a.m_color) return -1;
00068       if (m_color > a.m_color) return 1;
00069       if (m_opacity < a.m_opacity) return -1;
00070       if (m_opacity > a.m_opacity) return 1;
00071       return 0;
00072     }
00074     friend std::ostream &operator<<(std::ostream &o, GradientStop const &st) {
00075       o << "offset=" << st.m_offset << ",";
00076       o << "color=" << st.m_color << ",";
00077       if (st.m_opacity<1.0)
00078         o << "opacity=" << st.m_opacity*100.f << "%,";
00079       return o;
00080     }
00082     float m_offset;
00084     MWAWColor m_color;
00086     float m_opacity;
00087   };
00092   struct Pattern {
00094     Pattern() : m_dim(0,0), m_data(), m_picture(), m_pictureMime(""), m_pictureAverageColor(MWAWColor::white()) {
00095       m_colors[0]=MWAWColor::black();
00096       m_colors[1]=MWAWColor::white();
00097     }
00099     Pattern(Vec2i dim, WPXBinaryData const &picture, std::string const &mime, MWAWColor const &avColor) :
00100       m_dim(dim), m_data(), m_picture(picture), m_pictureMime(mime), m_pictureAverageColor(avColor) {
00101       m_colors[0]=MWAWColor::black();
00102       m_colors[1]=MWAWColor::white();
00103     }
00105     virtual ~Pattern() {}
00107     bool empty() const {
00108       if (m_dim[0]==0 || m_dim[1]==0) return true;
00109       if (m_picture.size()) return false;
00110       if (m_dim[0]!=8 && m_dim[0]!=16 && m_dim[0]!=32) return true;
00111       return m_data.size()!=size_t((m_dim[0]/8)*m_dim[1]);
00112     }
00114     bool getAverageColor(MWAWColor &col) const;
00116     bool getUniqueColor(MWAWColor &col) const;
00118     bool getBinary(WPXBinaryData &data, std::string &type) const;
00119 
00121     int cmp(Pattern const &a) const {
00122       int diff = m_dim.cmp(a.m_dim);
00123       if (diff) return diff;
00124       if (m_data.size() < a.m_data.size()) return -1;
00125       if (m_data.size() > a.m_data.size()) return 1;
00126       for (size_t h=0; h < m_data.size(); ++h) {
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         if (m_colors[i] < a.m_colors[i]) return 1;
00132         if (m_colors[i] > a.m_colors[i]) return -1;
00133       }
00134       if (m_pictureAverageColor < a.m_pictureAverageColor) return 1;
00135       if (m_pictureAverageColor > a.m_pictureAverageColor) return -1;
00136       if (m_pictureMime < a.m_pictureMime) return 1;
00137       if (m_pictureMime > a.m_pictureMime) return -1;
00138       if (m_picture.size() < a.m_picture.size()) return 1;
00139       if (m_picture.size() > a.m_picture.size()) return -1;
00140       const unsigned char *ptr=m_picture.getDataBuffer();
00141       const unsigned char *aPtr=a.m_picture.getDataBuffer();
00142       for (unsigned long h=0; h < m_picture.size(); ++h, ++ptr, ++aPtr) {
00143         if (*ptr < *aPtr) return 1;
00144         if (*ptr > *aPtr) return -1;
00145       }
00146       return 0;
00147     }
00149     friend std::ostream &operator<<(std::ostream &o, Pattern const &pat) {
00150       o << "dim=" << pat.m_dim << ",";
00151       if (pat.m_picture.size()) {
00152         o << "type=" << pat.m_pictureMime << ",";
00153         o << "col[average]=" << pat.m_pictureAverageColor << ",";
00154       } else {
00155         if (!pat.m_colors[0].isBlack()) o << "col0=" << pat.m_colors[0] << ",";
00156         if (!pat.m_colors[1].isWhite()) o << "col1=" << pat.m_colors[1] << ",";
00157         o << "[";
00158         for (size_t h=0; h < pat.m_data.size(); ++h)
00159           o << std::hex << (int) pat.m_data[h] << std::dec << ",";
00160         o << "],";
00161       }
00162       return o;
00163     }
00165     Vec2i m_dim;
00166 
00168     MWAWColor m_colors[2];
00170     std::vector<unsigned char> m_data;
00171   protected:
00173     WPXBinaryData m_picture;
00175     std::string m_pictureMime;
00177     MWAWColor m_pictureAverageColor;
00178   };
00180   MWAWGraphicStyle() :  m_lineWidth(1), m_lineDashWidth(), m_lineCap(C_Butt), m_lineJoin(J_Miter), m_lineOpacity(1), m_lineColor(MWAWColor::black()),
00181     m_fillRuleEvenOdd(false), m_surfaceColor(MWAWColor::white()), m_surfaceOpacity(0),
00182     m_shadowColor(MWAWColor::black()), m_shadowOpacity(0), m_shadowOffset(1,1),
00183     m_pattern(),
00184     m_gradientType(G_None), m_gradientStopList(), m_gradientAngle(0), m_gradientBorder(0), m_gradientPercentCenter(0.5f,0.5f), m_gradientRadius(1),
00185     m_rotate(0), m_extra("") {
00186     m_arrows[0]=m_arrows[1]=false;
00187     m_flip[0]=m_flip[1]=false;
00188     m_gradientStopList.push_back(GradientStop(0.0, MWAWColor::white()));
00189     m_gradientStopList.push_back(GradientStop(1.0, MWAWColor::black()));
00190   }
00192   virtual ~MWAWGraphicStyle() { }
00194   bool hasLine() const {
00195     return m_lineWidth>0 && m_lineOpacity>0;
00196   }
00198   void setSurfaceColor(MWAWColor const &col, float opacity = 1) {
00199     m_surfaceColor = col;
00200     m_surfaceOpacity = opacity;
00201   }
00203   bool hasSurfaceColor() const {
00204     return m_surfaceOpacity > 0;
00205   }
00207   void setPattern(Pattern const &pat) {
00208     m_pattern=pat;
00209   }
00211   bool hasPattern() const {
00212     return !m_pattern.empty();
00213   }
00215   bool hasGradient(bool complex=false) const {
00216     return m_gradientType != G_None && m_gradientStopList.size() >= (complex ? 3 : 2);
00217   }
00219   bool hasSurface() const {
00220     return hasSurfaceColor() || hasPattern() || hasGradient();
00221   }
00223   void setShadowColor(MWAWColor const &col, float opacity = 1) {
00224     m_shadowColor = col;
00225     m_shadowOpacity = opacity;
00226   }
00228   bool hasShadow() const {
00229     return m_shadowOpacity > 0;
00230   }
00232   friend std::ostream &operator<<(std::ostream &o, MWAWGraphicStyle const &st);
00234   void addTo(WPXPropertyList &pList, WPXPropertyListVector &gradient, bool only1d=false) const;
00235 
00237   int cmp(MWAWGraphicStyle const &a) const;
00238 
00240   float m_lineWidth;
00242   std::vector<float> m_lineDashWidth;
00244   LineCap m_lineCap;
00246   LineJoin m_lineJoin;
00248   float m_lineOpacity;
00250   MWAWColor m_lineColor;
00252   bool m_fillRuleEvenOdd;
00254   MWAWColor m_surfaceColor;
00256   float m_surfaceOpacity;
00257 
00259   MWAWColor m_shadowColor;
00261   float m_shadowOpacity;
00263   Vec2f m_shadowOffset;
00264 
00266   Pattern m_pattern;
00267 
00269   GradientType m_gradientType;
00271   std::vector<GradientStop> m_gradientStopList;
00273   float m_gradientAngle;
00275   float m_gradientBorder;
00277   Vec2f m_gradientPercentCenter;
00279   float m_gradientRadius;
00280 
00282   bool m_arrows[2];
00283 
00284   // some transformation: must probably be somewhere else
00285 
00287   float m_rotate;
00289   bool m_flip[2];
00290 
00292   std::string m_extra;
00293 };
00294 #endif
00295 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: