home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- * fmi.cpp (FontMatchInfoObject.cpp)
- *
- * C++ implementation of the (fmi) FontMatchInfoObject
- *
- * dp Suresh <dp@netscape.com>
- */
-
-
- #include "fmi.h"
-
- static const char *fmi_attributes[] = {
- nfFmiName,
- nfFmiCharset,
- nfFmiEncoding,
- nfFmiWeight,
- nfFmiPitch,
- nfFmiStyle,
- nfFmiUnderline,
- nfFmiStrikeOut,
- nfFmiResolutionX,
- nfFmiResolutionY,
- };
-
- static char fmi_attributes_type[] = {
- FMI_TYPE_CSTRING,
- FMI_TYPE_CSTRING,
- FMI_TYPE_CSTRING,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- FMI_TYPE_JINT,
- };
-
- #define MAX_STANDARD_ATTRIBUTES (sizeof(fmi_attributes)/sizeof(*fmi_attributes))
-
- FontMatchInfoObject::
- FontMatchInfoObject(const char *iname, const char *icharset,
- const char *iencoding, jint iweight, jint ipitch,
- jint istyle, jint iunderline, jint istrikeOut, jint resX, jint resY)
- : wfList(free_fmi_attr_store), stringRepresentation(NULL),
- stringLen(0), stringMaxLen(0)
- {
- addAttribute(nfFmiName, iname);
- addAttribute(nfFmiCharset, icharset);
- addAttribute(nfFmiEncoding, iencoding);
- addAttribute(nfFmiWeight, iweight);
- addAttribute(nfFmiPitch, ipitch);
- addAttribute(nfFmiStyle, istyle);
- addAttribute(nfFmiUnderline, iunderline);
- addAttribute(nfFmiStrikeOut, istrikeOut);
- addAttribute(nfFmiResolutionX, resX);
- addAttribute(nfFmiResolutionY, resY);
- WF_TRACEMSG( ("NF: Created fmi (%s).", describe()) );
- }
-
- FontMatchInfoObject::
- FontMatchInfoObject(const char *reconstructString)
- : wfList(free_fmi_attr_store), stringRepresentation(NULL),
- stringLen(0), stringMaxLen(0)
- {
- reconstruct(reconstructString);
- }
-
- FontMatchInfoObject::
- ~FontMatchInfoObject()
- {
- WF_TRACEMSG( ("NF: Destroying fmi (%s).", describe()) );
- releaseStringRepresentation();
- }
-
- const char ** FontMatchInfoObject::
- ListAttributes()
- {
- return (fmi_attributes);
- }
-
- void * FontMatchInfoObject::
- GetValue(const char *attr)
- {
- wfListElement *tmp = head;
- void *value = NULL;
-
- if (!attr)
- {
- // Invalid input
- return (NULL);
- }
-
- for (; tmp; tmp = tmp->next)
- {
- struct fmi_attr_store *ele = (struct fmi_attr_store *)tmp->item;
- if (ele->attr && !strcmp(ele->attr, attr))
- {
- value = ele->u.genericValue;
- break;
- }
- }
-
- return (value);
- }
-
- jint FontMatchInfoObject::
- IsEquivalent(struct nffmi *fmi)
- {
- void *fmi_value;
- void *this_value;
- for (int i = 0; i < MAX_STANDARD_ATTRIBUTES; i++)
- {
- fmi_value = nffmi_GetValue(fmi, fmi_attributes[i], NULL);
- this_value = GetValue(fmi_attributes[i]);
- if (fmi_attributes_type[i] == FMI_TYPE_CSTRING)
- {
- // FMI_TYPE_CSTRING
- char * fmi_str_value = (char *)fmi_value;
- char * this_str_value = (char *)this_value;
- if (fmi_str_value != NULL && *fmi_str_value != '*' &&
- this_str_value != NULL && *this_str_value != '*' &&
- !strcmp(fmi_str_value, this_str_value))
- {
- // Mismatch
- return (0);
- }
-
- }
- else
- {
- // FMI_TYPE_INT
- #ifdef OSF1
- long fmi_int_value = (long)fmi_value;
- long this_int_value = (long)this_value;
- #else
- int fmi_int_value = (int)fmi_value;
- int this_int_value = (int)this_value;
- #endif
- if (fmi_int_value != 0 && this_int_value != 0
- && fmi_int_value != this_int_value)
- {
- // Mismatch
- return (0);
- }
-
- }
- }
- return (1);
- }
-
-
- //
- // Check for equality of fmi
- //
- int
- FontMatchInfoObject::isEqual(FontMatchInfoObject *fob)
- {
- // Two fmi's are equal if their string representations ARE THE SAME
- return (!strcmp(describe(), fob->describe()));
- }
-
-
- int FontMatchInfoObject::
- reconstruct(const char *reconstructString)
- {
- // Release any stringRepresentation
- releaseStringRepresentation();
-
- // Remove all existing attributes
- removeAll();
-
- // Reconstruct the FMI from the string.
- int i = 0;
- int len = strlen(reconstructString);
- char *fontpart = new char[len+1];
- if (!fontpart)
- {
- // ERROR: No Memory.
- return (-1);
- }
- const char *attr = NULL;
- const char *value = NULL;
- while (reconstructString && *reconstructString)
- {
- if (i < MAX_STANDARD_ATTRIBUTES)
- {
- reconstructString = scanFontpart(reconstructString, fontpart, attr, value);
- if (fmi_attributes_type[i] == FMI_TYPE_CSTRING)
- {
- addAttribute(fmi_attributes[i], fontpart);
- }
- else
- {
- jint ival = atoi(fontpart);
- addAttribute(fmi_attributes[i], ival);
- }
- }
- else
- {
- reconstructString = scanFontpart(reconstructString, fontpart, attr, value);
- addAttribute(attr, (char *)value);
- }
- i++;
- }
- return (0);
- }
-
- const char * FontMatchInfoObject::
- describe(void)
- {
- if (stringRepresentation != NULL)
- {
- return (stringRepresentation);
- }
-
- wfListElement *tmp = head;
- stringLen = 0;
- stringMaxLen = 0;
-
- for (; tmp; tmp = tmp->next)
- {
- struct fmi_attr_store *ele = (struct fmi_attr_store *)tmp->item;
- addToString(stringRepresentation, stringLen, stringMaxLen, ele);
- }
- return (stringRepresentation);
- }
-
- //
- // Private method implementations
- //
-
- int FontMatchInfoObject::
- addAttribute(const char *attr, const char *value)
- {
- struct fmi_attr_store *ele = new fmi_attr_store;
- if (!ele)
- {
- // no memory
- return (-1);
- }
-
- ele->attr = attr;
- ele->valueType = FMI_TYPE_CSTRING;
- ele->u.stringValue = CopyString(value);
- add(ele);
-
- // Sync stringRepresentation
- addToString(stringRepresentation, stringLen, stringMaxLen, ele);
-
- return (0);
- }
-
-
- int FontMatchInfoObject::
- addAttribute(const char *attr, jint value)
- {
- struct fmi_attr_store *ele = new fmi_attr_store;
- if (!ele)
- {
- // no memory
- return (-1);
- }
-
- ele->attr = attr;
- ele->valueType = FMI_TYPE_JINT;
- ele->u.intValue = value;
- add(ele);
-
- // Sync stringRepresentation
- addToString(stringRepresentation, stringLen, stringMaxLen, ele);
-
- return (0);
- }
-
- void
- /*ARGSUSED*/
- free_fmi_attr_store(wfList *object, void *item)
- {
- struct fmi_attr_store *ele = (struct fmi_attr_store *)item;
- if (ele)
- {
- if (ele->valueType == FMI_TYPE_CSTRING)
- {
- // Free the copy of the string we took
- delete[] (char *)ele->u.stringValue;
- }
- delete ele;
- }
- }
-
- #define MY_BLOCK_SIZE 16
- static const char needsEscape[] = {
- FMI_FONTPART_DEFAULT, FMI_FONTPART_SEPERATOR,
- FMI_FONTPART_ESCAPE, FMI_FONTPART_ATTRSEPERATOR,
- '\0',
- };
-
-
- int FontMatchInfoObject::
- addToString(const char *&str, int &strLen, int &strMaxLen, struct fmi_attr_store *ele)
- {
- const char *value;
- char *newValue = NULL;
- char strValue[64]; // XXX There must be a better way to do this.
- int ret = 0;
-
- addToString(str, strLen, strMaxLen, FMI_FONTPART_SEPERATOR);
- if (count() > MAX_STANDARD_ATTRIBUTES)
- {
- // Add the attribute also
- addToString(str, strLen, strMaxLen, ele->attr);
- addToString(str, strLen, strMaxLen, ":");
- }
-
- if (ele->valueType == FMI_TYPE_JINT)
- {
- strValue[0] = '\0';
- if (ele->u.intValue > 0)
- {
- sprintf(strValue, "%d", ele->u.intValue);
- }
- value = strValue;
- }
- else
- {
- // Escape {:-*} in value. These have special meaning to us.
- value = ele->u.stringValue;
- if (value && *value)
- {
- newValue = EscapeString(value, needsEscape);
- if (!newValue)
- {
- // ERROR: No memory
- return (-1);
- }
- value = newValue;
- }
- }
- ret = addToString(str, strLen, strMaxLen, value);
- if (newValue)
- {
- delete[] newValue;
- }
- return (ret);
- }
-
- int FontMatchInfoObject::
- addToString(const char *&str, int &strLen, int &strMaxLen, const char *value)
- {
- int valueLen = 0;
- if (!value || !*value)
- {
- // Use default symbol
- return (0);
- }
- valueLen = strlen(value);
-
- while ((strMaxLen - strLen) <= valueLen)
- {
- str = (char *)WF_REALLOC((char*)str,strMaxLen + MY_BLOCK_SIZE);
- if (str == NULL) return 0;
- strMaxLen += MY_BLOCK_SIZE;
- }
-
- strcpy((char*)(str+strLen), value);
- strLen += valueLen;
- return strLen;
- }
-
- int FontMatchInfoObject::
- addToString(const char *&str, int &strLen, int &strMaxLen, const char value)
- {
- if ((strMaxLen - strLen) <= 1)
- {
- str = (char *)WF_REALLOC((char*)str,strMaxLen + MY_BLOCK_SIZE);
- if (str == NULL) return 0;
- strMaxLen += MY_BLOCK_SIZE;
- }
-
- *((char *)(str+strLen)) = value;
- strLen++;
- *((char *)(str+strLen)) = '\0';
- return strLen;
- }
-
- int FontMatchInfoObject::
- releaseStringRepresentation(void)
- {
- if (stringRepresentation)
- {
- WF_FREE((char*)stringRepresentation);
- stringRepresentation = NULL;
- stringLen = stringMaxLen = 0;
- }
- return (0);
- }
-
- //
- // Scans for the next fontpart from str and copies it into fontpart.
- // Assumes enough memory has been allocated for fontpart.
- // If value/attr are non-null, then points value and attr to their
- // appropriate places in fontpart
- //
- const char *FontMatchInfoObject::
- scanFontpart(const char *str, char *fontpart, const char *&value, const char *&attr)
- {
- char *attrEnd = NULL;
-
- if (attr) attr = NULL;
- if (value) value = fontpart;
- if (*str == FMI_FONTPART_SEPERATOR)
- str++;
- while (*str && *str != FMI_FONTPART_SEPERATOR)
- {
- if (*str == FMI_FONTPART_ESCAPE)
- {
- str++;
- }
- else
- {
- if (*str == FMI_FONTPART_ATTRSEPERATOR)
- {
- attrEnd = fontpart+1;
- }
-
- }
- *fontpart++ = *str++;
- }
- *fontpart = '\0';
-
- if (attrEnd)
- {
- if (attr) attr = fontpart;
- *attrEnd = '\0';
- if (value) value = attrEnd+1;
- }
- return (str);
- }
-