home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libfont / src / fmi.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.1 KB  |  456 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.  * fmi.cpp (FontMatchInfoObject.cpp)
  20.  *
  21.  * C++ implementation of the (fmi) FontMatchInfoObject
  22.  *
  23.  * dp Suresh <dp@netscape.com>
  24.  */
  25.  
  26.  
  27. #include "fmi.h"
  28.  
  29. static const char *fmi_attributes[] = {
  30.         nfFmiName,
  31.         nfFmiCharset,
  32.         nfFmiEncoding,
  33.         nfFmiWeight,
  34.         nfFmiPitch,
  35.         nfFmiStyle,
  36.         nfFmiUnderline,
  37.         nfFmiStrikeOut,
  38.         nfFmiResolutionX,
  39.         nfFmiResolutionY,
  40. };
  41.  
  42. static char fmi_attributes_type[] = {
  43.         FMI_TYPE_CSTRING,
  44.         FMI_TYPE_CSTRING,
  45.         FMI_TYPE_CSTRING,
  46.         FMI_TYPE_JINT,
  47.         FMI_TYPE_JINT,
  48.         FMI_TYPE_JINT,
  49.         FMI_TYPE_JINT,
  50.         FMI_TYPE_JINT,
  51.         FMI_TYPE_JINT,
  52.         FMI_TYPE_JINT,
  53. };
  54.  
  55. #define MAX_STANDARD_ATTRIBUTES (sizeof(fmi_attributes)/sizeof(*fmi_attributes))
  56.  
  57. FontMatchInfoObject::
  58. FontMatchInfoObject(const char *iname, const char *icharset,
  59.                     const char *iencoding, jint iweight, jint ipitch,
  60.                     jint istyle, jint iunderline, jint istrikeOut, jint resX, jint resY)
  61.                     : wfList(free_fmi_attr_store), stringRepresentation(NULL),
  62.                       stringLen(0), stringMaxLen(0)
  63. {
  64.     addAttribute(nfFmiName, iname);
  65.     addAttribute(nfFmiCharset, icharset);
  66.     addAttribute(nfFmiEncoding, iencoding);
  67.     addAttribute(nfFmiWeight, iweight);
  68.     addAttribute(nfFmiPitch, ipitch);
  69.     addAttribute(nfFmiStyle, istyle);
  70.     addAttribute(nfFmiUnderline, iunderline);
  71.     addAttribute(nfFmiStrikeOut, istrikeOut);
  72.     addAttribute(nfFmiResolutionX, resX);
  73.     addAttribute(nfFmiResolutionY, resY);
  74.     WF_TRACEMSG( ("NF: Created fmi (%s).", describe()) );
  75. }
  76.  
  77. FontMatchInfoObject::
  78. FontMatchInfoObject(const char *reconstructString)
  79. : wfList(free_fmi_attr_store), stringRepresentation(NULL),
  80.   stringLen(0), stringMaxLen(0)
  81. {
  82.     reconstruct(reconstructString);
  83. }
  84.  
  85. FontMatchInfoObject::
  86. ~FontMatchInfoObject()
  87. {
  88.     WF_TRACEMSG( ("NF: Destroying fmi (%s).", describe()) );
  89.     releaseStringRepresentation();
  90. }
  91.  
  92. const char ** FontMatchInfoObject::
  93. ListAttributes()
  94. {
  95.     return (fmi_attributes);
  96. }
  97.  
  98. void * FontMatchInfoObject::
  99. GetValue(const char *attr)
  100. {
  101.     wfListElement *tmp = head;
  102.     void *value = NULL;
  103.  
  104.     if (!attr)
  105.       {
  106.         // Invalid input
  107.         return (NULL);
  108.       }
  109.  
  110.     for (; tmp; tmp = tmp->next)
  111.       {
  112.         struct fmi_attr_store *ele = (struct fmi_attr_store *)tmp->item;
  113.         if (ele->attr && !strcmp(ele->attr, attr))
  114.           {
  115.             value = ele->u.genericValue;
  116.             break;
  117.           }
  118.       }
  119.  
  120.     return (value);
  121. }
  122.  
  123. jint FontMatchInfoObject::
  124. IsEquivalent(struct nffmi *fmi)
  125. {
  126.     void *fmi_value;
  127.     void *this_value;
  128.     for (int i = 0; i < MAX_STANDARD_ATTRIBUTES; i++)
  129.     {
  130.         fmi_value = nffmi_GetValue(fmi, fmi_attributes[i], NULL);
  131.         this_value = GetValue(fmi_attributes[i]);
  132.         if (fmi_attributes_type[i] == FMI_TYPE_CSTRING)
  133.         {
  134.             // FMI_TYPE_CSTRING
  135.             char * fmi_str_value = (char *)fmi_value;
  136.             char * this_str_value = (char *)this_value;
  137.             if (fmi_str_value != NULL && *fmi_str_value != '*' &&
  138.                 this_str_value != NULL && *this_str_value != '*' &&
  139.                 !strcmp(fmi_str_value, this_str_value))
  140.             {
  141.                 // Mismatch
  142.                 return (0);
  143.             }
  144.             
  145.         }
  146.         else
  147.         {
  148.             // FMI_TYPE_INT
  149. #ifdef OSF1
  150.                         long fmi_int_value = (long)fmi_value;
  151.                         long this_int_value = (long)this_value;
  152. #else
  153.                         int fmi_int_value = (int)fmi_value;
  154.                         int this_int_value = (int)this_value;
  155. #endif
  156.             if (fmi_int_value != 0 && this_int_value != 0
  157.                 && fmi_int_value != this_int_value)
  158.             {
  159.                 // Mismatch
  160.                 return (0);
  161.             }
  162.                 
  163.         }
  164.     }
  165.     return (1);
  166. }
  167.  
  168.  
  169. //
  170. // Check for equality of fmi
  171. //
  172. int
  173. FontMatchInfoObject::isEqual(FontMatchInfoObject *fob)
  174. {
  175.     // Two fmi's are equal if their string representations ARE THE SAME
  176.     return (!strcmp(describe(), fob->describe()));
  177. }
  178.  
  179.  
  180. int FontMatchInfoObject::
  181. reconstruct(const char *reconstructString)
  182. {
  183.     // Release any stringRepresentation
  184.     releaseStringRepresentation();
  185.  
  186.     // Remove all existing attributes
  187.     removeAll();
  188.  
  189.     // Reconstruct the FMI from the string.
  190.     int i = 0;
  191.     int len = strlen(reconstructString);
  192.     char *fontpart = new char[len+1];
  193.     if (!fontpart)
  194.     {
  195.         // ERROR: No Memory.
  196.         return (-1);
  197.     }
  198.     const char *attr = NULL;
  199.     const char *value = NULL;
  200.     while (reconstructString && *reconstructString)
  201.     {
  202.         if (i < MAX_STANDARD_ATTRIBUTES)
  203.         {
  204.             reconstructString = scanFontpart(reconstructString, fontpart, attr, value);
  205.             if (fmi_attributes_type[i] == FMI_TYPE_CSTRING)
  206.             {
  207.                 addAttribute(fmi_attributes[i], fontpart);
  208.             }
  209.             else
  210.             {
  211.                 jint ival = atoi(fontpart);
  212.                 addAttribute(fmi_attributes[i], ival);
  213.             }
  214.         }
  215.         else
  216.         {
  217.             reconstructString = scanFontpart(reconstructString, fontpart, attr, value);
  218.             addAttribute(attr, (char *)value);
  219.         }
  220.         i++;
  221.     }
  222.     return (0);
  223. }
  224.  
  225. const char * FontMatchInfoObject::
  226. describe(void)
  227. {
  228.     if (stringRepresentation != NULL)
  229.     {
  230.         return (stringRepresentation);
  231.     }
  232.     
  233.     wfListElement *tmp = head;
  234.     stringLen = 0;
  235.     stringMaxLen = 0;
  236.     
  237.     for (; tmp; tmp = tmp->next)
  238.     {
  239.         struct fmi_attr_store *ele = (struct fmi_attr_store *)tmp->item;
  240.         addToString(stringRepresentation, stringLen, stringMaxLen, ele);
  241.     }
  242.     return (stringRepresentation);
  243. }   
  244.  
  245. //
  246. // Private method implementations
  247. //
  248.  
  249. int FontMatchInfoObject::
  250. addAttribute(const char *attr, const char *value)
  251. {
  252.     struct fmi_attr_store *ele = new fmi_attr_store;
  253.     if (!ele)
  254.       {
  255.         // no memory
  256.         return (-1);
  257.       }
  258.  
  259.     ele->attr = attr;
  260.     ele->valueType = FMI_TYPE_CSTRING;
  261.     ele->u.stringValue = CopyString(value);
  262.     add(ele);
  263.  
  264.     // Sync stringRepresentation
  265.     addToString(stringRepresentation, stringLen, stringMaxLen, ele);
  266.     
  267.     return (0);
  268. }
  269.  
  270.  
  271. int FontMatchInfoObject::
  272. addAttribute(const char *attr, jint value)
  273. {
  274.     struct fmi_attr_store *ele = new fmi_attr_store;
  275.     if (!ele)
  276.       {
  277.         // no memory
  278.         return (-1);
  279.       }
  280.  
  281.     ele->attr = attr;
  282.     ele->valueType = FMI_TYPE_JINT;
  283.     ele->u.intValue = value;
  284.     add(ele);
  285.  
  286.     // Sync stringRepresentation
  287.     addToString(stringRepresentation, stringLen, stringMaxLen, ele);
  288.     
  289.     return (0);
  290. }
  291.  
  292. void
  293. /*ARGSUSED*/
  294. free_fmi_attr_store(wfList *object, void *item)
  295. {
  296.     struct fmi_attr_store *ele = (struct fmi_attr_store *)item;
  297.     if (ele)
  298.     {
  299.         if (ele->valueType == FMI_TYPE_CSTRING)
  300.         {
  301.             // Free the copy of the string we took
  302.             delete[] (char *)ele->u.stringValue;
  303.         }
  304.         delete ele;
  305.     }
  306. }
  307.  
  308. #define MY_BLOCK_SIZE 16
  309. static const char needsEscape[] = {
  310.     FMI_FONTPART_DEFAULT, FMI_FONTPART_SEPERATOR,
  311.     FMI_FONTPART_ESCAPE, FMI_FONTPART_ATTRSEPERATOR,
  312.     '\0',
  313. };
  314.  
  315.  
  316. int FontMatchInfoObject::
  317. addToString(const char *&str, int &strLen, int &strMaxLen, struct fmi_attr_store *ele)
  318. {
  319.     const char *value;
  320.     char *newValue = NULL;
  321.     char strValue[64];    // XXX There must be a better way to do this.
  322.     int ret = 0;
  323.  
  324.     addToString(str, strLen, strMaxLen, FMI_FONTPART_SEPERATOR);
  325.     if (count() > MAX_STANDARD_ATTRIBUTES)
  326.     {
  327.         // Add the attribute also
  328.         addToString(str, strLen, strMaxLen, ele->attr);
  329.         addToString(str, strLen, strMaxLen, ":");
  330.     }
  331.     
  332.     if (ele->valueType == FMI_TYPE_JINT)
  333.     {
  334.         strValue[0] = '\0';
  335.         if (ele->u.intValue > 0)
  336.         {
  337.             sprintf(strValue, "%d", ele->u.intValue);
  338.         }
  339.         value = strValue;
  340.     }
  341.     else
  342.     {
  343.         // Escape {:-*} in value. These have special meaning to us.
  344.         value = ele->u.stringValue;
  345.         if (value && *value)
  346.         {
  347.             newValue = EscapeString(value, needsEscape);
  348.             if (!newValue)
  349.             {
  350.                 // ERROR: No memory
  351.                 return (-1);
  352.             }
  353.             value = newValue;
  354.         }
  355.     }
  356.     ret = addToString(str, strLen, strMaxLen, value);
  357.     if (newValue)
  358.     {
  359.         delete[] newValue;
  360.     }
  361.     return (ret);
  362. }
  363.  
  364. int FontMatchInfoObject::
  365. addToString(const char *&str, int &strLen, int &strMaxLen, const char *value)
  366. {
  367.     int valueLen = 0;
  368.     if (!value || !*value)
  369.     {
  370.         // Use default symbol
  371.         return (0);
  372.     }
  373.     valueLen = strlen(value);
  374.  
  375.     while ((strMaxLen - strLen) <= valueLen)
  376.     {
  377.         str = (char *)WF_REALLOC((char*)str,strMaxLen + MY_BLOCK_SIZE);
  378.         if (str == NULL) return 0;
  379.         strMaxLen += MY_BLOCK_SIZE;
  380.     }
  381.  
  382.     strcpy((char*)(str+strLen), value);
  383.     strLen += valueLen;
  384.     return strLen;
  385. }
  386.  
  387. int FontMatchInfoObject::
  388. addToString(const char *&str, int &strLen, int &strMaxLen, const char value)
  389. {
  390.     if ((strMaxLen - strLen) <= 1)
  391.     {
  392.         str = (char *)WF_REALLOC((char*)str,strMaxLen + MY_BLOCK_SIZE);
  393.         if (str == NULL) return 0;
  394.         strMaxLen += MY_BLOCK_SIZE;
  395.     }
  396.  
  397.     *((char *)(str+strLen)) = value;
  398.     strLen++;
  399.     *((char *)(str+strLen)) = '\0';
  400.     return strLen;
  401. }
  402.  
  403. int FontMatchInfoObject::
  404. releaseStringRepresentation(void)
  405. {
  406.     if (stringRepresentation)
  407.     {
  408.         WF_FREE((char*)stringRepresentation);
  409.         stringRepresentation = NULL;
  410.         stringLen = stringMaxLen = 0;
  411.     }
  412.     return (0);
  413. }
  414.  
  415. //
  416. // Scans for the next fontpart from str and copies it into fontpart.
  417. // Assumes enough memory has been allocated for fontpart.
  418. // If value/attr are non-null, then points value and attr to their
  419. // appropriate places in fontpart
  420. //
  421. const char *FontMatchInfoObject::
  422. scanFontpart(const char *str, char *fontpart, const char *&value, const char *&attr)
  423. {
  424.     char *attrEnd = NULL;
  425.  
  426.     if (attr) attr = NULL;
  427.     if (value) value = fontpart;
  428.     if (*str == FMI_FONTPART_SEPERATOR)
  429.         str++;
  430.     while (*str && *str != FMI_FONTPART_SEPERATOR)
  431.     {
  432.         if (*str == FMI_FONTPART_ESCAPE)
  433.         {
  434.             str++;
  435.         }
  436.         else
  437.         {
  438.             if (*str == FMI_FONTPART_ATTRSEPERATOR)
  439.             {
  440.                 attrEnd = fontpart+1;
  441.             }
  442.  
  443.         }
  444.         *fontpart++ = *str++;
  445.     }
  446.     *fontpart = '\0';
  447.  
  448.     if (attrEnd)
  449.     {
  450.         if (attr) attr = fontpart;
  451.         *attrEnd = '\0';
  452.         if (value) value = attrEnd+1;
  453.     }
  454.     return (str);
  455. }
  456.