\begindata{text,539028584} \textdsversion{12} \template{default} \define{global

\begindata{text,539028584}
\textdsversion{12}
\template{default}
\define{global
}
\define{itemize
}
\chapter{\formatnote{Example 15 -- Creating Styles in Documents} }
\indexi{Styles++Document} \indexi{Style} \indexi{Class++Style}
\indexi{Stylesheet} \indexi{Class++Stylesheet}\indexi{Tree23}
\indexi{Class++Tree23} \indexi{Environment}\indexi{Class++Environment}
Example 15 illustrates the use of styles in text documents. Styles can
be
fonts, predefined title or region formats, justifications, and so on. In
this
example, we will modify the text class in Example 14 to print "Hello
world!"
with bold-face and italic type, similar to the display in Example 13.
The
Andrew Toolkit provides several classes for dealing with styles in text
documents: \italic{stylesheet}, \italic{style}, \italic{tree23}, and
\italic{environment}. Of these, we need only to use the class
\italic{style}
explicitly for this program.
An Andrew Toolkit text object has an associated tree of
\italic{environments},
each of which has a position in the text object, a length, and a
\italic{style}
(a different "style" from the font descriptor styles Example 13, but with
a
similar use). They must be nested, i.e., an environment must be wholly
contained within its parent. Any text within the region encompassed by
an
environment is modified by that environment's style, the environment's
parent's style, and so on. Styles affect such things as font size, font
style
(the font descriptor style), text layout (justification, indenting), and
so
on.
The effects of multiple styles on the same piece
\indexi{Styles++Multiple}
of text is cumulative: text contained in an environment with a style
that
turns on bold, whose parent's style turns on italic would be displayed as
bold-italic. It is important to note, however, that an environment takes
precedence over its ancestors. Styles can also be used turn off various
attributes, for example, a "plainer" style will strip off a style.
The discussion that follows presents a step-by-step description of how to
modify the text class in Example 14 to produce Example 15. If you were
to
follow the steps, you would produce a program, called
\italic{helloworldapp},
in three files:
\itemize{
a helloa.ch file -- will contain the class definition for the application
program that will display an instance of the class in a window. This
will be
exactly the same as in Example 14.
a helloa.c -- will contain declarations needed by the Andrew Toolkit
linking
and loading facilities as well the definition of the
\italic{helloworldview}
application method. We will add to the Start method the statementes
necessary
for creating styled text.
Makefile -- will contain the directions for compiling, linking and
loading.
This will be exactly the same as Example 14.
}
For a complete listing of these files, see \italic{Program Listing for
Example
15} at the end of this section on p.
\begindata{textref,539236104}
\textdsversion{12}
# ExFifteenListing\
\enddata{textref,539236104}
\view{textrefv,539236104,964,0,0}. The source code is available in the
directory /usr/andrew/examples/ex15, together with the compiled program.
Although the discussion of the steps refers directly to this example, the
information generally applies to the creation of any text document with
styles.
\begindata{bp,538928968}
\enddata{bp,538928968}
\view{bpv,538928968,965,0,0}
\section{Running the example program}
\formatnote{\bold{Action 1.} \formatnote{To run the program, at the
\bold{command }prompt type
runapp /usr/andrew/examples/ex15/helloa
and press the Enter key.
}
\bold{Response.}\formatnote{
with\bold{ Hello}
}The program will produce two windows each
\italic{world! }in the upper-left corner of the window, a vertical scroll
bar, a message line, and the default text menus.
\bold{Action 2.} \formatnote{
\bold{Hello}
with the mouse
}Position the cursor in front of
and type in some characters.
\bold{Response. } \formatnote{
\bold{Action 3.}\formatnote{
after \bold{Hello}
}The characters will be inserted.
}Position the cursor within or immediately
and type some characters.
\bold{Response. }\formatnote{
face.
Environments
}The characters will be inserted in bold-
on styles are defined so that the cursor lies within the style at the
end, and outside the style at the beginning of a styled region.
Thus,
any character typed after a styled region is displayed in that style;
any typed in front of the region is not.
\bold{Action 4.}\formatnote{
of
\italic{world} and
}Position the cursor immediately in front
type some characters.
\bold{Response.} \formatnote{
regular
type.
\bold{Action 5.}\formatnote{
after \italic{world}
}The characters will be inserted in
}Position the cursor within or immediately
and type some characters.
\bold{Response.} \formatnote{
italic
font.
\bold{Action 6.}\formatnote{
the !
and type
}The characters will be inserted in
} Position the cursor immediately after
some characters.
\bold{Response.} \formatnote{
regular
type.
\bold{Action 7.}\formatnote{
choose \bold{Quit}
}The characters will be inserted in
}To quit the program, pop-up the menus and
from the top card.
\bold{Response.} \formatnote{
screen.
}\
\begindata{bp,538928712}
\enddata{bp,538928712}
\view{bpv,538928712,966,0,0}
\section{Overview of Styles}
}The windows will disappear from the
Here are some basic definitions of the major components of the complete
style
package: \indexi{Style++Package}
\leftindent{\bold{Templatelist} \indexi{Template list} - the group of
most
recently used templates for a given editor session. This avoids have to
read
the same templates in repeatedly when switching between text documents.
\bold{Template} \indexi{Template} - a stylesheet
\indexi{Style sheet} which is saved in a file separate from the rest of
the
document. Creation of a template allows its styles and global attributes
to
be easily included in multiple documents.
\bold{Stylesheet} - the group of styles and global attributes which are
applicable to the current document.
\bold{Style} \indexi{Style}
the group of devices which are applicable to the current style.
style is
most often the object that should be
The
referenced. Style names (e.g. bold, subheading, etc.) are used in the
external representation to indicate where a styled region begins.
}
\subsection{External data representation of styles}
\indexi{Styles++External representation}
The external data representation is entirely in ascii, and is expected to
be
used both for storing objects in files and for cut and paste operations.
A
stylesheet can contain zero or more styles, each of which can contain
multiple
font/style definitions.
Text documents which contain no style information or other objects are
treated
as uninterpreted files and stored in a straightforward manner. Text
documents
which do contain these extra dimensions are written with a special
syntax.
The general syntax of these interpreted files follows the protocols
defined
in the documentation for stylesheet.
Here is one example of creating a style:
\example{
struct stylesheet *ssptr;
\indexi{Style++Creating}
struct style *styleptr;
if ((styleptr = stylesheet_Find(ssptr, "bold")) == NULL) \{
styleptr = style_New();
style_SetName(styleptr, "bold");
style_SetMenuName(styleptr, "Font~1,Bold~10");
stylesheet_Add(ssptr, styleptr);
\}
style_AddNewFontFace(bold, fontdesc_Bold);
}
Notes:
\itemize{
It is not necessary to add the style to a stylesheet, programs may create
and
use styles independently of the stylesheet.
It is not necessary to set the menu name for a style. If no menu name is
given, the style will not be added to the menu. (It is also not
necessary to
give prioritization in the menu string).
}
\subsection{Global vs. default styles}
\indexi{Styles++Global}
\indexi{Styles++Default}
There are two ways of modifying the style that defines how normal
(unstyled)
text looks for a particular application. One way is through the global
style,
and the other is through the default style.
The global style is associated with the text object. This style is
attached
to the root environment of the 23tree. Usually, this style would be
under
control of the application program and it defines the basic attributes
for all
text (that is, it is global to the document). The global style is the
place
to set up application specific attributes such as using a fixed with font
and
left justification (no fill) in ctext.
The default style is associated with the textview. This style is
attached to
the textview object. Usually, this style is defined by the user through
the
preferences file. The default style is the place to set up user specific
attributes such as bodyfont (fontfamily and fontsize) in typescript.
In this example, we will be modifying the default styles for the text
inset
from the previous example.
\section{Modifying the class definition}
First, we will import procedures from style as well as fontdesc.
\indexi{Importing}
\indexi{Fontdesc} \indexi{Font descriptor}
\formatnote{
#include <class.h>
#include "helloa.eh"
#include "im.ih"
#include "frame.ih"
#include "text.ih"
#include "dataobj.ih"
#include "view.ih"
\bold{#include "fontdesc.ih"
#include "style.ih"}
}
Then, we will modify the Start
\indexi{ \italic{Start}}
method to create italic and bold environments, and have the program print
the
text string in different environments on start-up.
\formatnote{
boolean helloworldapp__Start(hwapp)
struct helloworldapp *hwapp;
\{
struct text *t;
struct style *bold,*italic;
if(!super_Start(hwapp))
return FALSE;
t=text_New();
if(t==NULL)
return FALSE;
bold=style_New();
if(bold==NULL) \{
text_Destroy(t);
return FALSE;
\}
style_AddNewFontFace(bold,fontdesc_Bold);
italic=style_New();
if(italic==NULL) \{
style_Destroy(bold);
return FALSE;
\}
style_AddNewFontFace(italic,fontdesc_Italic);
text_InsertCharacters
(t,0,"Hello world!",
sizeof("Hello world!")-1);
text_AddStyle(t,0,5,bold);
text_AddStyle(t,6,5,italic);
if(!makeWindow((struct dataobject *)t) ||
!makeWindow((struct dataobject *)t)) \{
style_Destroy(italic);
return FALSE;
\}
return TRUE;
\}
}
For this example, we create two styles, one for each different type of
modification we want to make to the text. The method
\italic{style_AddNewFontFace} \indexi{ \italic{style_AddNewFontFace}}
asserts
that text affected by an environment containing this style should have
the
given font descriptor style bits added to the set already turned on.
After inserting the "hello world" string with text_InsertCharacters
\indexi{ \italic{text_InsertCharacters}}
as in the previous example, we use the \italic{text_AddStyle}
\indexi{ \italic{text_AddStyle}}
method, to create an environment \indexi{Environment} with the given
position, length, and style objects. If the position and length given
would
cause the environment to cross the boundary of an existing environment,
the
environments are split up into smaller environments, so that the
hierarchical
nature of the environment tree is preserved.
\begindata{bp,538929032}
\enddata{bp,538929032}
\view{bpv,538929032,967,0,0}
\begindata{texttag,539315976}
\textdsversion{12}
ExFifteenListing\
\enddata{texttag,539315976}
\view{texttagv,539315976,968,0,0}
\section{Program listing for Example 15}
\formatnote{
\bold{helloa.ch}
class helloworldapp[helloa] : application[app]\{
overrides:
Start() returns boolean;
\};
\bold{helloa.c}
#include <class.h>
#include "helloa.eh"
#include "im.ih"
#include "frame.ih"
#include "text.ih"
#include "dataobj.ih"
#include "view.ih"
#include "fontdesc.ih"
#include "style.ih"
static boolean makeWindow(dobj)
struct dataobject *dobj;
\{
struct view *v;
struct view *applayer;
struct frame *frame;
struct im *im;
v=(struct view *)class_NewObject
(dataobject_ViewName(dobj));
if(v==NULL)
return FALSE;
applayer=view_GetApplicationLayer(v);
if(applayer==NULL) \{
view_Destroy(v);
return FALSE;
\}
frame=frame_New();
if(frame==NULL) \{
view_DeleteApplicationLayer(v,applayer);
return FALSE;
\}
im=im_Create(NULL);
if(im==NULL) \{
frame_Destroy(frame);
return FALSE;
\}
view_SetDataObject(v,dobj);
frame_SetView(frame,applayer);
im_SetView(im,frame);
view_WantInputFocus(v,v);
return TRUE;
\}
boolean helloworldapp__Start(hwapp)
struct helloworldapp *hwapp;
\{
struct text *t;
struct style *bold,*italic;
if(!super_Start(hwapp))
return FALSE;
t=text_New();
if(t==NULL)
return FALSE;
bold=style_New();
if(bold==NULL) \{
text_Destroy(t);
return FALSE;
\}
style_AddNewFontFace(bold,fontdesc_Bold);
italic=style_New();
if(italic==NULL) \{
style_Destroy(bold);
return FALSE;
\}
style_AddNewFontFace(italic,fontdesc_Italic);
text_InsertCharacters
(t,0,"Hello world!",sizeof
("Hello world!")-1);
text_AddStyle(t,0,5,bold);
text_AddStyle(t,6,5,italic);
if(!makeWindow((struct dataobject *)t) ||
!makeWindow((struct dataobject *)t)) \{
style_Destroy(italic);
return FALSE;
\}
return TRUE;
\}
\bold{Makefile}
SRCDIR=/usr/andrew/
INCLUDES= -I. -I$\{SRCDIR\}include/atk -I$\{SRCDIR\}include
INCLUDESRC = $\{SRCDIR\}include/atk
CC=cc
DEBUG = -g
TOOLS = $\{SRCDIR\}bin/
CFLAGS= $\{DEBUG\} $\{INCLUDES\}
CLASSFLAGS=$\{INCLUDES\}
MAKEDO = $\{TOOLS\}makedo $\{DEBUG\} -b $\{TOOLS\}
-d $\{SRCDIR\}lib
CLASS = $\{TOOLS\}class
.SUFFIXES: .ih .eh .ch .do
.ch.ih:
$\{CLASS\} $\{CLASSFLAGS\} $*.ch
.ch.eh:
$\{CLASS\} $\{CLASSFLAGS\} $*.ch
.o.do:
$\{MAKEDO\} $<
all:
helloa.do
helloa.do: helloa.o helloa.eh
helloa.o: helloa.c
helloa.o: $\{INCLUDESRC\}/app.ih
helloa.o: $\{INCLUDESRC\}/atom.ih
helloa.o: $\{INCLUDESRC\}/dataobj.ih
helloa.o: $\{INCLUDESRC\}/frame.ih
helloa.o: $\{INCLUDESRC\}/graphic.ih
helloa.o: $\{INCLUDESRC\}/im.ih
helloa.o: $\{INCLUDESRC\}/lpair.ih
helloa.o: $\{INCLUDESRC\}/mark.ih
helloa.o: $\{INCLUDESRC\}/message.ih
helloa.o: $\{INCLUDESRC\}/namespc.ih
helloa.o: $\{INCLUDESRC\}/observe.ih
helloa.o: $\{INCLUDESRC\}/point.h
helloa.o: $\{INCLUDESRC\}/rect.h
helloa.o: $\{INCLUDESRC\}/smpltext.ih
helloa.o: $\{INCLUDESRC\}/text.ih
helloa.o: $\{INCLUDESRC\}/view.ih
helloa.o: $\{SRCDIR\}include/class.h
helloa.o: helloa.eh
helloa.eh helloa.ih: helloa.ch
helloa.eh helloa.ih:
$\{INCLUDESRC\}/app.ih
}
\begindata{bp,537558784}
\enddata{bp,537558784}
\view{bpv,537558784,970,0,0}
Copyright 1992 Carnegie Mellon University and IBM.
All rights reserved.
\smaller{\smaller{$Disclaimer:
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
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 IBM not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission.
#
# THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ANY COPYRIGHT
# HOLDER 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.
#
# $
}}\enddata{text,539028584}