PageSize.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:7k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: PageSize.c++,v 1.1.1.1 2005/11/11 21:32:03 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1993-1996 Sam Leffler
  4.  * Copyright (c) 1993-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. /*
  27.  * Page Size Support.
  28.  */
  29. #include "Types.h"
  30. #include "PageSize.h"
  31. #include "Array.h"
  32. #include "config.h"
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include <stdlib.h>
  36. fxDECLARE_StructArray(PageInfoArray, PageInfo)
  37. fxIMPLEMENT_StructArray(PageInfoArray, PageInfo)
  38. PageInfoArray* PageSizeInfo::pageInfo = NULL;
  39. #include <stdarg.h>
  40. static void
  41. parseError(const char* file, u_int lineno, const char* fmt ...)
  42. {
  43.     va_list ap;
  44.     va_start(ap, fmt);
  45.     fprintf(stderr, "%s: line %u: ", file, lineno); 
  46.     vfprintf(stderr, fmt, ap);
  47.     va_end(ap);
  48. }
  49. bool
  50. PageSizeInfo::skipws(char*& cp,
  51.     const char* file, const char* item, u_int lineno)
  52. {
  53.     if (isspace(*cp))
  54. *cp++ = '';
  55.     while (isspace(*cp))
  56. cp++;
  57.     if (*cp == '') {
  58. parseError(file, lineno,
  59.     "Unexpected end of line after "%s".n", item);
  60. return (false);
  61.     } else
  62. return (true);
  63. }
  64. PageInfoArray*
  65. PageSizeInfo::readPageInfoFile()
  66. {
  67.     fxStr file = FAX_LIBDATA;
  68.     file.append("/");
  69.     file.append(FAX_PAGESIZES);
  70.     PageInfoArray* info = new PageInfoArray;
  71.     FILE* fp = fopen(file, "r");
  72.     u_int lineno = 0;
  73.     if (fp) {
  74. char line[1024];
  75. while (fgets(line, sizeof (line), fp)) {
  76.     lineno++;
  77.     char* cp = strchr(line, '#');
  78.     if (cp)
  79. *cp = '';
  80.     else if ((cp = strchr(line, 'n')))
  81. *cp = '';
  82.     for (cp = line; isspace(*cp); cp++)
  83. ;
  84.     if (*cp == '')
  85. continue;
  86.     // name<tab>width<ws>height<ws>gwidth<ws>gheight<ws>top<ws>left
  87.     PageInfo pi;
  88.     pi.name = cp;
  89.     while (*cp != 't')
  90. cp++;
  91.     if (!skipws(cp, file, "page size name", lineno))
  92. continue;
  93.     pi.abbr = cp;
  94.     while (*cp != 't')
  95. cp++;
  96.     if (!skipws(cp, file, "page size abbreviation", lineno))
  97. continue;
  98.     pi.w = (BMU) strtoul(cp, &cp, 10);
  99.     if (!skipws(cp, file, "page width", lineno))
  100. continue;
  101.     pi.h = (BMU) strtoul(cp, &cp, 10);
  102.     if (!skipws(cp, file, "page height", lineno))
  103. continue;
  104.     pi.grw = (BMU) strtoul(cp, &cp, 10);
  105.     if (!skipws(cp, file, "guaranteed page width", lineno))
  106. continue;
  107.     pi.grh = (BMU) strtoul(cp, &cp, 10);
  108.     if (!skipws(cp, file, "guaranteed page height", lineno))
  109. continue;
  110.     pi.top = (BMU) strtoul(cp, &cp, 10);
  111.     if (!skipws(cp, file, "top margin", lineno))
  112. continue;
  113.     pi.left = (BMU) strtoul(cp, &cp, 10);
  114.     pi.name = strdup(pi.name);
  115.     pi.abbr = strdup(pi.abbr);
  116.     info->append(pi);
  117. }
  118. fclose(fp);
  119.     } else {
  120. fprintf(stderr,
  121.     "Warning, no page size database file "%s", using builtin default.n",
  122.     (const char*)file);
  123. PageInfo pi;
  124. pi.name = strdup("default");
  125. pi.abbr = strdup("NA-LET");
  126. // North American Letter
  127. pi.w = 10200;
  128. pi.h = 13200;
  129. pi.grw = 9240;
  130. pi.grh = 12400;
  131. pi.top = 472;
  132. pi.left = 345;
  133. info->append(pi);
  134.     }
  135.     return info;
  136. }
  137. const PageInfo*
  138. PageSizeInfo::getPageInfoByName(const char* name)
  139. {
  140.     int c = tolower(name[0]);
  141.     size_t len = strlen(name);
  142.     for (int i = 0, n = pageInfo->length(); i < n; i++) {
  143. const PageInfo& pi = (*pageInfo)[i];
  144. if (strncasecmp(pi.abbr, name, len) == 0)
  145.     return &pi;
  146. for (const char* cp = pi.name; *cp != ''; cp++)
  147.     if (tolower(*cp) == c && strncasecmp(cp, name, len) == 0)
  148. return &pi;
  149.     }
  150.     return (NULL);
  151. }
  152. PageSizeInfo*
  153. PageSizeInfo::getPageSizeByName(const char* name)
  154. {
  155.     if (pageInfo == NULL)
  156. pageInfo = readPageInfoFile();
  157.     const PageInfo* info = getPageInfoByName(name);
  158.     return info ? new PageSizeInfo(*info) : (PageSizeInfo*) NULL;
  159. }
  160. PageSizeInfo*
  161. PageSizeInfo::getPageSizeBySize(float wmm, float hmm)
  162. {
  163.     BMU w = fromMM(wmm);
  164.     BMU h = fromMM(hmm);
  165.     if (pageInfo == NULL)
  166. pageInfo = readPageInfoFile();
  167.     int best = 0;
  168.     u_long bestMeasure = (u_long)-1;
  169.     for (int i = 0, n = pageInfo->length(); i < n; i++) {
  170. int dw = (int)((*pageInfo)[i].w - w);
  171. int dh = (int)((*pageInfo)[i].h - h);
  172. u_long measure = dw*dw + dh*dh;
  173. if (measure < bestMeasure) {
  174.     best = i;
  175.     bestMeasure = measure;
  176. }
  177.     }
  178. #define THRESHOLD 720000 // .5" in each dimension
  179.     return bestMeasure < THRESHOLD ?
  180. new PageSizeInfo((*pageInfo)[best]) : (PageSizeInfo*) NULL;
  181. }
  182. PageSizeInfo::PageSizeInfo()
  183. {
  184.     if (pageInfo == NULL)
  185. pageInfo = readPageInfoFile();
  186.     info = getPageInfoByName("default");
  187. }
  188. PageSizeInfo::PageSizeInfo(const PageInfo& i) : info(&i) {}
  189. PageSizeInfo::~PageSizeInfo() {}
  190. /*
  191.  * C stub interfaces...
  192.  */
  193. extern "C" struct pageSizeInfo*
  194. getPageSize(const char* name)
  195. {
  196.     return (struct pageSizeInfo*) PageSizeInfo::getPageSizeByName(name);
  197. }
  198. extern "C" struct pageSizeInfo*
  199. closestPageSize(float w, float h)
  200. {
  201.     return (struct pageSizeInfo*) PageSizeInfo::getPageSizeBySize(w,h);
  202. }
  203. extern "C" void
  204. delPageSize(struct pageSizeInfo* info)
  205. {
  206.     delete (PageSizeInfo*) info;
  207. }
  208. extern "C" const char*
  209. getPageName(const struct pageSizeInfo* info)
  210. {
  211.      return ((const PageSizeInfo*) info)->name();
  212. }
  213. extern "C" const char*
  214. getPageAbbrev(const struct pageSizeInfo* info)
  215. {
  216.      return ((const PageSizeInfo*) info)->abbrev();
  217. }
  218. extern "C" float
  219. getPageWidth(const struct pageSizeInfo* info)
  220. {
  221.      return ((const PageSizeInfo*) info)->width();
  222. }
  223. extern "C" float
  224. getPageHeight(const struct pageSizeInfo* info)
  225. {
  226.      return ((const PageSizeInfo*) info)->height();
  227. }
  228. extern "C" float
  229. getPageGuarHeight(const struct pageSizeInfo* info)
  230. {
  231.      return ((const PageSizeInfo*) info)->guarHeight();
  232. }
  233. extern "C" float
  234. getPageGuarWidth(const struct pageSizeInfo* info)
  235. {
  236.      return ((const PageSizeInfo*) info)->guarWidth();
  237. }
  238. extern "C" float
  239. getPageTopMargin(const struct pageSizeInfo* info)
  240. {
  241.      return ((const PageSizeInfo*) info)->topMargin();
  242. }
  243. extern "C" float
  244. getPageLeftMargin(const struct pageSizeInfo* info)
  245. {
  246.      return ((const PageSizeInfo*) info)->leftMargin();
  247. }
  248. /*
  249.  * Page size iterator support.
  250.  */
  251. PageSizeInfoIter::PageSizeInfoIter()
  252. {
  253.     i = 0;
  254. }
  255. PageSizeInfoIter::~PageSizeInfoIter() {}
  256. void PageSizeInfoIter::operator++() { i++; }
  257. void PageSizeInfoIter::operator++(int) { i++; }
  258. PageSizeInfoIter::operator const PageSizeInfo&()
  259. {
  260.     if (i < PageSizeInfo::pageInfo->length())
  261. pi.info = &(*PageSizeInfo::pageInfo)[i];
  262.     return (pi);
  263. }
  264. bool PageSizeInfoIter::notDone()
  265.     { return i < PageSizeInfo::pageInfo->length(); }