filters

structures.h

00001 /* This file is part of the LibMSWrite Library
00002    Copyright (C) 2001-2003 Clarence Dang <clarencedang@users.sourceforge.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License Version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License Version 2 for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    Version 2 along with this library; see the file COPYING.LIB.  If not,
00015    write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 
00018    LibMSWrite Project Website:
00019    http://sourceforge.net/projects/libmswrite/
00020 */
00021 
00022 #ifndef __STRUCTURES_H__
00023 #define __STRUCTURES_H__
00024 
00025 #include "structures_generated.h"
00026 #include "structures_private.h"
00027 
00028 namespace MSWrite
00029 {
00030     class Format
00031     {
00032     public:
00033         static const Word Write_3_0 = 0xBE31;
00034         static const Word Write_3_1 = 0xBE32;
00035     };
00036 
00037 
00038     class PageLayout : public PageLayoutGenerated,
00039                                 public NeedsHeader
00040     {
00041     private:
00042         int m_numModified;
00043 
00044         bool readFromDevice (void); friend class InternalGenerator;
00045         bool writeToDevice (void);  friend class InternalParser;
00046 
00047         // the defaults of course
00048         static const Byte magic102Default = Byte (102);
00049         static const Word magic512Default = Word (512);
00050         static const Word pageHeightDefault = Word (Inch2Twip (11));
00051         static const Word pageWidthDefault = Word (Inch2Twip (8.5));
00052         static const Word pageNumberStartDefault = Word (1);
00053         static const Word topMarginDefault = Word (Inch2Twip (1));
00054         static const Word textHeightDefault = Word (Inch2Twip (9));
00055         static const Word leftMarginDefault = Word (Inch2Twip (1.25));
00056         static const Word textWidthDefault = Word (Inch2Twip (6));
00057         static const Word magic256Default = Word (256);
00058         static const Word headerFromTopDefault = Word (Inch2Twip (0.75));
00059         static const Word footerFromTopDefault = Word (Inch2Twip (10.25 /*11.0 (m_pageHeight) - 0.75*/));
00060         static const Word magic720Default = Word (720);
00061         static const Word zeroDefault = Word (0);
00062         static const Word magic1080Default = Word (1080);
00063         // no reliable default for m_unknown
00064         static const Word zero2Default = Word (0);
00065 
00066     public:
00067         PageLayout ();
00068         virtual ~PageLayout ();
00069 
00070         PageLayout &operator= (const PageLayout &rhs);
00071 
00072         bool getIsModified (void) const {   return m_numModified > 0;   }
00073 
00074         #define PageLayoutModify(variable,value)                                        \
00075         {                                                                                           \
00076             if (m_##variable != value)  /* don't skew m_numModified count */    \
00077             {                                                                                       \
00078                 if (value == variable##Default)                                         \
00079                     --m_numModified;                                                            \
00080                 else                                                                                \
00081                     m_numModified++;                                                            \
00082                 m_##variable = value;                                                       \
00083             }                                                                                       \
00084         }
00085 
00086         Word getPageNumberStart (const bool purist = false) const
00087         {
00088             if (purist)
00089                 return m_pageNumberStart;
00090 
00091             if (m_pageNumberStart == Word (0xFFFF))
00092                 return 1;
00093             else
00094                 return m_pageNumberStart;
00095         }
00096         void setPageNumberStart (const Word val)    {   PageLayoutModify (pageNumberStart, val);    }
00097 
00098         //
00099         // since these are calculated values,
00100         // there can't be corresponding set functions
00101         // (how do I know what value you want to change?)
00102         //
00103         Word getBottomMargin (void) const
00104         {
00105             return getPageHeight () - getTopMargin () - getTextHeight ();
00106         }
00107 
00108         Word getRightMargin (void) const
00109         {
00110             return getPageWidth () - getLeftMargin () - getTextWidth ();
00111         }
00112 
00113 
00114         //
00115         // get and set functions (could not generated because we want to keep a
00116         // "modified" counter)
00117         //
00118 
00119         Word getPageHeight (void) const {   return m_pageHeight;    }
00120         void setPageHeight (const Word val) {   PageLayoutModify (pageHeight, val); }
00121 
00122         Word getPageWidth (void) const  {   return m_pageWidth; }
00123         void setPageWidth (const Word val)  {   PageLayoutModify (pageWidth, val);  }
00124 
00125         Word getTopMargin (void) const  {   return m_topMargin; }
00126         void setTopMargin (const Word val)  {   PageLayoutModify (topMargin, val);  }
00127 
00128         Word getTextHeight (void) const {   return m_textHeight;    }
00129         void setTextHeight (const Word val) {   PageLayoutModify (textHeight, val); }
00130 
00131         Word getLeftMargin (void) const {   return m_leftMargin;    }
00132         void setLeftMargin (const Word val) {   PageLayoutModify (leftMargin, val); }
00133 
00134         Word getTextWidth (void) const  {   return m_textWidth; }
00135         void setTextWidth (const Word val)  {   PageLayoutModify (textWidth, val);  }
00136 
00137         Word getHeaderFromTop (void) const  {   return m_headerFromTop; }
00138         void setHeaderFromTop (const Word val)  {   PageLayoutModify (headerFromTop, val);  }
00139 
00140         Word getFooterFromTop (void) const  {   return m_footerFromTop; }
00141         void setFooterFromTop (const Word val)  {   PageLayoutModify (footerFromTop, val);  }
00142     };
00143 
00144 
00145     class Font : public FontGenerated
00146     {
00147     private:
00148         Byte *m_name;
00149 
00150         friend class FontTable;
00151             bool readFromDevice (void);
00152             bool writeToDevice (void);
00153 
00154     public:
00155         enum Family
00156         {
00157             DontCare        = 0x00,
00158             Roman           = 0x10, Times           = 0x10, Serif           = 0x10,
00159             Swiss           = 0x20, Helvetica   = 0x20, SansSerif   = 0x20,
00160             Modern      = 0x30, Courier     = 0x30, TypeWriter  = 0x30,
00161             Script      = 0x40,
00162             Decorative  = 0x50, OldEnglish  = 0x50
00163         };
00164 
00165         Font (const Byte *name = NULL, const Byte family = DontCare);
00166         virtual ~Font ();
00167 
00168         Font &operator= (const Font &rhs);
00169 
00170         Byte *getName (void) const  {   return m_name;  }
00171         Byte *setName (const Byte *s)
00172         {
00173 #if 0 // TODO fix
00174         #ifdef CHECK_INTERNAL
00175             if (!m_device)
00176                 CHECK_DEVICE_ERROR;
00177         #endif
00178 
00179             if (!s)
00180             {
00181                 m_device->error (Error::InternalError, "NULL fontName passed to Font::setName\n");
00182                 return m_name = NULL;
00183             }
00184 #endif
00185             int length = strlen ((const char *) s) + 1 /* NUL */;
00186 
00187             delete [] m_name;
00188             m_name = new Byte [length];
00189             if (!m_name)
00190                 m_device->error (Error::OutOfMemory, "could not allocate memory for fontName\n");
00191             else
00192                 strcpy ((char *) m_name, (const char *) s);
00193 
00194             FontGenerated::m_numDataBytes = sizeof (m_family) + length;
00195             
00196             return m_name;
00197         }
00198 
00199         bool operator!= (const Font &rhs)
00200         {
00201             // if their m_family's are different, it's not my problem...
00202             return strcmp ((const char *) this->m_name, (const char *) rhs.m_name) != 0;
00203         }
00204 
00205         bool operator== (const Font &rhs)
00206         {
00207             // if their m_family's are different, it's not my problem...
00208             return strcmp ((const char *) this->m_name, (const char *) rhs.m_name) == 0;
00209         }
00210 
00211     private:
00212         Font (const Font &rhs);
00213     };
00214 
00215 
00216     class FontTable;    // from structures_private.h
00217     class FormatCharProperty : public FormatCharPropertyGenerated
00218     {
00219     private:
00220         DWord m_afterEndCharByte;   // from the FormatPointer that points to us
00221         FontTable *m_fontTable; // pointer to fontTable (valid only during & after FormatInfoPage::(readFromDevice|add))
00222         Font m_font;    // temporarily store font until we get the fontTable
00223 
00224         Word getFontCode (void) const
00225         {
00226             return ((Word) getFontCodeLow ()) | (((Word) getFontCodeHigh ()) << 6);
00227         }
00228 
00229         void setFontCode (const Word code)
00230         {
00231             setFontCodeHigh ((code >> 6) & BitMask3);   // OPT: I don't think we really need & BitMask3
00232             setFontCodeLow (code & BitMask6);
00233         }
00234 
00235         friend class FormatInfoPage;
00236         friend class FormatInfo;
00237         friend class InternalParser;
00238         friend class InternalGenerator;
00239             bool readFromDevice (void);
00240             bool writeToDevice (void);
00241         
00242             void setFontTable (FontTable *fontTable)    {   m_fontTable = fontTable;    }
00243         
00244             DWord getAfterEndCharByte (void) const  {   return m_afterEndCharByte;  }
00245             void setAfterEndCharByte (const DWord b)    {   m_afterEndCharByte = b; }
00246         
00247             // convenience functions
00248             DWord getEndCharByte (void) const   {   return m_afterEndCharByte - 1;  }
00249             void setEndCharByte (const DWord b) {   m_afterEndCharByte = b + 1; }
00250 
00251     public:
00252         FormatCharProperty ();
00253         virtual ~FormatCharProperty ();
00254 
00255         FormatCharProperty &operator= (const FormatCharProperty &rhs);
00256 
00257         const Font *getFont (void) const
00258         {
00259             return &m_font;
00260         }
00261 
00262         void setFont (const Font *font)
00263         {
00264             m_font = *font;
00265         }
00266 
00267         // [PRIVATE] called by FormatCharProperty::readFromDevice and other places too
00268         bool updateFont (void);
00269         // [PRIVATE] called by FormatInfoPage::add
00270         bool updateFontCode (void);
00271 
00272         Byte getFontSizeHalfPoints (void) const {   return m_fontSize;  }
00273         void setFontSizeHalfPoints (const Byte val)
00274         {
00275             m_fontSize = val;
00276             signalHaveSetData (m_fontSize == fontSizeDefault, (2 * 8)/*offset*/ + (1 * 8)/*size*/);
00277         }
00278 
00279         // loss of accuracy but look, would you prefer it in half-points or twips instead? :)
00280         Byte getFontSize (void) const   {   return getFontSizeHalfPoints () / 2;    }
00281         void setFontSize (const Byte val)   {   setFontSizeHalfPoints (val * 2);    }
00282 
00283         bool getIsNormalPosition (void) const   {   return getPosition () == 0; }
00284         void setIsNormalPosition (void) {   setPosition (0);    }
00285 
00286         bool getIsSuperscript (void) const  {   return getPosition () >= 1 && getPosition () <= 127;    }
00287         void setIsSuperscript (void)    {   setPosition (4);    /* common value (sometimes 10, but) */  }
00288 
00289         bool getIsSubscript (void) const    {   return getPosition () >= 128;   }
00290         void setIsSubscript (void)  {   setPosition (252);  /* common value */  }
00291 
00292         // compares if the contents are the same (not if it points to the same place etc. etc.)
00293         bool operator== (FormatCharProperty &rhs);
00294     };
00295 
00296     
00297     class FormatParaPropertyTabulator : public FormatParaPropertyTabulatorGenerated
00298     {
00299     private:
00300         friend class FormatParaPropertyGenerated;
00301         friend class FormatParaProperty;
00302             bool readFromDevice (void);
00303             bool writeToDevice (void);
00304 
00305     public:
00306         FormatParaPropertyTabulator ();
00307         virtual ~FormatParaPropertyTabulator ();
00308 
00309         FormatParaPropertyTabulator &operator= (const FormatParaPropertyTabulator &rhs);
00310         
00311         // you can use getType()/setType() if you really want to...
00312         bool getIsNormal (void) const   {   return m_type == 0; }
00313         void setIsNormal (const bool yes = true)    {   m_type = (yes ? 0 : 3); }
00314 
00315         bool getIsDecimal (void) const  {   return m_type == 3; }
00316         void setIsDecimal (const bool yes = true)   {   m_type = (yes ? 3 : 0); }
00317 
00318         // is this a sentinel tabulator?
00319         bool getIsDummy (void) const    {   return m_indent == 0;   }
00320     };
00321 
00322 
00323     class Alignment
00324     {
00325     public:
00326         static const int Left           =   0;
00327         static const int Centre         =   1;
00328         static const int Center         =   1;
00329         static const int Right          =   2;
00330         static const int Justify        =   3;
00331     };
00332 
00333     // lazy synonym
00334     class Align : public Alignment {};
00335 
00336     class LineSpacing
00337     {
00338     public:
00339         static const int Normal         =   240;
00340         static const int Single         =   240;
00341         static const int OneAndAHalf    =   360;
00342         static const int Double         =   480;
00343     };
00344 
00345     class FormatParaProperty : public FormatParaPropertyGenerated
00346     {
00347     private:
00348         DWord m_afterEndCharByte;   // from the FormatPointer that points to us
00349         Word m_leftMargin, m_rightMargin;   // needed to adjust leftIndent & rightIndent in header/footer
00350         int m_numTabulators;
00351         bool m_addedTooManyTabs;
00352 
00353         friend class FormatInfoPage;
00354         friend class FormatInfo;
00355         friend class InternalParser;
00356         friend class InternalGenerator;
00357             bool readFromDevice (void);
00358             bool writeToDevice (void);
00359             
00360             void setMargins (const Word leftMargin, const Word rightMargin)
00361             {
00362                 m_leftMargin = leftMargin;
00363                 m_rightMargin = rightMargin;
00364             }
00365 
00366             DWord getAfterEndCharByte (void) const  {   return m_afterEndCharByte;  }
00367             void setAfterEndCharByte (const DWord b)    {   m_afterEndCharByte = b; }
00368 
00369             // convenience functions
00370             DWord getEndCharByte (void) const   {   return m_afterEndCharByte - 1;  }
00371             void setEndCharByte (const DWord b) {   m_afterEndCharByte = b + 1; }
00372 
00373     public:
00374         FormatParaProperty ();
00375         virtual ~FormatParaProperty ();
00376 
00377         FormatParaProperty &operator= (const FormatParaProperty &rhs);
00378         
00379         // convenience functions
00380         Byte getAlign (void) const  {   return getAlignment (); }
00381         void setAlign (const Byte val)  {   setAlignment (val); }
00382         
00383         Short getLeftIndentFirstLine (const bool purist = false) const
00384         {
00385             // Write _always_ ignores "First Line Indent" if it's an object
00386             if (getIsObject () && !purist)
00387             {
00388             #ifdef DEBUG_PARA
00389                 if (m_leftIndentFirstLine)
00390                 #ifdef CHECK_INTERNAL
00391                     if (m_device)
00392                 #endif
00393                         m_device->debug ("user specified leftIndentFirstLine for an object=", m_leftIndentFirstLine);
00394                 #ifdef CHECK_INTERNAL
00395                     else
00396                         CHECK_DEVICE_ERROR;
00397                 #endif
00398             #endif
00399 
00400                 return 0;
00401             }
00402             else
00403                 return m_leftIndentFirstLine;
00404         }
00405         void setLeftIndentFirstLine (const Word val)
00406         {
00407             m_leftIndentFirstLine = val;
00408             signalHaveSetData (m_leftIndentFirstLine == leftIndentFirstLineDefault,
00409                                         8 * 8/*offset*/ + 2 * 8/*size*/);
00410         }
00411 
00412         // [PRIVATE] called by FormatInfoPage::add
00413         bool updateIndents (void)
00414         {
00415             if (getIsNotNormalParagraph ())
00416             {
00417                 m_leftIndent += m_leftMargin;
00418                 m_rightIndent += m_rightMargin;
00419             }
00420 
00421             return true;
00422         }
00423         
00424         bool getIsText (void) const {   return !getIsObject (); }
00425         void setIsText (const bool val) {   setIsObject (!val); }
00426 
00427         bool getIsNormalParagraph (void) const  {   return !getIsNotNormalParagraph (); }
00428         void setIsNormalParagraph (const bool val = true)   {   setIsNotNormalParagraph (!val); }
00429         
00430         bool getIsHeader (void) const   {   return getIsNotNormalParagraph () && getHeaderOrFooter () == 0; }
00431         void setIsHeader (const bool val)
00432         {
00433             setIsNormalParagraph (false);
00434             setHeaderOrFooter (val ? 0 : 1);
00435         }
00436 
00437         bool getIsFooter (void) const   {   return getIsNotNormalParagraph () && getHeaderOrFooter () == 1; }
00438         void setIsFooter (const bool val)
00439         {
00440             setIsNormalParagraph (false);
00441             setHeaderOrFooter (val ? 1 : 0);
00442         }
00443 
00444         Word getNumTabulator (void) const   {   return m_numTabulators; }
00445         const FormatParaPropertyTabulator *getTabulator (const int which) const
00446         {
00447             if (which > m_numTabulators) return NULL;
00448             return m_tab [which];
00449         }
00450 
00451         bool addTabulator (FormatParaPropertyTabulator *fpp)
00452         {
00453             if (m_numTabulators >= 14)
00454             {
00455                 // we can't return false yet because there may be no m_device
00456                 // so we will return false in writeToDevice() instead
00457                 m_addedTooManyTabs = true;
00458                 return true;
00459             }
00460     
00461             *m_tab [m_numTabulators++] = *fpp;
00462 
00463             // OPT: could use fewer bytes if Tabulator can do so
00464             signalHaveSetData (false/*probably not default*/, (22 + m_numTabulators * FormatParaPropertyTabulator::s_size) * 8);
00465             return true;
00466         }
00467 
00468         // compares if the contents are the same (not if it points to the same place etc. etc.)
00469         bool operator== (FormatParaProperty &rhs);
00470     };
00471     
00472 
00473     class ObjectType
00474     {
00475     public:
00476         static const int NotObject = 0;
00477         static const int Bitmap = 1, BMP = 1;
00478         static const int WindowsMetaFile = 2, WMF = 2;
00479         static const int OLE = 3;
00480     };
00481 
00482     class Image : public ImageGenerated
00483     {
00484     private:
00485         Byte *m_externalImage;
00486         DWord m_externalImageSize;
00487         DWord m_externalImageUpto;
00488 
00489         // image dimensions in twips
00490         double m_originalWidth, m_originalHeight;
00491         double m_displayedWidth, m_displayedHeight;
00492         
00493         static int getBytesPerScanLine (const int width, const int bitsPerPixel, const int padBytes);
00494 
00495         // these read and write an image stored in .WRI format
00496         bool readFromDevice (void); friend class InternalGenerator;
00497         bool writeToDevice (void);  friend class InternalParser;
00498     public:
00499         Image ();
00500         virtual ~Image ();
00501 
00502         Image &operator= (const Image &rhs);
00503         
00504         bool getIsWMF (void) const  {   return m_mappingMode != 0xE3;   }
00505         bool getIsBMP (void) const  {   return m_mappingMode == 0xE3;   }
00506 
00507         // 0x88 is a common value for WMFs
00508         void setIsWMF (const bool yes = true)   {   yes ? m_mappingMode = 0x88 : m_mappingMode = 0xE3;  }
00509         void setIsBMP (const bool yes = true)   {   yes ? m_mappingMode = 0xE3 : m_mappingMode = 0x88;  }
00510 
00511         
00512         double getOriginalWidth (void) const    {   return m_originalWidth; }
00513         void setOriginalWidth (const double val)    {   m_originalWidth = val;  }
00514         
00515         double getOriginalHeight (void) const   {   return m_originalHeight;    }
00516         void setOriginalHeight (const double val)   {   m_originalHeight = val; }
00517         
00518         double getDisplayedWidth (void) const   {   return m_displayedWidth;    }
00519         void setDisplayedWidth (const double val)   {   m_displayedWidth = val; }
00520         
00521         double getDisplayedHeight (void) const  {   return m_displayedHeight;   }
00522         void setDisplayedHeight (const double val)  {   m_displayedHeight = val;    }
00523 
00524         
00525         // these read and write an image stored in an external format
00526         Byte *getExternalImage (void) const {   return m_externalImage; }
00527         DWord getExternalImageSize (void) const {   return m_externalImageSize; }
00528 
00529         bool setExternalImage (const Byte *data, const DWord size)
00530         {
00531         CHECK_DEVICE;
00532 
00533             if (!m_externalImage)
00534             {
00535                 m_externalImage = new Byte [m_externalImageSize];
00536                 if (!m_externalImage)
00537                     ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for external image\n");
00538             }
00539             
00540             if (m_externalImageUpto + size > m_externalImageSize)
00541             {
00542                 Dump (externalImageUpto);
00543                 m_device->debug ("\tsize: ", size);
00544                 Dump (externalImageSize);
00545                 
00546                 ErrorAndQuit (Error::InternalError, "user overflowed setExternalImage(); attempt to write too much binary data\n");
00547             }
00548 
00549             memcpy (m_externalImage + m_externalImageUpto, data, size);
00550             m_externalImageUpto += size;
00551             return true;
00552         }
00553 
00554         bool setExternalImageSize (const DWord externalImageSize)
00555         {
00556             m_externalImageSize = externalImageSize;
00557             m_externalImageUpto = 0;
00558 
00559             return true;
00560         }
00561     };
00562 
00563 
00564     class OLEType
00565     {
00566     public:
00567         static const int Static = 1;
00568         static const int Embedded = 2;
00569         static const int Link = 3;
00570     };
00571 
00572     class OLE : public OLEGenerated
00573     {
00574     private:
00575         Byte *m_externalObject;
00576         DWord m_externalObjectSize;
00577         DWord m_externalObjectUpto;
00578 
00579         // these read and write OLE stored in .WRI format
00580         bool readFromDevice (void); friend class InternalGenerator;
00581         bool writeToDevice (void);  friend class InternalParser;
00582 
00583     public:
00584         OLE ();
00585         virtual ~OLE ();
00586 
00587         OLE &operator= (const OLE &rhs);
00588 
00589         Byte *getExternalObject (void) const    {   return m_externalObject;    }
00590         DWord getExternalObjectSize (void) const    {   return m_externalObjectSize;    }
00591 
00592         bool setExternalObject (const Byte *data, const DWord size)
00593         {
00594         CHECK_DEVICE;
00595 
00596             if (!m_externalObject)
00597             {
00598                 m_externalObject = new Byte [m_externalObjectSize];
00599                 if (!m_externalObject)
00600                     ErrorAndQuit (Error::OutOfMemory, "could not allocate memory for external object\n");
00601             }
00602             
00603             if (m_externalObjectUpto + size > m_externalObjectSize)
00604             {
00605                 Dump (externalObjectUpto);
00606                 m_device->debug ("\tsize: ", size);
00607                 Dump (externalObjectSize);
00608 
00609                 ErrorAndQuit (Error::InternalError, "user overflowed setExternalObject (); attempt to write too much binary data\n");
00610             }
00611 
00612             memcpy (m_externalObject + m_externalObjectUpto, data, size);
00613             m_externalObjectUpto += size;
00614             return true;
00615         }
00616 
00617         bool setExternalObjectSize (const DWord externalObjectSize)
00618         {
00619             m_externalObjectSize = externalObjectSize;
00620             m_externalObjectUpto = 0;
00621 
00622             return true;
00623         }
00624     };
00625 
00626 }   // namespace MSWrite    {
00627 
00628 #endif  // __STRUCTURES_H__
00629 
00630 // end of structures.h
KDE Home | KDE Accessibility Home | Description of Access Keys