home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
x
/
xhyper10.zip
/
XHyper_v1.0
/
src
/
Tag.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-08
|
15KB
|
616 lines
/*
* Copyright (c) 1992 U.S. Geological Survey (USGS)
*
* 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 name of USGS not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. USGS makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* USGS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL USGS
* 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.
*
*/
/*
* Tag
*/
#include <InterViews/character.h>
#include <InterViews/color.h>
#include <InterViews/discretion.h>
#include <InterViews/font.h>
#include <InterViews/glue.h>
#include <InterViews/glyph.h>
#include <InterViews/psfont.h>
#include <InterViews/space.h>
#include <InterViews/strut.h>
#include <InterViews/style.h>
#include <InterViews/world.h>
#include <string.h>
#include <stdio.h>
#include "TextView.h"
#include "Tag.h"
#include "list.h"
//
// *** defines available fonts
//
static FontList fontlist[] = {
{nil, "times-roman", 10},
{nil, "times-roman", 12},
{nil, "times-roman", 14},
{nil, "times-roman", 18},
{nil, "times-bold", 10},
{nil, "times-bold", 12},
{nil, "times-bold", 14},
{nil, "times-bold", 18},
{nil, nil, nil},
};
//
// *** declare font list
//
declareList(FontFamilyInfo_List,FontFamilyInfo)
implementList(FontFamilyInfo_List,FontFamilyInfo)
//
// *** creates font family
//
FontFamily* find_font_family (const char* name)
{
static FontFamilyInfo_List* _families;
if (_families == nil)
_families = new FontFamilyInfo_List();
if (strlen(name) == 0)
{
return nil;
}
else
{
long count = _families->count();
for (long i = 0; i < count; ++i)
{
FontFamilyInfo& info = _families->item(0);
if (strcmp(info._name, name) == 0)
break;
}
if (i == count)
{
FontFamilyInfo info;
info._name = strcpy(new char[strlen(name) + 1], name);
info._family = new FontFamily(name);
_families->append(info);
}
return _families->item(i)._family;
}
}
//
// *** initialize font list
//
void init_fonts()
{
static FontFamily* times;
static FontFamily* helvetica;
static FontFamily* courier;
char screenfont[100];
char* hyphen;
char* screenstyle;
char* fullname;
FontFamily* family;
FontList* fl;
float scale = 1.0;
int i;
i = 0;
while (fontlist[i]._font_name != nil)
{
fl = &fontlist[i]; //shorthand
strcpy(screenfont, fl->_font_name);
hyphen = strchr(screenfont, '-');
//
// *** find font family and style
//
if (hyphen != nil)
{
*hyphen = '\0';
screenstyle = hyphen+1;
}
else
screenstyle = "";
family = find_font_family(screenfont);
//
// *** if in list, load it; otherwise, use default
//
if (family != nil &&
family->font(int(fl->_pts), screenstyle, fullname, scale))
{
if (PSFont::exists(fl->_font_name))
fl->_font = new PSFont(fl->_font_name,
int(fl->_pts),
fullname,
scale);
else
fl->_font = new Font(fullname, scale);
}
else
fl->_font = (Font*)World::current()->font();
fl->_font->ref();
i++;
}
}
/*--------------------------------------------------------------------
Class SimpleTag
The SimpleTag class presently is a base class for the Font and
Paragraph tags. However in the future, it will be used to
define real or floating MML variables.
Members:
Id - return Id string
Class - returns class string
getid - defines id
getline - reads line of unpadded text from file
Define - makes all definitions
--------------------------------------------------------------------*/
SimpleTag::SimpleTag(const char* id, const char* cl, int v)
{
_id = strcpy(new char[strlen(id)+1], id);
_class = strcpy(new char[strlen(cl)+1], cl);
_ivalue = v;
}
SimpleTag::SimpleTag(const char* id, const char* cl, Coord v)
{
_id = strcpy(new char[strlen(id)+1], id);
_class = strcpy(new char[strlen(cl)+1], cl);
_rvalue = v;
}
SimpleTag::SimpleTag()
{
}
SimpleTag::~SimpleTag()
{
delete _id;
delete _class;
}
const char* SimpleTag::Id()
{
return (_id);
}
const char* SimpleTag::Class()
{
return (_class);
}
void SimpleTag::Define(FILE* fd)
{
}
void SimpleTag::getline(FILE* fd, char* line)
{
int i = 0;
char c;
while (((c = fgetc(fd)) != '<') && (c != '>'));
if (c == '>')
line[i++] = '>';
else
while ((c = fgetc(fd)) != '>')
line[i++] = c;
line[i] = '\0';
}
void SimpleTag::getid(const char* line)
{
char tag[40];
char idbuf[40];
int i;
sscanf(line, "%s", &tag);
i = strlen(tag);
while((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%s", &idbuf);
_id = strcpy(new char[strlen(idbuf)+1], idbuf);
return;
}
/*--------------------------------------------------------------------
Class FontTag
The FontTag are variables which define a given font. FontTags may
be used within a paragraph text or within a paragraph tag definition.
Members:
font - returns pointer to given font in list
Name - return the full name of the font
Points - return the point size of the font
index - return the list index of the tag
findfont - finds font name in definition
lookup_fontt - finds font in list
--------------------------------------------------------------------*/
FontTag::FontTag(const char* id, int v) : SimpleTag(id, "FontTag", v)
{
_index = 0;
}
FontTag::FontTag(const char* line, FILE* fd)
{
_index = 0;
_class = strcpy(new char[strlen("FontTag")+1], "FontTag");
getid(line);
if (strcmp(_id, "deffont") != 0)
findfont(fd);
}
FontTag::~FontTag()
{
}
void FontTag::findfont(FILE* fd)
{
char line[100];
char key[40];
char fontname[80];
char style[40];
int pts;
int i=0;
getline(fd, line);
while(line[0] != '>')
{
if (strncasecmp(line, "Family", 6) == 0)
{
i = strlen("Family");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%s", fontname);
}
else if (strncasecmp(line, "pts", 3) == 0)
{
i = strlen("pts");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%d", &pts);
}
else
{
strcat(fontname, "-");
if (strncasecmp(line, "plain", 5) == 0)
strcat(fontname, "Roman");
else
sscanf(line, "%s", fontname+strlen(fontname));
}
getline(fd, line);
}
_index = lookup_font(fontname, pts);
}
int FontTag::lookup_font(const char*name, int pts)
{
int i = 0;
while (fontlist[i]._font != nil)
if ((strcasecmp(fontlist[i]._font_name, name) == 0) &&
(fontlist[i]._pts == pts))
break;
else
i++;
if (fontlist[i]._font != nil)
return(i);
else
return(0);
}
int FontTag::index()
{
return _index;
}
int FontTag::Points()
{
return (fontlist[_index]._pts);
}
const char* FontTag::Name()
{
return (fontlist[_index]._font_name);
}
Font* FontTag::font()
{
return (fontlist[_index]._font);
}
/*--------------------------------------------------------------------
Class ParaTag
The ParaTag are variables which define a given paragraph style.
Presently, only alignment and fonts are supported.
Members:
fonttag - returns font definition
setalign - defines alignment variables
define - define Tag
discretionaries - defines discret. variables
--------------------------------------------------------------------*/
ParaTag::ParaTag(const char* id) : SimpleTag(id, "ParaTag", int(0))
{
_hypertext = false;
_leading = 0;
_left = 0;
_after = 0;
_before = 0;
_font = new FontTag("deffont", 0);
setalign("Left");
discretionaries();
}
ParaTag::ParaTag(const char* line, FILE* fd, TextView *view)
{
_hypertext = false;
_class = strcpy(new char[strlen("ParaTag")+1], "ParaTag");
_font = nil;
_alignment = nil;
_interline_glue = nil;
_interpar_glue = nil;
_leading = 0;
_left = 0;
_after = 0;
_before = 0;
getid(line);
define(fd, view);
if (_font == nil)
_font = new FontTag("deffont", 0);
/*
* *** default is justified
*/
if (_alignment == nil)
setalign("left");
else
setalign(_alignment);
discretionaries();
}
ParaTag::~ParaTag()
{
if (_alignment != nil)
delete _alignment;
_begin_line_strut->unref();
_end_line_strut->unref();
_begin_par_strut->unref();
_end_par_strut->unref();
_line_strut->unref();
_fil_strut->unref();
_hyphen->unref();
_interline_glue->unref();
_interpar_glue->unref();
_hfil_glue->unref();
_hfill_glue->unref();
_vfil_glue->unref();
_word_space->unref();
delete _font;
}
void ParaTag::discretionaries()
{
Color* fg = (Color*)Session::instance()->style()->foreground();
_line_strut = new Strut(_font->font());
_line_strut->ref();
_fil_strut = new Strut(_font->font(), 0, fil, 0);
_fil_strut->ref();
_hyphen = new Character('-', _font->font(), fg);
_hyphen->ref();
if (_interline_glue == nil)
{
_interline_glue = new VGlue(0, 10, 0);
_interline_glue->ref();
}
if (_interpar_glue == nil)
{
_interpar_glue = new VGlue(10, 10.0, 0);
_interpar_glue->ref();
}
_hfil_glue = new HGlue(0, fil, 0);
_hfil_glue->ref();
_hfill_glue = new HGlue(0, 1000000*fil, 0);
_hfill_glue->ref();
_vfil_glue = new VGlue(0, fil, 0);
_vfil_glue->ref();
_word_space = new Space(2, 0.5, _font->font(), fg);
_word_space->ref();
}
void ParaTag::define(FILE* fd, TextView* view)
{
char line[100];
char key[40];
char fontname[80];
char style[40];
char* gt;
int i;
getline(fd, line);
while(line[0] != '>')
{
if (strncasecmp(line, "Alignment", 9) == 0)
{
i = strlen("Alignment");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
if ((gt = strchr(line, '>')) != 0)
gt[0] = '\0';
_alignment = strcpy(new char[strlen(line+i)+1], line+i);
}
else if (strncasecmp(line, "Hypertext", 9) == 0)
{
_hypertext = true;
}
else if (strncasecmp(line, "Leading", 7) == 0)
{
i = strlen("Leading");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &_leading);
_interline_glue = new VGlue(_leading, 10, 0);
_interline_glue->ref();
}
else if (strncasecmp(line, "FirstIndent", 11) == 0)
{
i = strlen("FirstIndent");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &_first);
}
else if (strncasecmp(line, "LeftIndent", 10) == 0)
{
i = strlen("LeftIndent");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &_left);
}
else if (strncasecmp(line, "RightIndent", 11) == 0)
{
float right;
i = strlen("RightIndent");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &right);
}
else if (strncasecmp(line, "SpaceAfter", 10) == 0)
{
i = strlen("SpaceAfter");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &_after);
}
else if (strncasecmp(line, "SpaceBefore", 11) == 0)
{
i = strlen("SpaceBefore");
while ((line[i] == ' ') || (line[i] == '\t'))
i++;
sscanf(line+i, "%f", &_before);
_interpar_glue = new VGlue(_before, 10.0, 0);
_interpar_glue->ref();
}
else
{
for (i = 0; i < view->_numfont; i++)
{
if (strcasecmp(view->fontlist[i]->Id(), line) == 0)
{
_font = view->fontlist[i];
break;
}
}
}
getline(fd, line);
}
}
void ParaTag::setalign(char* align)
{
if (strncasecmp(align, "leftright", 9) == 0)
{
Color* fg = (Color*)Session::instance()->style()->foreground();
_begin_line_strut = new VStrut(0);
// _begin_line_strut = new Space(10, 0.5, _font->font(), fg);
_begin_par_strut = new VStrut(0);
_end_line_strut = new Strut(_font->font());
_end_par_strut = new Strut(_font->font(), 0, fil, 0);
}
else if (strncasecmp(align, "right", 5) == 0)
{
_begin_line_strut = new VStrut(0, 0, 0, fil, 0);
_begin_par_strut = new VStrut(_before, 0, 0, fil, 0);
_end_line_strut = new Strut(_font->font());
_end_par_strut = new Strut(_font->font());
}
else if (strncasecmp(align, "center", 6) == 0)
{
_begin_line_strut = new VStrut(0, 0, 0, fil, 0);
_begin_par_strut = new VStrut(0, 0, 0, fil, 0);
_end_line_strut = new Strut(_font->font(), 0, fil, 0);
_end_par_strut = new Strut(_font->font(), 0, fil, 0);
}
//
// *** default is left justified
//
else
{
_begin_line_strut = new VStrut(0);
_begin_par_strut = new VStrut(0);
_end_line_strut = new Strut(_font->font(), 0, fil, 0);
_end_par_strut = new Strut(_font->font(), 0, fil, 0);
}
_begin_line_strut->ref();
_end_line_strut->ref();
_begin_par_strut->ref();
_end_par_strut->ref();
}
FontTag* ParaTag::fonttag()
{
return(_font);
}