// fp_PageSize.cpp #include "string.h" #include "fp_PageSize.h" #include "ut_units.h" #include "ut_assert.h" #include "ut_debugmsg.h" // This class stores the pagesize in mm. The resoning behind // that is that mm is at least a derived unit from an ISO standard. // If anyone think it's more apropriate to express it in meters, // you're free to change the implementation. static const int cMaxSymbolicLength = 25; static const UT_Dimension FUND = DIM_MM; struct private_pagesize_sizes { double w; // width double h; // height UT_Dimension u; // unit for all these values char name[cMaxSymbolicLength]; // symbolic name double l; // left margin double r; // right margin double t; // top margin double b; // bottom margin }; // all paper sizes with this value set for any of its margins // means that i don't know what the correct value is. we should // find these out ASAP! Default to 1inch (25.4mm) #define MARGIN_UNKNOWN 25.4 const private_pagesize_sizes pagesizes[fp_PageSize::_last_predefined_pagesize_dont_use_] = { // the A sizes {1682.0, 2378.0, DIM_MM, "4A", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, {1189.0, 1682.0, DIM_MM, "2A", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 841.0, 1189.0, DIM_MM, "A0", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 594.0, 841.0, DIM_MM, "A1", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 420.0, 594.0, DIM_MM, "A2", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 297.0, 420.0, DIM_MM, "A3", 28.0, 28.0, 28.0, 28.0 }, { 210.0, 297.0, DIM_MM, "A4", 28.0, 28.0, 28.0, 28.0 }, { 148.0, 210.0, DIM_MM, "A5", 28.0, 28.0, 28.0, 28.0 }, { 105.0, 148.0, DIM_MM, "A6", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 74.0, 105.0, DIM_MM, "A7", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 52.0, 74.0, DIM_MM, "A8", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 37.0, 52.0, DIM_MM, "A9", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 26.0, 37.0, DIM_MM, "A10", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, // the B sizes {2000.0, 2828.0, DIM_MM, "4B", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, {1414.0, 2000.0, DIM_MM, "2B", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, {1000.0, 1414.0, DIM_MM, "B0", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 707.0, 1000.0, DIM_MM, "B1", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 500.0, 707.0, DIM_MM, "B2", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 353.0, 500.0, DIM_MM, "B3", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 250.0, 353.0, DIM_MM, "B4", 21.0, 21.0, 21.0, 21.0 }, { 176.0, 250.0, DIM_MM, "B5", 28.0, 28.0, 28.0, 28.0 }, { 125.0, 176.0, DIM_MM, "B6", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 88.0, 125.0, DIM_MM, "B7", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 62.0, 88.0, DIM_MM, "B8", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 44.0, 62.0, DIM_MM, "B9", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 31.0, 44.0, DIM_MM, "B10", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, // the C sizes { 917.0, 1297.0, DIM_MM, "C0", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 648.0, 917.0, DIM_MM, "C1", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 458.0, 648.0, DIM_MM, "C2", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 324.0, 458.0, DIM_MM, "C3", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 229.0, 324.0, DIM_MM, "C4", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, // FIXME: C5 is dealt with below, under envelopes // FIXME: should prolly have C6/C5 here too, for completeness { 114.0, 162.0, DIM_MM, "C6", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 81.0, 114.0, DIM_MM, "C7", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 57.0, 81.0, DIM_MM, "C8", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 40.0, 57.0, DIM_MM, "C9", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, { 28.0, 40.0, DIM_MM, "C10", MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN, MARGIN_UNKNOWN }, // Japanese B sizes // FIXME: should prolly have the other Japanese sizes { 182.0, 258.0, DIM_MM, "B5-Japan", 28.0, 28.0, 28.0, 28.0}, // the rest { 8.5, 14.0, DIM_IN, "Legal", 1.0, 1.0, 1.0, 1.0 }, { 8.5, 13.0, DIM_IN, "Folio", 1.0, 1.0, 1.0, 1.0 }, { 8.5, 11.0, DIM_IN, "Letter", 1.0, 1.0, 1.0, 1.0 }, { 8.5, 5.5, DIM_IN, "Half-Letter", 1.0, 1.0, 1.0, 1.0 }, { 7.5, 10.0, DIM_IN, "Executive", 1.0, 1.0, 1.0, 1.0 }, { 280.1, 267.0, DIM_MM, "Tabloid/Ledger", 25.4, 25.4, 25.4, 25.4}, { 99.0, 191.0, DIM_MM, "Monarch", 3.5, 3.5, 3.5, 3.5}, { 297.0, 433.0, DIM_MM, "SuperB", 28.2, 28.2, 28.2, 28.2}, { 105.0, 242.0, DIM_MM, "Envelope-Commercial", 1.8, 1.8, 1.8, 1.8}, { 99.0, 191.0, DIM_MM, "Envelope-Monarch", 1.8, 1.8, 1.8, 1.8}, { 110.0, 220.0, DIM_MM, "Envelope-DL", 1.8, 1.8, 1.8, 1.8}, { 162.0, 229.0, DIM_MM, "Envelope-C5", 1.8, 1.8, 1.8, 1.8}, { 105.0, 148.0, DIM_MM, "EuroPostcard", 1.8, 1.8, 1.8, 1.8}, { 0.0, 0.0, DIM_MM, "Custom", 0.0, 0.0, 0.0, 0.0} }; fp_PageSize::fp_PageSize(Predefined preDef) { m_bisPortrait = true; Set(preDef); m_scale = 1.0; } fp_PageSize::fp_PageSize(const char *name) { m_bisPortrait = true; m_scale = 1.0; Set(name); } fp_PageSize::fp_PageSize(double w, double h, UT_Dimension u) { UT_ASSERT(u >= DIM_IN && u <= DIM_none); m_bisPortrait = true; m_scale = 1.0; Set(w, h, u); } // all Set() calls ultimately go through this function void fp_PageSize::Set(Predefined preDef, UT_Dimension u) { UT_ASSERT(preDef >= _first_predefined_pagesize_ && preDef < _last_predefined_pagesize_dont_use_); UT_ASSERT(u >= DIM_IN && u <= DIM_none); const private_pagesize_sizes& size = pagesizes[preDef]; if (u != DIM_none) m_unit = u; else m_unit = size.u; // Always scale to mm's, which we store. m_iWidth = UT_convertDimensions(size.w, size.u, FUND); m_iHeight = UT_convertDimensions(size.h, size.u, FUND); m_iMarginTop = UT_convertDimensions(size.t, size.u, FUND); m_iMarginBottom = UT_convertDimensions(size.b, size.u, FUND); m_iMarginLeft = UT_convertDimensions(size.l, size.u, FUND); m_iMarginRight = UT_convertDimensions(size.r, size.u, FUND); m_predefined = (char *)pagesizes [preDef].name; } /*! Set the pagesize to given width and height, assumed to be in given unit. */ void fp_PageSize::Set(double w, double h, UT_Dimension u) { int i; double converted_w, converted_h; UT_ASSERT(u >= DIM_IN && u <= DIM_none); // calculate which predefined this represents for (i = _first_predefined_pagesize_; i < (int)_last_predefined_pagesize_dont_use_; i++) { if (pagesizes[i].u != u ) // Convert to local defined units and round off { converted_w = UT_convertDimensions(w, u, pagesizes[i].u); converted_w = ((int)(converted_w*10.0+0.5))/(double)10.0; converted_h = UT_convertDimensions(h, u, pagesizes[i].u); converted_h = ((int)(converted_h*10.0+0.5))/(double)10.0; } else { converted_w = w; converted_h = h; } if ((pagesizes [i].w == converted_w) && (pagesizes [i].h == converted_h)) { Set(static_cast(i), u); break; } if ((pagesizes [i].h == converted_w) && (pagesizes [i].w == converted_h)) { Set(static_cast(i), u); m_bisPortrait = false; break; } } // Force Custom Label if nothing else fits if ( i == (int)_last_predefined_pagesize_dont_use_ ) { Set (static_cast(i-1), u); m_iWidth = UT_convertDimensions(w, u, FUND); m_iHeight = UT_convertDimensions(h, u, FUND); } } void fp_PageSize::Set(const char *name, UT_Dimension u) { Set(NameToPredefined(name), u); } void fp_PageSize::setPortrait(void) { m_bisPortrait = true; } void fp_PageSize::setLandscape(void) { m_bisPortrait = false; } double fp_PageSize::Width(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iWidth, FUND, u); else return m_scale * UT_convertDimensions(m_iHeight, FUND, u); } double fp_PageSize::Height(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iHeight, FUND, u); else return m_scale * UT_convertDimensions(m_iWidth, FUND, u); } double fp_PageSize::MarginTop(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iMarginTop, FUND, u); else return m_scale * UT_convertDimensions(m_iMarginRight, FUND, u); } double fp_PageSize::MarginBottom(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iMarginBottom, FUND, u); else return m_scale * UT_convertDimensions(m_iMarginLeft, FUND, u); } double fp_PageSize::MarginLeft(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iMarginLeft, FUND, u); else return m_scale * UT_convertDimensions(m_iMarginTop, FUND, u); } double fp_PageSize::MarginRight(UT_Dimension u) const { UT_ASSERT(u >= DIM_IN && u <= DIM_none); if(m_bisPortrait == true) return m_scale * UT_convertDimensions(m_iMarginRight, FUND, u); else return m_scale * UT_convertDimensions(m_iMarginBottom, FUND, u); } bool fp_PageSize::IsPredefinedName(const char* szPageSizeName) { for (int i = (int)_first_predefined_pagesize_; i < (int)_last_predefined_pagesize_dont_use_; ++i) { if (!strcmp(pagesizes[i].name, szPageSizeName)) { return true; } } return false; } fp_PageSize::Predefined fp_PageSize::NameToPredefined(const char *name) { int preDef = 0; // determine the predefined layout the name represents if(!name) { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return fp_PageSize::psLetter; } for(preDef = (int)_first_predefined_pagesize_; preDef < static_cast(_last_predefined_pagesize_dont_use_); preDef++) { if (0 == strcmp(pagesizes[preDef].name, name)) { break; } } if ((preDef >= _first_predefined_pagesize_) && (preDef < _last_predefined_pagesize_dont_use_)) { return static_cast(preDef); } UT_ASSERT(UT_SHOULD_NOT_HAPPEN); return fp_PageSize::psLetter; } const char * fp_PageSize::PredefinedToName(Predefined preDef) { UT_ASSERT((preDef >= _first_predefined_pagesize_) && (preDef < _last_predefined_pagesize_dont_use_)); return pagesizes[preDef].name; }