PageSize.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:7k
- /* $Id: PageSize.c++,v 1.1.1.1 2005/11/11 21:32:03 faxguy Exp $ */
- /*
- * Copyright (c) 1993-1996 Sam Leffler
- * Copyright (c) 1993-1996 Silicon Graphics, Inc.
- * HylaFAX is a trademark of Silicon Graphics
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- /*
- * Page Size Support.
- */
- #include "Types.h"
- #include "PageSize.h"
- #include "Array.h"
- #include "config.h"
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
- fxDECLARE_StructArray(PageInfoArray, PageInfo)
- fxIMPLEMENT_StructArray(PageInfoArray, PageInfo)
- PageInfoArray* PageSizeInfo::pageInfo = NULL;
- #include <stdarg.h>
- static void
- parseError(const char* file, u_int lineno, const char* fmt ...)
- {
- va_list ap;
- va_start(ap, fmt);
- fprintf(stderr, "%s: line %u: ", file, lineno);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- }
- bool
- PageSizeInfo::skipws(char*& cp,
- const char* file, const char* item, u_int lineno)
- {
- if (isspace(*cp))
- *cp++ = ' ';
- while (isspace(*cp))
- cp++;
- if (*cp == ' ') {
- parseError(file, lineno,
- "Unexpected end of line after "%s".n", item);
- return (false);
- } else
- return (true);
- }
- PageInfoArray*
- PageSizeInfo::readPageInfoFile()
- {
- fxStr file = FAX_LIBDATA;
- file.append("/");
- file.append(FAX_PAGESIZES);
- PageInfoArray* info = new PageInfoArray;
- FILE* fp = fopen(file, "r");
- u_int lineno = 0;
- if (fp) {
- char line[1024];
- while (fgets(line, sizeof (line), fp)) {
- lineno++;
- char* cp = strchr(line, '#');
- if (cp)
- *cp = ' ';
- else if ((cp = strchr(line, 'n')))
- *cp = ' ';
- for (cp = line; isspace(*cp); cp++)
- ;
- if (*cp == ' ')
- continue;
- // name<tab>width<ws>height<ws>gwidth<ws>gheight<ws>top<ws>left
- PageInfo pi;
- pi.name = cp;
- while (*cp != 't')
- cp++;
- if (!skipws(cp, file, "page size name", lineno))
- continue;
- pi.abbr = cp;
- while (*cp != 't')
- cp++;
- if (!skipws(cp, file, "page size abbreviation", lineno))
- continue;
- pi.w = (BMU) strtoul(cp, &cp, 10);
- if (!skipws(cp, file, "page width", lineno))
- continue;
- pi.h = (BMU) strtoul(cp, &cp, 10);
- if (!skipws(cp, file, "page height", lineno))
- continue;
- pi.grw = (BMU) strtoul(cp, &cp, 10);
- if (!skipws(cp, file, "guaranteed page width", lineno))
- continue;
- pi.grh = (BMU) strtoul(cp, &cp, 10);
- if (!skipws(cp, file, "guaranteed page height", lineno))
- continue;
- pi.top = (BMU) strtoul(cp, &cp, 10);
- if (!skipws(cp, file, "top margin", lineno))
- continue;
- pi.left = (BMU) strtoul(cp, &cp, 10);
- pi.name = strdup(pi.name);
- pi.abbr = strdup(pi.abbr);
- info->append(pi);
- }
- fclose(fp);
- } else {
- fprintf(stderr,
- "Warning, no page size database file "%s", using builtin default.n",
- (const char*)file);
- PageInfo pi;
- pi.name = strdup("default");
- pi.abbr = strdup("NA-LET");
- // North American Letter
- pi.w = 10200;
- pi.h = 13200;
- pi.grw = 9240;
- pi.grh = 12400;
- pi.top = 472;
- pi.left = 345;
- info->append(pi);
- }
- return info;
- }
- const PageInfo*
- PageSizeInfo::getPageInfoByName(const char* name)
- {
- int c = tolower(name[0]);
- size_t len = strlen(name);
- for (int i = 0, n = pageInfo->length(); i < n; i++) {
- const PageInfo& pi = (*pageInfo)[i];
- if (strncasecmp(pi.abbr, name, len) == 0)
- return π
- for (const char* cp = pi.name; *cp != ' '; cp++)
- if (tolower(*cp) == c && strncasecmp(cp, name, len) == 0)
- return π
- }
- return (NULL);
- }
- PageSizeInfo*
- PageSizeInfo::getPageSizeByName(const char* name)
- {
- if (pageInfo == NULL)
- pageInfo = readPageInfoFile();
- const PageInfo* info = getPageInfoByName(name);
- return info ? new PageSizeInfo(*info) : (PageSizeInfo*) NULL;
- }
- PageSizeInfo*
- PageSizeInfo::getPageSizeBySize(float wmm, float hmm)
- {
- BMU w = fromMM(wmm);
- BMU h = fromMM(hmm);
- if (pageInfo == NULL)
- pageInfo = readPageInfoFile();
- int best = 0;
- u_long bestMeasure = (u_long)-1;
- for (int i = 0, n = pageInfo->length(); i < n; i++) {
- int dw = (int)((*pageInfo)[i].w - w);
- int dh = (int)((*pageInfo)[i].h - h);
- u_long measure = dw*dw + dh*dh;
- if (measure < bestMeasure) {
- best = i;
- bestMeasure = measure;
- }
- }
- #define THRESHOLD 720000 // .5" in each dimension
- return bestMeasure < THRESHOLD ?
- new PageSizeInfo((*pageInfo)[best]) : (PageSizeInfo*) NULL;
- }
- PageSizeInfo::PageSizeInfo()
- {
- if (pageInfo == NULL)
- pageInfo = readPageInfoFile();
- info = getPageInfoByName("default");
- }
- PageSizeInfo::PageSizeInfo(const PageInfo& i) : info(&i) {}
- PageSizeInfo::~PageSizeInfo() {}
- /*
- * C stub interfaces...
- */
- extern "C" struct pageSizeInfo*
- getPageSize(const char* name)
- {
- return (struct pageSizeInfo*) PageSizeInfo::getPageSizeByName(name);
- }
- extern "C" struct pageSizeInfo*
- closestPageSize(float w, float h)
- {
- return (struct pageSizeInfo*) PageSizeInfo::getPageSizeBySize(w,h);
- }
- extern "C" void
- delPageSize(struct pageSizeInfo* info)
- {
- delete (PageSizeInfo*) info;
- }
- extern "C" const char*
- getPageName(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->name();
- }
- extern "C" const char*
- getPageAbbrev(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->abbrev();
- }
- extern "C" float
- getPageWidth(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->width();
- }
- extern "C" float
- getPageHeight(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->height();
- }
- extern "C" float
- getPageGuarHeight(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->guarHeight();
- }
- extern "C" float
- getPageGuarWidth(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->guarWidth();
- }
- extern "C" float
- getPageTopMargin(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->topMargin();
- }
- extern "C" float
- getPageLeftMargin(const struct pageSizeInfo* info)
- {
- return ((const PageSizeInfo*) info)->leftMargin();
- }
- /*
- * Page size iterator support.
- */
- PageSizeInfoIter::PageSizeInfoIter()
- {
- i = 0;
- }
- PageSizeInfoIter::~PageSizeInfoIter() {}
- void PageSizeInfoIter::operator++() { i++; }
- void PageSizeInfoIter::operator++(int) { i++; }
- PageSizeInfoIter::operator const PageSizeInfo&()
- {
- if (i < PageSizeInfo::pageInfo->length())
- pi.info = &(*PageSizeInfo::pageInfo)[i];
- return (pi);
- }
- bool PageSizeInfoIter::notDone()
- { return i < PageSizeInfo::pageInfo->length(); }