A rendition (data type XmRendition) is an opaque data type used to specify data used in rendering compound strings.
A rendition has two parts: the set of data used to render a compound string (such as fonts, colors, and tabs), and a name, or "tag" (data type XmStringTag), by which to identify it.
A rendition is neither a widget nor a gadget. However, the style used to specify resources for widgets and gadgets is a simple and familiar way to set data values, and it has been implemented for renditions well. To change the foreground color for a rendition, the application programmer must set a "resource" called XmNrenditionForeground for that rendition, in a manner identical to that of a programmer changing a color resource for some widget. For a complete description of the XmRendition resource set, see the XmRendition page in the Motif Programmer's Reference.
XmRenditionCreate takes an argument list (use XtSetArg to create the list) of resource name and value pairs as input, and returns a rendition, which can then be entered into the render table.
The following code fragment establishes a rendition that would display a compound string in the 8x16 font, in blue, and underlined with a single line.
int n; XmRendition Rendition; XmStringTag RenditionTag; XtVaGetValues(parent, XmNcolormap, &cmap, NULL); if ( XAllocNamedColor(XtDisplay(parent), cmap, "blue", &color, &unused)) { pixel_color = color.pixel; } else { pixel_color = XmUNSPECIFIED_PIXEL; } n = 0; XtSetArg( args[n], XmNrenditionForeground, pixel_color); n++; XtSetArg( args[n], XmNfontName, "8x16" ); n++; XtSetArg( args[n], XmNfontType, XmFONT_IS_FONT ); n++; XtSetArg( args[n], XmNunderlineType, XmSINGLE_LINE ); n++; RenditionTag = (XmStringTag) "Rendition1"; Rendition = XmRenditionCreate( parent, RenditionTag, args, n );
These functions are used to read and modify a rendition.
The XmRenditionUpdate function works in a similar way to XmRenditionCreate, merging the given argument list into the definition of the rendition. Resources in the input ArgList that were XmAS_IS will be set to the given values, and resources in the input ArgList that were already set will be reset to the new value. Resources not in the input ArgList will remain unchanged. The XmRenditionRetrieve function also uses an ArgList, but the user must specify the address (instead of the value) of each resource value to be returned.
The following code retrieves a rendition. If the rendition was underlined, the underline is removed. If the rendition was not underlined, the underline is inserted.
int n; unsigned char underline; n = 0; XtSetArg( args[n], XmNunderlineType, &underline ); n++; XmRenditionRetrieve( Rendition, args, n ); if (( underline == XmAS_IS) || ( underline == XmNO_LINE )) underline = XmSINGLE_LINE; else if ( underline == XmSINGLE_LINE) underline = XmNO_LINE; n = 0; XtSetArg( args[n], XmNunderlineType, underline ); n++; XmRenditionUpdate( Rendition, args, n );
The modified rendition must still be added to the render table, and the modified render table sent back to the widget, before it is accessible to a widget needing to display a compound string.
The XmRenditionCreate function allocates memory for the created rendition structure. The application calling this function is responsible for maintaining its own memory management scheme. Use XmRenditionFree to recover memory space allocated to a rendition when the application is done with it. The application may dispose of the rendition as soon as it has been added to a render table.
A collection of renditions, each identified by a rendition "tag" (type XmStringTag), constitutes a render table (type XmRenderTable). Each rendition contains specifications describing how to display text, including the font, the color, the tab stops, and other information.
A compound string can specify its rendition in more than one way. The typical way is simply for each compound string text component to be associated with a rendition tag, which is matched with the entry in the render table with the same tag. However, an application may use the default rendition for the current locale (tag=_MOTIF_DEFAULT_LOCALE). Alternatively, older applications may specify a charset tag, which will identify a font to use to display some text. The charset and the locale options may not both be specified, but both may exist with one or more rendition tags.
Renditions are accumulated as a compound string is read. If there have been three rendition begin tags and only one corresponding rendition end tag preceding a particular segment of text, then there are two renditions associated with that text. The last rendition specified that is still in effect is the primary rendition. If a segment of text is associated with more than one rendition, and if there are unspecified values in the primary rendition, the widget must create an effective rendition for that segment. This is formed by using the previous (active) rendition to fill in the unspecified values of the primary rendition. If this effective rendition still has unspecified values, then the next active rendition back is used, and so on. Finally, if the resulting rendition still has resources with unspecified values and the segment has a locale or charset tag (these are optional and mutually exclusive) this tag is matched with a rendition in the render table, and the missing rendition values are filled in from that entry.
If no matching rendition is found for a particular tag, then the XmNoRenditionCallback of the XmDisplay object is called and the render table is searched again for that tag.
If the resulting rendition does not specify a font or fontset, then for segments whose text type is XmCHARSET_TEXT, the render table will be searched for a rendition tagged with XmFONTLIST_DEFAULT_TAG, and if a matching rendition is found, it will be merged into the current rendition. If the resulting rendition contains no font or fontset, the XmNnoFontCallback will be called with the default rendition and "" as the font name. If no rendition matches or no font was found after the callback, then the first rendition in the render table will be merged into the current rendition. If this rendition still has no font, then the segment will not be rendered and a warning will be issued.
For segments whose text type is XmMULTIBYTE_TEXT or XmWIDECHAR_TEXT, the render table will be searched for a rendition tagged with _MOTIF_DEFAULT_LOCALE, and if a matching rendition is found, it will be merged into the current rendition. If the resulting rendition contains no font, the XmNnoFontCallback will be called with the default rendition and "" as the font name. If no rendition matches or no font was found after the callback, then the segment will not be rendered and a warning will be issued.
For example, imagine a render table containing three renditions. One belongs to the default locale, and has the tag _MOTIF_DEFAULT_LOCALE, while the other two renditions are called fred and susan. Further suppose the default locale rendition specifies a font, but the foreground and background color resources are XmUNSPECIFIED_PIXEL. Rendition fred specifies the foreground color as red, but the background field is XmUNSPECIFIED_PIXEL, and rendition susan gives blue for the foreground and purple for the background. Following is a schematic representation of such a render table:
_MOTIF_DEFAULT_LOCALE: XmNfontName: variable XmNfontType: XmFONT_IS_FONT XmNrenditionForeground: XmUNSPECIFIED_PIXEL XmNrenditionBackground: XmUNSPECIFIED_PIXEL ... fred: XmNfontName: XmAS_IS XmNfontType: XmAS_IS XmNrenditionForeground: red XmNrenditionBackground: XmUNSPECIFIED_PIXEL ... susan: XmNfontName: XmAS_IS XmNfontType: XmAS_IS XmNrenditionForeground: blue XmNrenditionBackground: purple ...
A text component associated with the fred and susan tags (in that order) will have red type on a purple background. But a component using susan and fred will have blue type on a purple background. Both components will use the font corresponding to the locale rendition, variable in this case. Note that the order of the renditions in the merge sequence is the opposite of the order in which the corresponding XmSTRING_COMPONENT_RENDITION_BEGIN components appear in the compound string. That is, the primary rendition for some piece of text corresponds to the last rendition component read.
If the search of the render table results in no font or fontset, then if there is a rendition in the render table with a tag of _MOTIF_DEFAULT_LOCALE, and if that rendition specifies a font, then that font will be used. If no font or fontset is specified at this point, the text component will not be rendered and a warning message will be displayed.
Before creating a render table, an application program must first have created at least one of the renditions that will be part of the table.
As the name implies, this function is also used to augment a render table with new renditions. To create a new render table, call the XmRenderTableAddRenditions function with a NULL argument in place of an existing render table. The following code creates a render table from three renditions.
n = 0; XtSetArg( args[n], XmNtopAttachment, XmATTACH_FORM ); n++; XtSetArg( args[n], XmNwidth, LIST_WIDTH ); n++; XtSetArg( args[n], XmNvisibleItemCount, NUM_ITEMS ); n++; List = XmCreateList( Manager, "List", args, n ); XtManageChild(List); n = 0; XtSetArg( args[n], XmNfontName, "fixed" ); n++; XtSetArg( args[n], XmNfontType, XmFONT_IS_FONT ); n++; XtSetArg( args[n], XmNunderlineType, XmNO_LINE ); n++; Renditions[0] = XmRenditionCreate( List, (XmStringTag)tags[0], args, n ); n = 0; XtSetArg( args[n], XmNfontName, XmAS_IS ); n++; XtSetArg( args[n], XmNfontType, XmFONT_IS_FONT ); n++; XtSetArg( args[n], XmNunderlineType, XmSINGLE_LINE ); n++; Renditions[1] = XmRenditionCreate( List, (XmStringTag)tags[1], args, n ); n = 0; XtSetArg( args[n], XmNfontName, "variable" ); n++; XtSetArg( args[n], XmNfontType, XmFONT_IS_FONT ); n++; XtSetArg( args[n], XmNunderlineType, XmDOUBLE_LINE ); n++; Renditions[2] = XmRenditionCreate( List, (XmStringTag)tags[2], args, n ); RenderTable = XmRenderTableAddRenditions( NULL, Renditions, 3, XmREPLACE ); n = 0; XtSetArg( args[n], XmNrenderTable, RenderTable ); n++; XtSetValues( List, args, n );
Note that the list widget must specify the resulting render table in its XmNrenderTable resource in order for that widget to have access to the render table's rendition data.
To create a new compound string with a new rendition out of an old compound string, use the XmStringPutRendition function. Given an XmString and the tag of a rendition from a render table, this function places XmSTRING_COMPONENT_RENDITION_BEGIN and XmSTRING_COMPONENT_RENDITION_END components containing the input rendition tag around a copy of the old string. This function does not strip old rendition data out of the string, so the resulting string will merge the existing rendition with the new one when it is rendered. See the example in section 9.1.2.
The XmRenderTableAddRenditions may also be used to update an existing render table by adding, replacing, or merging new renditions into the table. The following functions also provide important editing functionality.
These functions are used to read and modify render tables. Use the XmRenderTableGetRenditions function to call up one or more renditions for a table. A program might do this in order to modify some of the renditions in the table. The XmRenderTableRemoveRenditions function will delete any unneeded renditions from a given table. A related function is XmRenderTableCopy, which will copy only renditions matching the input list of rendition tags into a new render table. Use XmRenderTableGetTags to retrieve a list of tags from a render table.
The following code uses the render table created in the last section, and modifies the variable rendition to include a single line "strike through." (This produces a horizontal line through the drawn text, as if the text had been crossed out.)
int n; XmRendition Rendition; Rendition = XmRenderTableGetRenditions(RenderTable, (XmStringTag) "variable", 1); n = 0; XtSetArg( args[n], XmNstrikethruType, XmSINGLE_LINE ); n++; XmRenditionUpdate( Rendition, args, n ); XmRenderTableAddRenditions(RenderTable, Rendition, 1, XmMERGE_NEW); n = 0; XtSetArg( args[n], XmNrenderTable, RenderTable ); n++; XtSetValues( List, args, n );
Note that the modified render table must be sent again to the widgets in which it will be used before becoming effective.
Although the XmRenderTableAddRenditions and XmRenderTableCopy functions allocate memory for a render table, the application program is responsible for its own memory management. Use the XmRenderTableFree function to free memory when a render table is no longer needed. Note, however, that the XmRenderTableAddRenditions function automatically frees the memory occupied by its input render table.
Renditions and render tables may be specified in resource files. For a properly internationalized application, in fact, this is the preferred method. When the render tables are specified in a file, the program binaries are made independent of the particular needs of a given locale, and may be easily customized to local needs. Render tables are specified in resource files with the following syntax:
resource_spec: [ tag [, tag ]* ]
where tag is some string suitable for the XmNtag resource of a rendition. This line creates an initial render table containing one more renditions than the number of tags specified. The renditions are attached to the specified tags, with the untagged rendition going with the tag _MOTIF_DEFAULT_LOCALE. If no tags are specified, then a render table will be created that contains only a rendition with a tag of _MOTIF_DEFAULT_LOCALE.
Specific values for specific rendition resources are specified using the following syntax:
resource_spec [*|.] rendition[*|.] resource_name: value
where resource_spec specifies the render table, rendition is either the class Rendition or a tag, resource_name is either the call or name of a particular resource, and value is the specification of the value to be set.
Any resource line that consists of just a resource name or class component with no rendition component or loose binding will be assumed to specify resource values for a rendition with a tag of _MOTIF_DEFAULT_LOCALE.
For example, the following:
*List.renderTable: green, variable *List.renderTable.green.renditionForeground: Green *List.renderTable.green.fontName: AS_IS *List.renderTable.variable.underlineType: SINGLE_LINE *List.renderTable.variable.renditionForeground: Red *List.renderTable.variable.fontName: variable *List.renderTable.variable.fontType: FONT_IS_FONT *List.renderTable.renditionForegound: black *List.renderTable.fontName: fixed *List.renderTable.fontType: FONT_IS_FONT *List.renderTable.variable.underlineType: NO_LINE *List.renderTable*tabList: 1in, +1.5in, +3in
would set the renderTable resource of List to a render table consisting of three renditions tagged with _MOTIF_DEFAULT_LOCALE, green, and variable with values for resources set as described in the resource specifications. Note that the tabList resource will be shared by all three renditions.
Several widget resource sets have been modified in Motif version 2.0 to accommodate the use of renditions and render tables. Several widgets have added the XmNrenderTable resource to their set. Several others have had more complex changes. The following list outlines the new resources for the affected widget classes. For complete information about the resource set of any widget, please refer to the appropriate section of the Motif Programmer's Reference.
Upon execution of the callback routine nominated by either of these resources, a pointer to the following structure is passed to the XmNnoFontCallback and XmNnoRenditionCallback callbacks:
typedef struct { int reason; XEvent * event; XmRendition rendition; char * font_name; XmRenderTable render_table; XmStringTag tag; }XmDisplayCallbackStruct;
The render table is an opaque data type. If a programmer wishes to save a render table for some future use, or to pass the table to some other program, the application using the render table must first translate the render table into a portable format. Motif provides two functions to convert render tables to and from such a format:
The XmRenderTableCvtToProp function takes a render table and outputs a character string containing the resource meanings and values for each of the render table's renditions. Use XmRenderTableCvtFromProp to convert such a character string table back into a Motif render table.
The font list paradigm of Motif 1 has been supplanted by renditions and render tables. The font list management routines are provided only for backward compatibility with older applications written. They should not be used for new applications, which can use renditions and render tables for the same effect. Following is a list of the remaining font list management functions: