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 >
C/C++ Source or Header  |  1992-12-08  |  15KB  |  616 lines

  1.  
  2. /*
  3.  * Copyright (c) 1992 U.S. Geological Survey (USGS)
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of USGS not be used in advertising or
  10.  * publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.  USGS makes no representations about the
  12.  * suitability of this software for any purpose.  It is provided "as is"
  13.  * without express or implied warranty.
  14.  *
  15.  * USGS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL USGS
  17.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  18.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  20.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  *
  22.  */
  23.  
  24. /*
  25.  * Tag
  26.  */
  27. #include <InterViews/character.h>
  28. #include <InterViews/color.h>
  29. #include <InterViews/discretion.h>
  30. #include <InterViews/font.h>
  31. #include <InterViews/glue.h>
  32. #include <InterViews/glyph.h>
  33. #include <InterViews/psfont.h>
  34. #include <InterViews/space.h>
  35. #include <InterViews/strut.h>
  36. #include <InterViews/style.h>
  37. #include <InterViews/world.h>
  38. #include <string.h>
  39. #include <stdio.h>
  40.  
  41. #include "TextView.h"
  42. #include "Tag.h"
  43. #include "list.h"
  44.  
  45. //
  46. //  *** defines available fonts
  47. //
  48. static FontList fontlist[] = {
  49.    {nil,     "times-roman",         10},
  50.    {nil,     "times-roman",         12},
  51.    {nil,     "times-roman",         14},
  52.    {nil,     "times-roman",         18},
  53.    {nil,     "times-bold",         10},
  54.    {nil,     "times-bold",         12},
  55.    {nil,     "times-bold",         14},
  56.    {nil,     "times-bold",         18},
  57.    {nil,     nil,             nil},
  58.    };
  59.  
  60. //
  61. // *** declare font list
  62. //
  63. declareList(FontFamilyInfo_List,FontFamilyInfo)
  64. implementList(FontFamilyInfo_List,FontFamilyInfo)
  65.  
  66. //
  67. //  *** creates font family
  68. //
  69. FontFamily* find_font_family (const char* name) 
  70.    {
  71.    static FontFamilyInfo_List* _families;
  72.  
  73.    if (_families == nil) 
  74.       _families = new FontFamilyInfo_List();
  75.  
  76.    if (strlen(name) == 0) 
  77.       {
  78.       return nil;
  79.       }
  80.    else 
  81.       {
  82.       long count = _families->count();
  83.       for (long i = 0; i < count; ++i) 
  84.          {
  85.          FontFamilyInfo& info = _families->item(0);
  86.          if (strcmp(info._name, name) == 0) 
  87.             break;
  88.          }
  89.  
  90.       if (i == count) 
  91.          {
  92.          FontFamilyInfo info;
  93.          info._name = strcpy(new char[strlen(name) + 1], name);
  94.          info._family = new FontFamily(name);
  95.          _families->append(info);
  96.          }
  97.       return _families->item(i)._family;
  98.       }
  99.    }
  100.  
  101. //
  102. //  *** initialize font list
  103. //
  104. void init_fonts()
  105.    {
  106.    static FontFamily* times;
  107.    static FontFamily* helvetica;
  108.    static FontFamily* courier;
  109.    char             screenfont[100];
  110.    char*              hyphen;
  111.    char*              screenstyle;
  112.    char*              fullname;
  113.    FontFamily*        family;
  114.    FontList*          fl;
  115.    float          scale = 1.0;
  116.    int                i;
  117.  
  118.    i = 0;
  119.    while (fontlist[i]._font_name != nil)
  120.       {
  121.       fl = &fontlist[i]; //shorthand
  122.       strcpy(screenfont, fl->_font_name);
  123.       hyphen = strchr(screenfont, '-');
  124.  
  125.       //
  126.       //  *** find font family and style
  127.       //
  128.       if (hyphen != nil)
  129.          {
  130.          *hyphen = '\0';
  131.          screenstyle = hyphen+1;
  132.          }
  133.       else
  134.          screenstyle = "";
  135.  
  136.       family = find_font_family(screenfont);
  137.  
  138.       //
  139.       //  *** if in list, load it;  otherwise, use default
  140.       //
  141.       if (family != nil &&
  142.           family->font(int(fl->_pts), screenstyle, fullname, scale))
  143.          {
  144.          if (PSFont::exists(fl->_font_name))
  145.             fl->_font = new PSFont(fl->_font_name,
  146.                                   int(fl->_pts),
  147.                                   fullname,
  148.                                   scale);
  149.          else
  150.             fl->_font = new Font(fullname, scale);
  151.          }
  152.       else
  153.          fl->_font = (Font*)World::current()->font();
  154.  
  155.       fl->_font->ref();
  156.       i++;
  157.       }
  158.    }
  159.  
  160.  
  161. /*--------------------------------------------------------------------
  162.   Class  SimpleTag
  163.  
  164.   The SimpleTag class presently is a base class for the Font and
  165.   Paragraph tags.  However in the future, it will be used to 
  166.   define real or floating MML variables.
  167.  
  168.   Members:
  169.      Id        - return Id string
  170.      Class    - returns class string
  171.      getid    - defines id
  172.      getline    - reads line of unpadded text from file
  173.      Define     - makes all definitions
  174.   --------------------------------------------------------------------*/
  175. SimpleTag::SimpleTag(const char* id,  const char* cl, int v)
  176.    {
  177.    _id = strcpy(new char[strlen(id)+1], id);
  178.    _class = strcpy(new char[strlen(cl)+1], cl);
  179.  
  180.    _ivalue = v;
  181.    }
  182.  
  183. SimpleTag::SimpleTag(const char* id,  const char* cl, Coord v)
  184.    {
  185.    _id = strcpy(new char[strlen(id)+1], id);
  186.    _class = strcpy(new char[strlen(cl)+1], cl);
  187.  
  188.    _rvalue = v;
  189.    }
  190.  
  191. SimpleTag::SimpleTag()
  192.    {
  193.    }
  194.  
  195. SimpleTag::~SimpleTag()
  196.    {
  197.    delete _id;
  198.    delete _class;
  199.    }
  200.  
  201. const char* SimpleTag::Id()
  202.    {
  203.    return (_id);
  204.    } 
  205.  
  206. const char* SimpleTag::Class()
  207.    {
  208.    return (_class);
  209.    } 
  210.  
  211. void SimpleTag::Define(FILE* fd)
  212.    {
  213.    }
  214.  
  215. void SimpleTag::getline(FILE* fd, char* line)
  216.    {
  217.    int   i = 0;
  218.    char  c;
  219.  
  220.    while (((c = fgetc(fd)) != '<') && (c != '>'));
  221.  
  222.    if (c == '>')
  223.       line[i++] = '>';
  224.    else
  225.       while ((c = fgetc(fd)) != '>')
  226.          line[i++] = c;
  227.  
  228.    line[i] = '\0';
  229.    }
  230.  
  231. void SimpleTag::getid(const char* line)
  232.    {
  233.    char   tag[40];
  234.    char   idbuf[40];
  235.    int    i;
  236.  
  237.  
  238.    sscanf(line, "%s", &tag);
  239.    i = strlen(tag);
  240.    while((line[i] == ' ') || (line[i] == '\t'))
  241.       i++;
  242.  
  243.    sscanf(line+i, "%s", &idbuf);
  244.  
  245.    _id = strcpy(new char[strlen(idbuf)+1], idbuf);
  246.  
  247.    return;
  248.    }
  249.  
  250. /*--------------------------------------------------------------------
  251.   Class  FontTag
  252.  
  253.   The FontTag are variables which define a given font.  FontTags may
  254.   be used within a paragraph text or within a paragraph tag definition.
  255.  
  256.   Members:
  257.      font    - returns pointer to given font in list
  258.      Name    - return the full name of the font
  259.      Points     - return the point size of the font
  260.      index      - return the list index of the tag
  261.      findfont   - finds font name in definition
  262.      lookup_fontt - finds font in list
  263.   --------------------------------------------------------------------*/
  264.  
  265. FontTag::FontTag(const char* id, int v) : SimpleTag(id, "FontTag", v)
  266.    {
  267.    _index = 0;
  268.    }
  269.  
  270. FontTag::FontTag(const char* line, FILE* fd)
  271.    {
  272.    _index = 0;
  273.    _class = strcpy(new char[strlen("FontTag")+1], "FontTag");
  274.    getid(line);
  275.  
  276.    if (strcmp(_id, "deffont") != 0)
  277.       findfont(fd);
  278.    }
  279.  
  280. FontTag::~FontTag()
  281.    {
  282.    }
  283.  
  284. void FontTag::findfont(FILE* fd)
  285.    {
  286.    char   line[100];
  287.    char   key[40];
  288.    char   fontname[80];
  289.    char   style[40];
  290.    int    pts;
  291.    int    i=0;
  292.  
  293.    getline(fd, line);
  294.  
  295.    while(line[0] != '>')
  296.       {
  297.       if (strncasecmp(line, "Family", 6) == 0)
  298.          {
  299.          i = strlen("Family");
  300.          while ((line[i] == ' ') || (line[i] == '\t'))
  301.            i++;
  302.          sscanf(line+i, "%s", fontname);
  303.          }
  304.       else if (strncasecmp(line, "pts", 3) == 0)
  305.          {
  306.          i = strlen("pts");
  307.          while ((line[i] == ' ') || (line[i] == '\t'))
  308.            i++;
  309.          sscanf(line+i, "%d", &pts);
  310.          }
  311.       else 
  312.          {
  313.          strcat(fontname, "-");
  314.          if (strncasecmp(line, "plain", 5) == 0)
  315.             strcat(fontname, "Roman");
  316.          else
  317.             sscanf(line, "%s", fontname+strlen(fontname));
  318.          }
  319.  
  320.       getline(fd, line);
  321.       }
  322.  
  323.    _index = lookup_font(fontname, pts);
  324.    }
  325.  
  326. int FontTag::lookup_font(const char*name, int pts)
  327.    {
  328.    int   i = 0;
  329.  
  330.    while (fontlist[i]._font != nil) 
  331.       if ((strcasecmp(fontlist[i]._font_name, name) == 0) &&
  332.           (fontlist[i]._pts == pts))
  333.          break;
  334.       else
  335.          i++;
  336.  
  337.    if (fontlist[i]._font != nil)
  338.       return(i);
  339.    else
  340.       return(0);
  341.    }
  342.  
  343. int FontTag::index()
  344.    {
  345.    return _index;
  346.    }
  347.  
  348. int FontTag::Points()
  349.    {
  350.    return (fontlist[_index]._pts);
  351.    }
  352.  
  353. const char* FontTag::Name()
  354.    {
  355.    return (fontlist[_index]._font_name);
  356.    }
  357.  
  358. Font* FontTag::font()
  359.    {
  360.    return (fontlist[_index]._font);
  361.    }
  362.  
  363.  
  364. /*--------------------------------------------------------------------
  365.   Class  ParaTag
  366.  
  367.   The ParaTag are variables which define a given paragraph style.  
  368.   Presently, only alignment and fonts are supported.
  369.  
  370.   Members:
  371.       fonttag           - returns font definition
  372.       setalign          - defines alignment variables
  373.       define         - define Tag
  374.       discretionaries    - defines discret. variables
  375.  
  376.   --------------------------------------------------------------------*/
  377.  
  378. ParaTag::ParaTag(const char* id) : SimpleTag(id, "ParaTag", int(0))
  379.    {
  380.    _hypertext = false;
  381.  
  382.    _leading = 0;
  383.    _left = 0;
  384.    _after = 0;
  385.    _before = 0;
  386.    _font   =  new FontTag("deffont", 0);
  387.    setalign("Left");
  388.    discretionaries();
  389.    }
  390.  
  391. ParaTag::ParaTag(const char* line, FILE* fd, TextView *view)
  392.    {
  393.    _hypertext = false;
  394.    _class = strcpy(new char[strlen("ParaTag")+1], "ParaTag");
  395.  
  396.    _font   = nil;
  397.    _alignment = nil;
  398.    _interline_glue = nil;
  399.    _interpar_glue = nil;
  400.    _leading = 0;
  401.    _left = 0;
  402.    _after = 0;
  403.    _before = 0;
  404.  
  405.    getid(line);
  406.    define(fd, view);
  407.  
  408.    if (_font == nil)
  409.       _font   =  new FontTag("deffont", 0);
  410.  
  411.   /*
  412.    *  *** default is justified
  413.    */
  414.    if (_alignment == nil)
  415.       setalign("left");
  416.    else
  417.       setalign(_alignment);
  418.  
  419.    discretionaries();
  420.    }
  421.  
  422. ParaTag::~ParaTag()
  423.    {
  424.    if (_alignment != nil)
  425.       delete _alignment;
  426.  
  427.    _begin_line_strut->unref();
  428.    _end_line_strut->unref();
  429.    _begin_par_strut->unref();
  430.    _end_par_strut->unref();
  431.    _line_strut->unref();
  432.    _fil_strut->unref();
  433.    _hyphen->unref();
  434.    _interline_glue->unref();
  435.    _interpar_glue->unref();
  436.    _hfil_glue->unref();
  437.    _hfill_glue->unref();
  438.    _vfil_glue->unref();
  439.    _word_space->unref();
  440.  
  441.    delete _font;
  442.    }
  443.  
  444. void ParaTag::discretionaries()
  445.    {
  446.    Color* fg = (Color*)Session::instance()->style()->foreground();
  447.  
  448.    _line_strut = new Strut(_font->font());
  449.    _line_strut->ref();
  450.    _fil_strut = new Strut(_font->font(), 0, fil, 0);
  451.    _fil_strut->ref();
  452.    _hyphen = new Character('-', _font->font(), fg);
  453.    _hyphen->ref();
  454.  
  455.    if (_interline_glue == nil)
  456.       {
  457.       _interline_glue = new VGlue(0, 10, 0);
  458.       _interline_glue->ref();
  459.       }
  460.  
  461.    if (_interpar_glue == nil)
  462.       {
  463.       _interpar_glue = new VGlue(10, 10.0, 0);
  464.       _interpar_glue->ref();
  465.       }
  466.  
  467.    _hfil_glue = new HGlue(0, fil, 0);
  468.    _hfil_glue->ref();
  469.    _hfill_glue = new HGlue(0, 1000000*fil, 0);
  470.    _hfill_glue->ref();
  471.    _vfil_glue = new VGlue(0, fil, 0);
  472.    _vfil_glue->ref();
  473.    _word_space = new Space(2, 0.5, _font->font(), fg);
  474.    _word_space->ref();
  475.    }
  476.  
  477. void ParaTag::define(FILE* fd, TextView* view)
  478.    {
  479.    char   line[100];
  480.    char   key[40];
  481.    char   fontname[80];
  482.    char   style[40];
  483.    char*  gt;
  484.    int    i;
  485.  
  486.    getline(fd, line);
  487.  
  488.    while(line[0] != '>')
  489.       {
  490.       if (strncasecmp(line, "Alignment", 9) == 0)
  491.          {
  492.          i = strlen("Alignment");
  493.          while ((line[i] == ' ') || (line[i] == '\t'))
  494.             i++;
  495.      
  496.          if ((gt = strchr(line, '>')) != 0)
  497.             gt[0] = '\0';
  498.  
  499.          _alignment = strcpy(new char[strlen(line+i)+1], line+i);
  500.          }
  501.       else if (strncasecmp(line, "Hypertext", 9) == 0)
  502.          {
  503.          _hypertext = true;
  504.          }
  505.       else if (strncasecmp(line, "Leading", 7) == 0)
  506.          {
  507.          i = strlen("Leading");
  508.          while ((line[i] == ' ') || (line[i] == '\t'))
  509.             i++;
  510.          sscanf(line+i, "%f", &_leading);
  511.          _interline_glue = new VGlue(_leading, 10, 0);
  512.          _interline_glue->ref();
  513.          }
  514.       else if (strncasecmp(line, "FirstIndent", 11) == 0)
  515.          {
  516.          i = strlen("FirstIndent");
  517.          while ((line[i] == ' ') || (line[i] == '\t'))
  518.             i++;
  519.          sscanf(line+i, "%f", &_first);
  520.          }
  521.       else if (strncasecmp(line, "LeftIndent", 10) == 0)
  522.          {
  523.          i = strlen("LeftIndent");
  524.          while ((line[i] == ' ') || (line[i] == '\t'))
  525.             i++;
  526.          sscanf(line+i, "%f", &_left);
  527.          }
  528.       else if (strncasecmp(line, "RightIndent", 11) == 0)
  529.          {
  530.          float    right;
  531.  
  532.          i = strlen("RightIndent");
  533.          while ((line[i] == ' ') || (line[i] == '\t'))
  534.             i++;
  535.          sscanf(line+i, "%f", &right);
  536.          }
  537.       else if (strncasecmp(line, "SpaceAfter", 10) == 0)
  538.          {
  539.          i = strlen("SpaceAfter");
  540.          while ((line[i] == ' ') || (line[i] == '\t'))
  541.             i++;
  542.          sscanf(line+i, "%f", &_after);
  543.          }
  544.       else if (strncasecmp(line, "SpaceBefore", 11) == 0)
  545.          {
  546.          i = strlen("SpaceBefore");
  547.          while ((line[i] == ' ') || (line[i] == '\t'))
  548.             i++;
  549.          sscanf(line+i, "%f", &_before);
  550.          _interpar_glue = new VGlue(_before, 10.0, 0);
  551.          _interpar_glue->ref();
  552.          }
  553.       else
  554.          {
  555.          for (i = 0; i < view->_numfont; i++)
  556.             {
  557.             if (strcasecmp(view->fontlist[i]->Id(), line) == 0) 
  558.                {
  559.                _font = view->fontlist[i];
  560.                break;
  561.                }
  562.             }
  563.          }
  564.  
  565.       getline(fd, line);
  566.       }
  567.    }
  568.  
  569. void ParaTag::setalign(char* align)
  570.    {
  571.    if (strncasecmp(align, "leftright", 9) == 0)
  572.       {
  573.    Color* fg = (Color*)Session::instance()->style()->foreground();
  574.  
  575.       _begin_line_strut = new VStrut(0);
  576.       // _begin_line_strut = new Space(10, 0.5, _font->font(), fg);
  577.       _begin_par_strut = new VStrut(0);
  578.       _end_line_strut = new Strut(_font->font());
  579.       _end_par_strut = new Strut(_font->font(), 0, fil, 0);
  580.       }
  581.    else if (strncasecmp(align, "right", 5) == 0)
  582.       {
  583.       _begin_line_strut = new VStrut(0, 0, 0, fil, 0);
  584.       _begin_par_strut = new VStrut(_before, 0, 0, fil, 0);
  585.       _end_line_strut = new Strut(_font->font());
  586.       _end_par_strut = new Strut(_font->font());
  587.       }
  588.    else if (strncasecmp(align, "center", 6) == 0)
  589.       {
  590.       _begin_line_strut = new VStrut(0, 0, 0, fil, 0);
  591.       _begin_par_strut = new VStrut(0, 0, 0, fil, 0);
  592.       _end_line_strut = new Strut(_font->font(), 0, fil, 0);
  593.       _end_par_strut = new Strut(_font->font(), 0, fil, 0);
  594.       }
  595.    //
  596.    //  *** default is left justified
  597.    //
  598.    else 
  599.       {
  600.       _begin_line_strut = new VStrut(0);
  601.       _begin_par_strut = new VStrut(0);
  602.       _end_line_strut = new Strut(_font->font(), 0, fil, 0);
  603.       _end_par_strut = new Strut(_font->font(), 0, fil, 0);
  604.       }
  605.  
  606.    _begin_line_strut->ref();
  607.    _end_line_strut->ref();
  608.    _begin_par_strut->ref();
  609.    _end_par_strut->ref();
  610.    }
  611.  
  612. FontTag* ParaTag::fonttag()
  613.    {
  614.    return(_font);
  615.    }
  616.