summaryrefslogtreecommitdiff
path: root/src/Speedo/spinfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Speedo/spinfo.c')
-rw-r--r--src/Speedo/spinfo.c441
1 files changed, 441 insertions, 0 deletions
diff --git a/src/Speedo/spinfo.c b/src/Speedo/spinfo.c
new file mode 100644
index 0000000..05d3f24
--- /dev/null
+++ b/src/Speedo/spinfo.c
@@ -0,0 +1,441 @@
+/* $Xorg: spinfo.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Network Computing Devices or Digital
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Dave Lemke, Network Computing Devices, Inc
+ */
+
+/*
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#include "fntfilst.h"
+#include "spint.h"
+#include <math.h>
+
+/* percentage of pointsize used to specify ascent & descent */
+#define STRETCH_FACTOR 120
+
+enum scaleType {
+ atom, truncate_atom, pixel_size, point_size, resolution_x,
+ resolution_y, average_width
+};
+
+typedef struct _fontProp {
+ char *name;
+ long atom;
+ enum scaleType type;
+} fontProp;
+
+static fontProp fontNamePropTable[] = {
+ { "FOUNDRY", 0, atom },
+ { "FAMILY_NAME", 0, atom },
+ { "WEIGHT_NAME", 0, atom },
+ { "SLANT", 0, atom },
+ { "SETWIDTH_NAME", 0, atom },
+ { "ADD_STYLE_NAME", 0, atom },
+ { "PIXEL_SIZE", 0, pixel_size },
+ { "POINT_SIZE", 0, point_size },
+ { "RESOLUTION_X", 0, resolution_x },
+ { "RESOLUTION_Y", 0, resolution_y },
+ { "SPACING", 0, atom },
+ { "AVERAGE_WIDTH", 0, average_width },
+ { "CHARSET_REGISTRY", 0, atom },
+ { "CHARSET_ENCODING", 0, truncate_atom }
+};
+
+/* Warning: following array is closely related to the sequence of
+ defines after it. */
+
+static fontProp extraProps[] = {
+ { "FONT", 0, },
+ { "COPYRIGHT", 0, },
+ { "RAW_PIXEL_SIZE", 0, },
+ { "RAW_POINT_SIZE", 0, },
+ { "RAW_ASCENT", 0, },
+ { "RAW_DESCENT", 0, },
+ { "RAW_AVERAGE_WIDTH", 0, }
+};
+
+/* this is a bit kludgy */
+#define FONTPROP 0
+#define COPYRIGHTPROP 1
+#define RAWPIXELPROP 2
+#define RAWPOINTPROP 3
+#define RAWASCENTPROP 4
+#define RAWDESCENTPROP 5
+#define RAWWIDTHPROP 6
+
+
+#define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
+#define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp))
+
+#define NPROPS (NNAMEPROPS + NEXTRAPROPS)
+
+extern Atom MakeAtom();
+
+void
+sp_make_standard_props()
+{
+ int i;
+ fontProp *t;
+
+ i = sizeof(fontNamePropTable) / sizeof(fontProp);
+ for (t = fontNamePropTable; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+ i = sizeof(extraProps) / sizeof(fontProp);
+ for (t = extraProps; i; i--, t++)
+ t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
+}
+
+void
+sp_make_header(spf, pinfo)
+ SpeedoFontPtr spf;
+ FontInfoPtr pinfo;
+{
+ int pixel_size;
+ SpeedoMasterFontPtr spmf = spf->master;
+
+ pinfo->firstCol = spmf->first_char_id & 0xff;
+ pinfo->firstRow = spmf->first_char_id >> 8;
+ pinfo->lastCol = spmf->max_id & 0xff;
+ pinfo->lastRow = spmf->max_id >> 8;
+
+ /* XXX -- hackery here */
+ pinfo->defaultCh = 0;
+/* computed by FontComputeInfoAccelerators:
+ * noOverlap
+ * constantMetrics
+ * terminalFont
+ * constantWidth
+ * inkInside
+ */
+ pinfo->inkMetrics = 0;
+ pinfo->allExist = 0;
+ pinfo->drawDirection = LeftToRight;
+ pinfo->cachable = 1;
+ if (spf->specs.xxmult != spf->specs.yymult)
+ pinfo->anamorphic = TRUE;
+ else
+ pinfo->anamorphic = FALSE;
+/* computed by sp_compute_bounds:
+ * maxOverlap
+ * maxbounds
+ * minbounds
+ * ink_maxbounds
+ * ink_minbounds
+ */
+ pixel_size = spf->vals.pixel_matrix[3] * STRETCH_FACTOR / 100;
+ pinfo->fontAscent = pixel_size * 764 / 1000; /* 764 == EM_TOP */
+ pinfo->fontDescent = pixel_size - pinfo->fontAscent;
+}
+
+static void
+adjust_min_max(minc, maxc, tmp)
+ xCharInfo *minc,
+ *maxc,
+ *tmp;
+{
+#define MINMAX(field,ci) \
+ if (minc->field > (ci)->field) \
+ minc->field = (ci)->field; \
+ if (maxc->field < (ci)->field) \
+ maxc->field = (ci)->field;
+
+ MINMAX(ascent, tmp);
+ MINMAX(descent, tmp);
+ MINMAX(leftSideBearing, tmp);
+ MINMAX(rightSideBearing, tmp);
+ MINMAX(characterWidth, tmp);
+
+ if ((INT16)minc->attributes > (INT16)tmp->attributes)
+ minc->attributes = tmp->attributes;
+ if ((INT16)maxc->attributes < (INT16)tmp->attributes)
+ maxc->attributes = tmp->attributes;
+
+#undef MINMAX
+}
+
+
+void
+sp_compute_bounds(spf, pinfo, flags, sWidth)
+ SpeedoFontPtr spf;
+ FontInfoPtr pinfo;
+ unsigned long flags;
+ long *sWidth;
+{
+ int i,
+ id,
+ index,
+ maxOverlap,
+ overlap,
+ total_width = 0;
+ xCharInfo minchar,
+ maxchar,
+ tmpchar;
+ bbox_t bbox;
+ fix31 width;
+ double pix_width;
+ SpeedoMasterFontPtr spmf = spf->master;
+ int firstChar;
+ int num_chars = 0;
+
+ firstChar = spmf->first_char_id;
+ minchar.ascent = minchar.descent =
+ minchar.leftSideBearing = minchar.rightSideBearing =
+ minchar.characterWidth = minchar.attributes = 32767;
+ maxchar.ascent = maxchar.descent =
+ maxchar.leftSideBearing = maxchar.rightSideBearing =
+ maxchar.characterWidth = maxchar.attributes = -32767;
+ maxOverlap = -32767;
+ *sWidth = 0;
+ for (i = 0; i < spmf->num_chars; i++) {
+ int j;
+ int char_id;
+
+ index = spmf->enc[i * 2 + 1];
+ char_id = spmf->enc[i * 2];
+ /*
+ * See if this character is in the list of ranges specified in the
+ * XLFD name
+ */
+ for (j = 0; j < spf->vals.nranges; j++)
+ if (char_id >= mincharno(spf->vals.ranges[j]) &&
+ char_id <= maxcharno(spf->vals.ranges[j]))
+ break;
+ if (spf->vals.nranges && j == spf->vals.nranges)
+ continue;
+ num_chars++;
+
+ if (!(flags & ComputeBoundsOnly)) {
+
+ width = sp_get_char_width(index);
+
+ /* convert to pixel coords */
+ pix_width = (int)width * (spf->specs.xxmult / 65536L) +
+ ((int) width * (spf->specs.xxmult % 65536L))
+ / 65536L;
+ pix_width /= 65536L;
+
+ (void) sp_get_char_bbox(index, &bbox);
+ bbox.ymax = (bbox.ymax + 32768L) >> 16;
+ bbox.ymin = (bbox.ymin + 32768L) >> 16;
+ bbox.xmin = (bbox.xmin + 32768L) >> 16;
+ bbox.xmax = (bbox.xmax + 32768L) >> 16;
+ tmpchar.ascent = bbox.ymax;
+ tmpchar.descent = -bbox.ymin;
+ tmpchar.characterWidth = (int)(pix_width + /* round */
+ (pix_width > 0 ? 0.5 : -0.5));
+ tmpchar.rightSideBearing = bbox.xmax;
+ tmpchar.leftSideBearing = bbox.xmin;
+
+ if (!tmpchar.characterWidth &&
+ tmpchar.ascent == -tmpchar.descent &&
+ tmpchar.rightSideBearing == tmpchar.leftSideBearing)
+ {
+ /* Character appears non-existent, probably as a result
+ of the transformation. Let's give it one pixel in
+ the universe so it's not mistaken for non-existent. */
+ tmpchar.leftSideBearing = tmpchar.descent = 0;
+ tmpchar.rightSideBearing = tmpchar.ascent = 1;
+ }
+
+ tmpchar.attributes = (int)((double)(int)width / 65.536 + .5);
+ }
+ else
+ tmpchar = spf->encoding[char_id - firstChar].metrics;
+
+ adjust_min_max(&minchar, &maxchar, &tmpchar);
+ overlap = tmpchar.rightSideBearing - tmpchar.characterWidth;
+ if (maxOverlap < overlap)
+ maxOverlap = overlap;
+
+ total_width += ((int)(INT16)tmpchar.attributes);
+ *sWidth += abs((int)(INT16)tmpchar.attributes);
+
+ if (flags & SaveMetrics) {
+ id = spmf->enc[i * 2] - firstChar;
+ assert(id <= spmf->max_id - firstChar);
+ spf->encoding[id].metrics = tmpchar;
+ }
+ }
+
+
+ if (num_chars > 0)
+ {
+ *sWidth = (int)(((double)*sWidth * 10.0 + (double)num_chars / 2.0) /
+ num_chars);
+ if (total_width < 0)
+ {
+ /* Predominant direction is R->L */
+ *sWidth = -*sWidth;
+ }
+ spf->vals.width = (int)((double)*sWidth * spf->vals.pixel_matrix[0] /
+ 1000.0 +
+ (spf->vals.pixel_matrix[0] > 0 ? .5 : -.5));
+ }
+ else
+ {
+ spf->vals.width = 0;
+ }
+ pinfo->maxbounds = maxchar;
+ pinfo->minbounds = minchar;
+ pinfo->ink_maxbounds = maxchar;
+ pinfo->ink_minbounds = minchar;
+ pinfo->maxOverlap = maxOverlap;
+}
+
+void
+sp_compute_props(spf, fontname, pinfo, sWidth)
+ SpeedoFontPtr spf;
+ char *fontname;
+ FontInfoPtr pinfo;
+ long sWidth;
+{
+ FontPropPtr pp;
+ int i,
+ nprops;
+ fontProp *fpt;
+ char *is_str;
+ char *ptr1,
+ *ptr2;
+ char *ptr3;
+ char tmpname[1024];
+ FontScalableRec tmpvals;
+
+ nprops = pinfo->nprops = NPROPS;
+ pinfo->isStringProp = (char *) xalloc(sizeof(char) * nprops);
+ pinfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops);
+ if (!pinfo->isStringProp || !pinfo->props) {
+ xfree(pinfo->isStringProp);
+ pinfo->isStringProp = (char *) 0;
+ xfree(pinfo->props);
+ pinfo->props = (FontPropPtr) 0;
+ return;
+ }
+ bzero(pinfo->isStringProp, (sizeof(char) * nprops));
+
+ ptr2 = fontname;
+ for (i = NNAMEPROPS, pp = pinfo->props, fpt = fontNamePropTable,
+ is_str = pinfo->isStringProp;
+ i;
+ i--, pp++, fpt++, is_str++) {
+
+ if (*ptr2)
+ {
+ ptr1 = ptr2 + 1;
+ if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
+ }
+
+ pp->name = fpt->atom;
+ switch (fpt->type) {
+ case atom:
+ *is_str = TRUE;
+ pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
+ break;
+ case truncate_atom:
+ *is_str = TRUE;
+ for (ptr3 = ptr1; *ptr3; ptr3++)
+ if (*ptr3 == '[')
+ break;
+ pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
+ break;
+ case pixel_size:
+ pp->value = (int)(spf->vals.pixel_matrix[3] +
+ (spf->vals.pixel_matrix[3] > 0 ? .5 : -.5));
+ break;
+ case point_size:
+ pp->value = (int)(spf->vals.point_matrix[3] * 10.0 +
+ (spf->vals.point_matrix[3] > 0 ? .5 : -.5));
+ break;
+ case resolution_x:
+ pp->value = spf->vals.x;
+ break;
+ case resolution_y:
+ pp->value = spf->vals.y;
+ break;
+ case average_width:
+ pp->value = spf->vals.width;
+ break;
+ }
+ }
+
+ for (i = 0, fpt = extraProps; i < NEXTRAPROPS; i++, is_str++, pp++, fpt++) {
+ pp->name = fpt->atom;
+ switch (i) {
+ case FONTPROP:
+ *is_str = TRUE;
+ strcpy(tmpname, fontname);
+ FontParseXLFDName(tmpname, &tmpvals, FONT_XLFD_REPLACE_ZERO);
+ FontParseXLFDName(tmpname, &spf->vals, FONT_XLFD_REPLACE_VALUE);
+ pp->value = MakeAtom(tmpname, strlen(tmpname), TRUE);
+ break;
+ case COPYRIGHTPROP:
+ *is_str = TRUE;
+ pp->value = MakeAtom(spf->master->copyright,
+ strlen(spf->master->copyright), TRUE);
+ break;
+ case RAWPIXELPROP:
+ *is_str = FALSE;
+ pp->value = 1000;
+ break;
+ case RAWPOINTPROP:
+ *is_str = FALSE;
+ pp->value = (long)(72270.0 / (double)spf->vals.y + .5);
+ break;
+ case RAWASCENTPROP:
+ *is_str = FALSE;
+ pp->value = STRETCH_FACTOR * 764 / 100;
+ break;
+ case RAWDESCENTPROP:
+ *is_str = FALSE;
+ pp->value = STRETCH_FACTOR * 236 / 100;
+ break;
+ case RAWWIDTHPROP:
+ *is_str = FALSE;
+ pp->value = sWidth;
+ break;
+ }
+ }
+}