00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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;
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
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
00367
00368
00370 float m_rotate;
00372 bool m_flip[2];
00373
00375 std::string m_extra;
00376 };
00377 #endif
00378