\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}