chimera2/html/font.c

476 lines
8.8 KiB
C

/*
* font.c
*
* libhtml - HTML->X renderer
*
* Copyright (c) 1995-1997, John Kilburg <john@cs.unlv.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "port_before.h"
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "port_after.h"
#include "html.h"
/*
*
* You really don't want to look in here.
*
*/
#define FONT_SCALE_COUNT 6
#define XLFD_FOUNDRY 0
#define XLFD_FAMILY 1
#define XLFD_WEIGHT_NAME 2
#define XLFD_SLANT 3
#define XLFD_SETWIDTH_NAME 4
#define XLFD_STYLE_NAME 5
#define XLFD_PIXEL_SIZE 6
#define XLFD_POINT_SIZE 7
#define XLFD_RES_X 8
#define XLFD_RES_Y 9
#define XLFD_SPACING 9
#define XLFD_AVERAGE_WIDTH 10
#define XLFD_REGISTRY 11
#define XLFD_ENCODING 12
#define XLFD_COUNT 13
/* Silly font information */
struct HTMLFontP
{
bool fixed; /* fixed width? */
int weight; /* bold, medium, ... */
int slant; /* italic, regular, ... */
int scale; /* scale of font */
int size; /* size of font */
XFontStruct *xfi; /* real font info */
};
struct HTMLFontListP
{
HTMLFont fontInfo;
int count;
int scale[FONT_SCALE_COUNT];
char **names;
};
static void ParseXLFD _ArgProto((MemPool, char *, HTMLFont));
static HTMLFontList GetFontList _ArgProto((HTMLClass, char *));
static void FreeFontList _ArgProto((HTMLClass, HTMLFontList));
static XFontStruct *GetFont _ArgProto((HTMLClass, HTMLFontList, int));
/*
* ParseXLFD
*
* Yipe!
*/
static void
ParseXLFD(mp, xlfd, lfi)
MemPool mp;
char *xlfd;
HTMLFont lfi;
{
char *fields[XLFD_COUNT];
int i;
char *t;
t = MPStrDup(mp, xlfd);
t++;
fields[0] = t;
for (i = 1; i < XLFD_COUNT; t++)
{
if (*t == '-')
{
*t = '\0';
fields[i++] = t + 1;
}
}
if (strcmp(fields[XLFD_WEIGHT_NAME], "bold") == 0 ||
strcmp(fields[XLFD_WEIGHT_NAME], "demi") == 0 ||
strcmp(fields[XLFD_WEIGHT_NAME], "demibold") == 0)
{
lfi->weight = 1;
}
else lfi->weight = 0;
lfi->size = atoi(fields[XLFD_PIXEL_SIZE]);
if (strcmp(fields[XLFD_SLANT], "i") == 0 ||
strcmp(fields[XLFD_SLANT], "o") == 0)
{
lfi->slant = 1;
}
else lfi->slant = 0;
return;
}
/*
* GetFont
*/
static XFontStruct *
GetFont(lc, fl, i)
HTMLClass lc;
HTMLFontList fl;
int i;
{
if (fl->fontInfo[i].xfi == NULL)
{
fl->fontInfo[i].xfi = XLoadQueryFont(lc->dpy, fl->names[i]);
if (fl->fontInfo[i].xfi == NULL) return(lc->defaultFont);
}
return(fl->fontInfo[i].xfi);
}
/*
* HTMLGetFont
*/
XFontStruct *
HTMLGetFont(li, env)
HTMLInfo li;
HTMLEnv env;
{
int i;
HTMLClass lc = li->lc;
HTMLFont lfi;
HTMLFontList fl;
lfi = env->fi;
if (lfi == NULL)
{
lfi = HTMLDupFont(li,li->cfi);
env->fi = lfi;
}
/*
* Check spacing
*/
if (lfi->fixed) fl = lc->fixed;
else fl = lc->prop;
/*
* Check slant, size, and weight
*/
for (i = 0; i < fl->count; i++)
{
if (((lfi->weight > 0) == (fl->fontInfo[i].weight > 0)) &&
((lfi->slant > 0) == (fl->fontInfo[i].slant > 0)) &&
fl->scale[lfi->scale] == fl->fontInfo[i].size)
{
return(GetFont(lc, fl, i));
}
}
/*
* Check slant and size
*/
for (i = 0; i < fl->count; i++)
{
if (((lfi->slant > 0) == (fl->fontInfo[i].slant > 0)) &&
fl->scale[lfi->scale] == fl->fontInfo[i].size)
{
return(GetFont(lc, fl, i));
}
}
/*
* Check weight and size
*/
for (i = 0; i < fl->count; i++)
{
if (((lfi->weight > 0) == (fl->fontInfo[i].weight > 0)) &&
fl->scale[lfi->scale] == fl->fontInfo[i].size)
{
return(GetFont(lc, fl, i));
}
}
/*
* Check size
*/
for (i = 0; i < fl->count; i++)
{
if (fl->scale[lfi->scale] == fl->fontInfo[i].size)
{
return(GetFont(lc, fl, i));
}
}
return(lc->defaultFont);
}
/*
* GetFontList
*/
static HTMLFontList
GetFontList(lc, pattern)
HTMLClass lc;
char *pattern;
{
int count;
int scale_count;
int i, j, k;
MemPool mp;
HTMLFontList fl;
fl = (HTMLFontList)MPCGet(lc->mp, sizeof(struct HTMLFontListP));
fl->names = XListFonts(lc->dpy, pattern, 999, &count);
if (fl->names == NULL || count == 0)
{
fprintf (stderr, "Could not get font list\n");
fflush(stderr);
exit(1);
}
fl->fontInfo = (HTMLFont)MPCGet(lc->mp, sizeof(struct HTMLFontP) * count);
/*
* Extract simple information from the XLFD strings.
*/
mp = MPCreate();
for (i = 0; i < count; i++)
{
ParseXLFD(mp, fl->names[i], &(fl->fontInfo[i]));
}
MPDestroy(mp);
/*
* Find sizes for each of the font scales. There must be a better way.
* This should probably not take
*/
scale_count = 0;
for (i = 0; i < count && scale_count < FONT_SCALE_COUNT; i++)
{
if (fl->fontInfo[i].size > 0)
{
for (j = 0; j < scale_count; j++)
{
if (fl->fontInfo[i].size == fl->scale[j]) break;
if (fl->fontInfo[i].size < fl->scale[j])
{
for (k = scale_count - 1; k >= j; k--)
{
fl->scale[k + 1] = fl->scale[k];
}
fl->scale[j] = fl->fontInfo[i].size;
scale_count++;
break;
}
}
if (j == scale_count)
{
fl->scale[j] = fl->fontInfo[i].size;
scale_count++;
}
}
}
/*
* This will probably never happen.
*/
if (scale_count == 0)
{
fl->scale[0] = fl->fontInfo[0].size;
scale_count++;
}
/*
* Fill out the rest if there aren't FONT_SCALE_COUNT
*/
if (scale_count < FONT_SCALE_COUNT)
{
for (i = scale_count; i < FONT_SCALE_COUNT; i++)
{
fl->scale[i] = fl->scale[i - 1];
}
scale_count = FONT_SCALE_COUNT;
}
/*
* Set miscellaneous information.
*/
fl->count = count;
return(fl);
}
/*
* HTMLSetupFonts
*/
void
HTMLSetupFonts(li)
HTMLInfo li;
{
char *name;
HTMLClass lc = li->lc;
/*
* Default HTML font.
*/
li->cfi = (HTMLFont)MPCGet(li->mp, sizeof(struct HTMLFontP));
HTMLSetFontProp(li->cfi);
HTMLSetFontScale(li->cfi, 2);
/*
* Only need to do HTML font information setup once.
*/
if (lc->font_setup_done) return;
lc->dpy = li->dpy;
/*
* Font to use if all else fails
*/
name = ResourceGetString(li->cres, "html.defaultFont");
if (name == NULL) name = "variable";
if ((lc->defaultFont = XLoadQueryFont(li->dpy, name)) == NULL)
{
fprintf (stderr, "Could not get default font.\n");
fflush(stderr);
exit(1);
}
/*
* Get the font list pattern for the proportional fonts. Hopefully
* a reasonable pattern was selected.
*/
name = ResourceGetString(li->cres, "html.propFontPattern");
if (name == NULL) name = "-adobe-times-*-*-*-*-*-*-*-*-*-*-iso8859-1";
lc->prop = GetFontList(lc, name);
/*
* Get the font list pattern for the fixed fonts. Hopefully
* a reasonable pattern was selected.
*/
name = ResourceGetString(li->cres, "html.fixedFontPattern");
if (name == NULL) name = "-misc-fixed-*-*-*-*-*-*-*-*-*-*-iso8859-1";
lc->fixed = GetFontList(lc, name);
lc->font_setup_done = true;
return;
}
/*
* FreeFontList
*/
static void
FreeFontList(lc, fl)
HTMLClass lc;
HTMLFontList fl;
{
int i;
if (fl->fontInfo != NULL)
{
for (i = 0; i < fl->count; i++)
{
if (fl->fontInfo[i].xfi != NULL &&
fl->fontInfo[i].xfi != lc->defaultFont)
{
XFreeFont(lc->dpy, fl->fontInfo[i].xfi);
}
}
}
if (fl->names != NULL) XFreeFontNames(fl->names);
return;
}
/*
* HTMLFreeFonts
*/
void
HTMLFreeFonts(lc)
HTMLClass lc;
{
if (lc->prop != NULL) FreeFontList(lc, lc->prop);
if (lc->fixed != NULL) FreeFontList(lc, lc->fixed);
if (lc->defaultFont != NULL) XFreeFont(lc->dpy, lc->defaultFont);
return;
}
HTMLFont
HTMLDupFont(li, f)
HTMLInfo li;
HTMLFont f;
{
HTMLFont n;
n = (HTMLFont)MPCGet(li->mp, sizeof(struct HTMLFontP));
memcpy(n, f, sizeof(struct HTMLFontP));
return(n);
}
void
HTMLAddFontWeight(f)
HTMLFont f;
{
f->weight++;
return;
}
void
HTMLAddFontSlant(f)
HTMLFont f;
{
f->slant++;
return;
}
void
HTMLAddFontScale(f)
HTMLFont f;
{
f->scale++;
return;
}
void
HTMLSetFontScale(f, scale)
HTMLFont f;
int scale;
{
f->scale = scale;
return;
}
void
HTMLSetFontProp(f)
HTMLFont f;
{
f->fixed = false;
return;
}
void
HTMLSetFontFixed(f)
HTMLFont f;
{
f->fixed = true;
return;
}