00001
00030 #ifndef INC_RVC_STYLEPATTERNLINE_H
00031 #define INC_RVC_STYLEPATTERNLINE_H
00032
00033 #ifndef INC_RVC_STYLEPATTERNBASE_H
00034 #include <rvc/stylepatternbase.h>
00035 #endif
00036
00037 #ifndef INC_MI32_MG2ENUMS_H
00038 #include <mi32/mg2enums.h>
00039 #endif
00040
00041 namespace RVC {
00042
00044 class STYLEPATTERN_LINE : public STYLEPATTERN_BASE {
00045 public:
00046
00047 enum ELEMENT_TYPE {
00048 ELEMENT_TYPE_Line = 0,
00049 ELEMENT_TYPE_CrossLine = 1,
00050 ELEMENT_TYPE_Circle = 2,
00051 ELEMENT_TYPE_Polyline = 3,
00052 ELEMENT_TYPE_Polygon = 4,
00053 ELEMENT_TYPE_Text = 5,
00054 ELEMENT_TYPE_Symbol = 6,
00055 ELEMENT_TYPE_COUNT
00056 };
00057
00058 class ITERATOR;
00059 class ELEMENT;
00060
00063 class ELEMENT_SHARED {
00064 public:
00065
00068 MGD::LINECAP GetCapStyle (
00069 ) const { return ((m_pData->flags & LINEPATTELEM::FLAG_CapRound) ? MGD::LINECAP_Round : MGD::LINECAP_Butt); }
00070
00073 UINT8 GetColorIndex (
00074 ) const { return (m_pData->colornum); }
00075
00076 bool GetFilled (
00077 ) const { return ((m_pData->flags & LINEPATTELEM::FLAG_Filled) != 0); }
00078
00081 INT16 GetInterval (
00082 ) const { return (m_pData->xspacing); }
00083
00084 MGD::LINEJOIN GetJoinStyle (
00085 ) const { return ((m_pData->flags & LINEPATTELEM::FLAG_JoinMiter) ? MGD::LINEJOIN_Miter : (m_pData->flags & LINEPATTELEM::FLAG_JoinBevel) ? MGD::LINEJOIN_Bevel : MGD::LINEJOIN_Round); }
00086
00089 INT16 GetOffsetAlong (
00090 ) const { return (m_pData->xoffset); }
00091
00094 INT16 GetOffsetAside (
00095 ) const { return ((m_pData->type != ELEMENT_TYPE_Line) ? -m_pData->yoffset : m_pData->yoffset); }
00096
00099 INT16 GetSize (
00100 ) const { return (m_pData->xsize); }
00101
00104 INT16 GetThickness (
00105 ) const { return (m_pData->thickness); }
00106
00109 ELEMENT_TYPE GetType (
00110 ) const { return (static_cast<ELEMENT_TYPE>(m_pData->type)); }
00111
00114 bool IsFilled (
00115 ) const { return ((m_pData->flags & LINEPATTELEM::FLAG_Filled) != 0); }
00116
00117 protected:
00118
00119 struct LINEPATTELEM {
00120 enum TYPE {
00121 TYPE_Line = 0,
00122 TYPE_CrossLine,
00123 TYPE_Circle,
00124 TYPE_PolyLine,
00125 TYPE_Polygon,
00126 TYPE_Last = TYPE_Polygon
00127 };
00128
00129 enum FLAGS {
00130 FLAG_Filled = 0x0001,
00131 FLAG_JoinMiter = 0x0002,
00132 FLAG_JoinBevel = 0x0004,
00133 FLAG_CapRound = 0x0008
00134 };
00135
00136 INT16 extrabytes;
00137 UINT8 type;
00138 UINT8 colornum;
00139 UINT16 flags;
00140 INT16 xoffset;
00141 INT16 xspacing;
00142 INT16 yoffset;
00143 INT16 xsize;
00144 INT16 thickness;
00145 };
00146
00147
00148 private:
00149 #ifndef GENERATING_DOXYGEN_OUTPUT
00150
00151 const LINEPATTELEM *m_pData;
00152 void *m_pExtra;
00153
00155 ELEMENT_SHARED (
00156 ): m_pData(0), m_pExtra(0) { }
00157
00158 explicit ELEMENT_SHARED (const void *pElemData)
00159 : m_pData(static_cast<const LINEPATTELEM*>(pElemData)), m_pExtra(static_cast<UINT8*>(const_cast<void*>(pElemData)) + sizeof(LINEPATTELEM))
00160 { }
00161
00163 ~ELEMENT_SHARED (
00164 ) { }
00165
00166 friend class RVC::STYLEPATTERN_LINE;
00167 friend class ELEMENT;
00168 friend class ITERATOR;
00169 #endif // GENERATING_DOXYGEN_OUTPUT
00170 };
00171
00173 class ELEMENT : public ELEMENT_SHARED {
00174 public:
00175
00177 ELEMENT (
00178 ) { memset(&m_MyData,0,sizeof(m_MyData)); m_pData = &m_MyData; }
00179
00181 ELEMENT (
00182 const ELEMENT& rhs
00183 );
00184
00186 ELEMENT (
00187 const ELEMENT_SHARED& rhs
00188 );
00189
00191 explicit ELEMENT (
00192 ELEMENT_TYPE type
00193 );
00194
00196 ~ELEMENT (
00197 ) { if (m_pExtra != 0) free(m_pExtra); }
00198
00200 ELEMENT& operator= (
00201 const ELEMENT& rhs
00202 );
00203
00205 ELEMENT& operator= (
00206 const ELEMENT_SHARED& rhs
00207 );
00208
00210 void SetCapStyle (
00211 MGD::LINECAP linecap
00212 ) { if (linecap == MGD::LINECAP_Round) m_MyData.flags |= LINEPATTELEM::FLAG_CapRound; else m_MyData.flags &= ~LINEPATTELEM::FLAG_CapRound; }
00213
00215 void SetColorIndex (
00216 UINT8 idx
00217 ) { m_MyData.colornum = idx; }
00218
00219 void SetFilled (
00220 bool filled
00221 ) { if (filled) m_MyData.flags |= LINEPATTELEM::FLAG_Filled; else m_MyData.flags &= ~LINEPATTELEM::FLAG_Filled; }
00222
00223 void SetInterval (
00224 INT16 interval
00225 ) { m_MyData.xspacing = interval; }
00226
00227 void SetJoinStyle (
00228 MGD::LINEJOIN linejoin
00229 ) {
00230 m_MyData.flags &= ~(LINEPATTELEM::FLAG_JoinMiter|LINEPATTELEM::FLAG_JoinBevel);
00231 if (linejoin == MGD::LINEJOIN_Miter) m_MyData.flags |= LINEPATTELEM::FLAG_JoinMiter;
00232 else if (linejoin == MGD::LINEJOIN_Bevel) m_MyData.flags |= LINEPATTELEM::FLAG_JoinBevel;
00233 }
00234
00235 void SetOffsetAlong (
00236 INT16 offset
00237 ) { m_MyData.xoffset = offset; }
00238
00239 void SetOffsetAside (
00240 INT16 offset
00241 ) { m_MyData.yoffset = (m_MyData.type != ELEMENT_TYPE_Line) ? -offset : offset; }
00242
00243 void SetSize (
00244 INT16 size
00245 ) { m_MyData.xsize = size; }
00246
00247 void SetThickness (
00248 INT16 thickness
00249 ) { m_MyData.thickness = thickness; }
00250
00251 private:
00252 #ifndef GENERATING_DOXYGEN_OUTPUT
00253 ELEMENT_SHARED::LINEPATTELEM m_MyData;
00254 #endif // GENERATING_DOXYGEN_OUTPUT
00255 };
00256
00258 class ITERATOR {
00259 public:
00260
00262 ITERATOR (
00263 ): m_pEnd(0) { }
00264
00266 ~ITERATOR (
00267 ) { }
00268
00270 const ELEMENT_SHARED& operator* (
00271 ) const { return (m_element); }
00272
00274 const ELEMENT_SHARED* operator-> (
00275 ) const { return (&m_element); }
00276
00278 ITERATOR& operator++ ();
00279
00281 bool operator== (
00282 const ITERATOR& rhs
00283 ) const { return ((m_pEnd == 0 && rhs.m_pEnd == 0) || m_element.m_pData == rhs.m_element.m_pData); }
00284
00286 bool operator!= (
00287 const ITERATOR& rhs
00288 ) const { return (!(*this == rhs)); }
00289
00290 private:
00291 #ifndef GENERATING_DOXYGEN_OUTPUT
00292
00293 ELEMENT_SHARED m_element;
00294 const void *m_pEnd;
00295
00296 ITERATOR (const void *pData, const void *pEnd)
00297 : m_element(pData), m_pEnd(pEnd)
00298 { }
00299
00300 friend class RVC::STYLEPATTERN_LINE;
00301 #endif // GENERATING_DOXYGEN_OUTPUT
00302 };
00303
00305 STYLEPATTERN_LINE (
00306 ) : STYLEPATTERN_BASE(PATTERNTYPE_Line, sizeof(PATTERNHEADER_LINE)) {}
00307
00309 STYLEPATTERN_LINE (
00310 const void* buf,
00311 INT32 NumBytes
00312 ) : STYLEPATTERN_BASE(PATTERNTYPE_Line, sizeof(PATTERNHEADER_LINE)) {
00313 SetPattern(buf, NumBytes, sizeof(PATTERNHEADER_LINE));
00314 }
00315
00317 STYLEPATTERN_LINE (
00318 const STYLEPATTERN_LINE& rhs
00319 ) : STYLEPATTERN_BASE(rhs) {}
00320
00322 virtual ~STYLEPATTERN_LINE (
00323 ) { }
00324
00326 STYLEPATTERN_LINE& operator= (
00327 const STYLEPATTERN_LINE& rhs
00328 ) { if (this != &rhs) { STYLEPATTERN_BASE::operator=(rhs); } return (*this); }
00329
00331 ITERATOR Begin (
00332 ) const { return (ITERATOR(GetFirstElemPtr(),GetPattBuffer()+GetSize())); }
00333
00336 ERRVALUE DeleteElement (
00337 unsigned idx
00338 );
00339
00342 void DeleteUnusedColors (
00343 );
00344
00346 ITERATOR End (
00347 #ifdef WIN32
00348 ) const { return (ITERATOR()); }
00349 #else
00350 ) const { ITERATOR it; return (it); }
00351 #endif
00352
00355 ELEMENT GetElement (
00356 unsigned idx
00357 ) const;
00358
00360 INT16 GetExtentLeft (
00361 ) const { return (reinterpret_cast<PATTERNHEADER_LINE*>(m_PattBuff)->extentsa); }
00362
00364 INT16 GetExtentRight (
00365 ) const { return (reinterpret_cast<PATTERNHEADER_LINE*>(m_PattBuff)->extentsb); }
00366
00369 ERRVALUE InsertElement (
00370 unsigned idx,
00371 const ELEMENT& element
00372 );
00373
00376 ERRVALUE SetElement (
00377 unsigned idx,
00378 const ELEMENT& element
00379 );
00380
00382 INT32 GetWidth (
00383 ) const;
00384
00385 private:
00386 #ifndef GENERATING_DOXYGEN_OUTPUT
00388 struct PATTERNHEADER_LINE : public STYLEPATTERN_BASE::PATTERNHEADER {
00389 INT16 extentsa;
00390 INT16 extentsb;
00391 };
00392
00393 ERRVALUE BuildOffsetIndex () const;
00394 INT32 GetOffset (unsigned idx) const;
00395 #endif // GENERATING_DOXYGEN_OUTPUT
00396 };
00397
00398 }
00399
00400 #endif
00401