|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: S T
Length: 26542 (0x67ae)
Types: TextFile
Names: »StaticText.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/Toolkit/Xr/src/Xrlib/Editor/StaticText.c«
/*
* $Source: /u1/Xr/src/Xrlib/Editor/RCS/StaticText.c,v $
* $Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $
*/
#ifndef lint
static char *rcsid_StaticText_c = "$Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $";
#endif lint
#include <Xr/xr-copyright.h>
/* $Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $ */
/* Copyright 1986, Hewlett-Packard Company */
/* Copyright 1986, Massachussetts Institute of Technology */
static char rcsid[] = "$Header: StaticText.c,v 1.1 86/12/17 09:05:33 swick Exp $";
/*************************************<+>*************************************
*****************************************************************************
**
** File: StaticText.c
**
** Project: X-ray Toolbox
**
** Description:
** This file contains the static text field editor source code.
**
**
** ------------------------ MODIFICATION RECORD ------------------------
*
* $Log: StaticText.c,v $
* Revision 1.1 86/12/17 09:05:33 swick
* Initial revision
*
* Revision 7.0 86/11/13 08:28:09 08:28:09 fred ()
* Final QA Release
*
* Revision 6.0 86/11/10 15:36:42 15:36:42 fred ()
* QA #2 release
*
* Revision 5.2 86/11/07 14:23:50 14:23:50 fred ()
* Added new copyright message.
*
* Revision 5.1 86/11/03 14:48:50 14:48:50 fred ()
* MSG_SIZE and MSG_NEW now fail if the editor rectangle width is smaller
* than the longer word in the string.
*
* Revision 5.0 86/10/28 08:34:48 08:34:48 fred ()
* QA #1.1 release
*
* Revision 4.1 86/10/22 07:30:13 07:30:13 fred ()
* Added 'message' parameter to createSText().
*
* Revision 4.0 86/10/20 12:14:13 12:14:13 fred ()
* QA #1 release
*
* Revision 3.4 86/10/17 06:48:14 06:48:14 fred ()
* Fixed a bug where trailing spaces were not properly stripped
* during text alignment.
*
* Revision 3.3 86/10/16 11:08:56 11:08:56 fred ()
* Filled in the procedure headers.
*
* Revision 3.2 86/10/16 09:18:56 09:18:56 fred ()
* Performance enhanced: added use of register variables.
*
* Revision 3.1 86/10/09 07:55:28 07:55:28 fred ()
* Added default color check to create routine.
*
* Revision 3.0 86/10/02 16:02:06 16:02:06 fred ()
* Alpha release set to 3.0
*
* Revision 2.3 86/09/25 09:48:19 09:48:19 fred ()
* Modified MSG_SIZE, so that the leading is not included for the
* last line of text.
*
* Revision 2.2 86/09/22 13:12:58 13:12:58 fred ()
* Added calls to XrEditorGroup().
*
* Revision 2.1 86/09/19 12:17:59 12:17:59 fred ()
* Modified names of the info and data structures.
*
* Revision 2.0 86/09/16 08:11:27 08:11:27 fred ()
* Updated input processing routine to use new SELECT strategy.
*
* Revision 1.2 86/09/16 05:51:20 05:51:20 fred ()
* Modified to swallow a select up event.
*
* Revision 1.1 86/09/03 13:58:32 13:58:32 fred ()
* Initial revision
*
*
*****************************************************************************
*************************************<+>*************************************/
#include <X/Xlib.h>
#include <Xr/defs.h>
#include <Xr/types.h>
#include <Xr/in_types.h>
extern INT32 stFreeMemory();
extern INT32 createSText();
extern INT32 drawSText();
extern INT32 processSText();
\f
/*************************************<->*************************************
*
* xrEditor *
* XrStaticText (staticText, message, data)
*
* xrEditor * staticText;
* INT32 message;
* INT8 * data;
*
* Description:
* -----------
* This is the main entry point and message handler for the static
* text field editor. It takes all message requests, and passes
* them onto the appropriate handler; invalid messages will fail
* and return an error.
*
*
* Inputs:
* ------
* staticText = For all messages but MSG_NEW and MSG_SIZE, this
* contains the instance pointer.
*
* message = This indicates which action the editor should perform.
*
* data = This is the message specific data. It's usage depend upon
* the 'message' parameter, and may be a scalar or a pointer.
*
* Outputs:
* -------
* Upon successful completion of a command, the instance pointer
* is returned; additional information may be returned by
* means of the 'data' parameter.
*
* Upon failure, NULL is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* _MsgNew() [MsgCommon.c]
* _MsgFree() [MsgCommon.c]
* _MsgGetState() [MsgCommon.c]
* _MsgSetState() [MsgCommon.c]
* _MsgRedraw() [MsgCommon.c]
* _MsgEdit() [MsgCommon.c]
* _XrMakeInvisible() [editorUtil.c]
* XrCopyRect() [calc.c]
* drawSText()
* sizeSText()
*
*************************************<->***********************************/
xrEditor *
XrStaticText (staticText, message, data)
register xrEditor * staticText;
INT32 message;
INT8 * data;
{
/* Determine the action being requested */
switch (message)
{
case MSG_NEW:
{
/*
* Create a new instance of the static text editor.
* The only parameter of interest is the 'data'
* parameter, which is a pointer to a filled instance
* of the xrStaticTextInfo structure.
*/
return ((xrEditor *) _MsgNew (staticText, data,
sizeof(xrStaticTextData),
createSText, drawSText,
stFreeMemory, XrStaticText,
NULL));
}
case MSG_FREE:
{
/*
* Destroy the specified static text instance.
* The 'staticText' parameter specifies the instance to
* be destroyed; the 'data' parameter is unused.
*/
return ((xrEditor *) _MsgFree (staticText, stFreeMemory));
}
case MSG_GETSTATE:
{
/*
* Return the settings of the state flags for the
* specified static text instance. The 'staticText'
* parameter specifies the instance to be queried, while
* the 'data' parameter must point to an INT8 value, into
* which the state flags will be placed.
*/
return ((xrEditor *) _MsgGetState (staticText, data));
}
case MSG_SETSTATE:
{
/*
* Change the state flag settings for the specified
* instance. The 'staticText' parameter specifies the
* instance to bemdified, and the 'data' parameter is
* interpreted as an INT8 value, containing the new
* state flag settings.
*/
return ((xrEditor *) _MsgSetState (staticText, data,
drawSText, NULL));
}
case MSG_SIZE:
{
/*
* Return the size of the rectangle needed to enclose
* an instance of this editor, using the specifications
* passed in by the application program. The 'data'
* parameter must point to a partially filled out instance
* of the 'xrStaticTextInfo' structure; upon completion,
* the 'editorRect' field of the 'info' structure will
* be filled.
*/
xrStaticTextInfo *stInfoPtr;
stInfoPtr = (xrStaticTextInfo *)data;
if (stInfoPtr == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *)NULL);
}
else if (sizeSText (stInfoPtr, &stInfoPtr->editorRect) == FALSE)
{
/* Size request failed; xrErrno set by sizeSText */
return ((xrEditor *)NULL);
}
return ((xrEditor *) TRUE);
}
case MSG_REDRAW:
{
/*
* Redraw the static text instance.
* The 'staticText' parameter specifies the instance to redraw,
* while the 'data' parameter is interpreted as an INT32 value,
* specifying the type of redraw to perform.
*/
return ((xrEditor *) _MsgRedraw (staticText, data, drawSText, NULL));
}
case MSG_MOVE:
{
/*
* Relocate a static text instance to a new location.
* The 'staticText' parameter specifies the instance to be
* moved, while the 'data' parameter must point to a POINT
* structure, containing the new editor rectangle origin.
*/
POINT * ptPtr = (POINT *) data;
RECTANGLE workRect;
if (staticText == NULL)
{
xrErrno = XrINVALIDID;
return ((xrEditor *) NULL);
}
else if (data == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *) NULL);
}
/* Reset the origin for the editorRect */
XrCopyRect (&staticText->editorRect, &workRect);
staticText->editorRect.x = ptPtr->x;
staticText->editorRect.y = ptPtr->y;
if (staticText->editorState & XrVISIBLE)
{
/* Remove the instance from the window, if visible */
_XrMakeInvisible (staticText->editorWindowId, &workRect, TRUE);
/* Redisplay the instance, if it was visible */
drawSText (staticText, NULL);
}
/* Force the editor group rectangle to be recalculated */
XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, staticText);
return (staticText);
}
case MSG_RESIZE:
{
/*
* Resize an existing static text instance.
* The 'staticText' parameter indicates the instance to be
* resized, while the 'data' parameter must point to a
* RECTANGLE structure, containing the new editor rectangle.
*/
RECTANGLE * rectPtr = (RECTANGLE *) data;
RECTANGLE workRect;
if (staticText == NULL)
{
xrErrno = XrINVALIDID;
return ((xrEditor *) NULL);
}
else if (data == NULL)
{
xrErrno = XrINVALIDPTR;
return ((xrEditor *) NULL);
}
/* Validate the rectangle size */
if ((rectPtr->width <= 0) || (rectPtr->height <= 0))
{
xrErrno = XrINVALIDRECT;
return ((xrEditor *) NULL);
}
/* Save the new rectangle definition */
XrCopyRect (&staticText->editorRect, &workRect);
XrCopyRect (rectPtr, &staticText->editorRect);
if (staticText->editorState & XrVISIBLE)
{
/* Remove the instance from the window, if visible */
_XrMakeInvisible (staticText->editorWindowId, &workRect, TRUE);
/* Redisplay the instance, if it was visible */
drawSText (staticText, NULL);
}
/* Force the editor group rectangle to be recalculated */
XrEditorGroup (NULL, MSG_ADJUSTGROUPRECT, staticText);
return (staticText);
}
case MSG_EDIT:
{
/*
* Process the incoming event, and generate a return
* event, to indicate to the application program
* how the editor instance was modified. The 'data'
* parameter must point to the event to be processed.
*/
return ((xrEditor *) _MsgEdit (staticText, data,
processSText, XrSTATICTEXT));
}
default:
/* All other commands are invalid */
xrErrno = XrINVALIDMSG;
return ((xrEditor *)NULL);
} /* end of switch */
} /* end of XrStaticText() */
\f
/*************************************<->*************************************
*
* static
* INT32
* stFreeMemory (stDataPtr)
*
* Description:
* -----------
* This routine is called both when an existing instance is freed,
* and when a MSG_NEW request fails after createSText() has been
* called. It will free up all resources which createSText()
* allocated for the instance.
*
*
* Inputs:
* ------
* stDataPtr = Pointer to the instance's internal 'data' structure.
*
* Outputs:
* -------
*
* Procedures Called
* -----------------
*
*************************************<->***********************************/
static
INT32
stFreeMemory (stDataPtr)
xrStaticTextData * stDataPtr;
{
(*xrFree) (stDataPtr->textString);
}
\f
/*************************************<->*************************************
*
* static
* INT32
* sizeSText (stInfoPtr, rectPtr)
*
* Description:
* -----------
* This routine will validate most of the parameters contained within
* the 'info' structure pointed to by 'stInfoPtr', and will then
* calculate the size of the editor rectangle needed to contain the
* specified instance.
*
*
* Inputs:
* ------
* stInfoPtr = Pointer to an instance of the 'xrStaticTextInfo'
* structure, which describes the instance to be sized.
*
* rectPtr = Pointer to a RECTANGLE structure, in which the editor
* rectangle definition will be placed.
*
* Outputs:
* -------
* Upon successful completion, TRUE is returned, and the editor
* rectangle is returned.
*
* Upon failure, FALSE is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* _XrTextInfo() [textUtil.c]
* parseText()
*
*************************************<->***********************************/
static
INT32
sizeSText (stInfoPtr, rectPtr)
register xrStaticTextInfo * stInfoPtr;
register RECTANGLE * rectPtr;
{
FontInfo * fontPtr;
xrTextInfo fontData;
register INT32 alignment = stInfoPtr->alignment;
/* Validate all parameters */
if (stInfoPtr->editorRect.width <= 0)
{
xrErrno = XrINVALIDRECT;
return (FALSE);
}
else if (stInfoPtr->string == NULL)
{
xrErrno = XrINVALIDPTR;
return (FALSE);
}
else if (strlen (stInfoPtr->string) == 0)
{
xrErrno = XrINVALIDPARM;
return (FALSE);
}
else if ((alignment != XrCENTER_ALIGNED) && (alignment != XrLEFT_ALIGNED) &&
(alignment != XrRIGHT_ALIGNED) && (alignment != XrNO_ALIGNMENT))
{
xrErrno = XrINVALIDOPTION;
return (FALSE);
}
/* Set the rectangle coordinates */
rectPtr->x = 0;
rectPtr->y = 0;
/* Set up the variables we'll need for our calculations */
fontPtr = stInfoPtr->editorFont ? stInfoPtr->editorFont : xrBaseFontInfo;
_XrTextInfo (fontPtr, &fontData);
if (parseText (0, stInfoPtr->string, alignment, rectPtr, &fontData, FALSE)
== FALSE)
return (FALSE);
else
return (TRUE);
}
\f
/*************************************<->*************************************
*
* static
* INT32
* createSText (stDataPtr, stInfoPtr, message)
*
* Description:
* -----------
* This routine takes the instance definition, contained within the
* 'xrStaticTextInfo' structure pointed to by 'stInfoPtr', and creates
* an instance to match it. All information describing the new
* instance will be saved in the structure pointed to by 'stDataPtr'.
*
*
* Inputs:
* ------
* stDataPtr = Points to the 'data' structure, in which all state
* information for the new instance will be stored.
*
* stInfoPtr = Points to the 'info' structure describing the instance
* to be created.
*
* message = Not used; parameter is include so that this routine
* may be called by _MsgNew().
*
* Outputs:
* -------
* Upon successful completion, TRUE is returned.
*
* Upon failure, FALSE is returned, and xrErrno is set.
*
* Procedures Called
* -----------------
* _XrTextInfo() [textUtil.c]
*
*************************************<->***********************************/
static
INT32
createSText (stDataPtr, stInfoPtr, message)
register xrStaticTextData * stDataPtr;
register xrStaticTextInfo * stInfoPtr;
INT32 message;
{
register INT32 alignment = stInfoPtr->alignment;
register INT8 * strPtr = stInfoPtr->string;
FontInfo * fontPtr;
RECTANGLE workRect;
/* Validate all parameters */
if ((stInfoPtr->editorRect.width <= 0) ||
(stInfoPtr->editorRect.height <= 0))
{
xrErrno = XrINVALIDRECT;
return (FALSE);
}
/* Allocate some space to hold the text string */
if ((stDataPtr->textString = (xrMalloc)(strlen(strPtr) + 1)) == NULL)
{
xrErrno = XrOUTOFMEM;
return (FALSE);
}
/* Check for an invalid editor rectangle */
XrCopyRect (&stInfoPtr->editorRect, &workRect);
if (sizeSText (stInfoPtr, &workRect) == FALSE)
return (FALSE);
/* Copy the rest of the information describing the instance */
strcpy (stDataPtr->textString, strPtr);
stDataPtr->textAlignment = alignment;
fontPtr = stInfoPtr->editorFont ? stInfoPtr->editorFont : xrBaseFontInfo;
_XrTextInfo (fontPtr, &stDataPtr->textFont);
stDataPtr->stFGColor = (stInfoPtr->editorFGColor == -1) ?
xrForegroundColor : stInfoPtr->editorFGColor;
stDataPtr->stBGColor = (stInfoPtr->editorBGColor == -1) ?
xrBackgroundColor : stInfoPtr->editorBGColor;
return (TRUE);
}
\f
/*************************************<->*************************************
*
* static
* INT32
* drawSText (staticText, drawOption)
*
* Description:
* -----------
* This routine draws a static text instance. The way in which it
* is drawn depends upon the state of the XrVISIBLE state flag only.
*
*
* Inputs:
* ------
* staticText = Points to the instance structure associated with the
* instance to be drawn. This contains all the data
* necessary to draw the particular static text instance.
*
* drawOption = Not used by this procedure; it is here only so that
* this routine may be called by _MsgNew().
*
* Outputs:
* -------
*
* Procedures Called
* -----------------
* _XrMakeInvisible() [editorUtil.c]
* _XrInitEditorGCs() [gcUtil.c]
* parseText()
*
*************************************<->***********************************/
static
INT32
drawSText (staticText, drawOption)
xrEditor * staticText;
INT32 drawOption;
{
Window windowId;
register xrStaticTextData * stDataPtr;
stDataPtr = (xrStaticTextData *) staticText->editorData;
windowId = staticText->editorWindowId;
/*
* If the instance is not visible, then fill its area with the
* background tile for the window, thus making the instance invisible.
*/
if (!(staticText->editorState & XrVISIBLE))
{
_XrMakeInvisible (windowId, &staticText->editorRect, TRUE);
return;
}
/* Initialize the graphics context we will be needing */
_XrInitEditorGCs (stDataPtr->stFGColor, stDataPtr->stBGColor,
stDataPtr->textFont.fontInfo->id);
/* Display the text */
parseText (windowId, stDataPtr->textString, stDataPtr->textAlignment,
&staticText->editorRect, &stDataPtr->textFont, TRUE);
}
\f
/*************************************<->*************************************
*
* static
* INT32
* parseText (windowId, string, textAlignment, rectPtr, fontPtr, draw)
*
* Description:
* -----------
* This is the real work horse routine during the drawing of an
* instance. It takes the static text string, and parses out each
* line, and then displays it. It continues until either the complete
* string has been displayed, or the bottom of the editor rectangle
* is reached.
*
* This routine is also used when a MSG_SIZE request is made. For
* this case, the text is parse only, and the size of the rectangle
* needed to contain all of it is calculated.
*
*
* Inputs:
* ------
* windowId = Id for window in which text is to be displayed.
*
* string = String to be parsed and potentially displayed.
*
* textAlignment = Type of alignment to use.
*
* rectPtr = If drawing, then this is the editor rectangle; else
* this needs to be filled with the editor rectangle.
*
* fontPtr = Points to the font information.
*
* draw = TRUE, if the instance is to be drawn; FALSE if the instance
* is to be sized only.
*
* Outputs:
* -------
* Returns TRUE if the text is successfully parsed.
*
* Returns FALSE otherwise.
*
* Procedures Called
* -----------------
* XrStringWidth() [utilities.c]
* _XrImageText8() [textUtil.c]
*
*************************************<->***********************************/
static
INT32
parseText (windowId, string, textAlignment, rectPtr, fontPtr, draw)
Window windowId;
INT8 * string;
INT32 textAlignment;
RECTANGLE * rectPtr;
register xrTextInfo * fontPtr;
INT32 draw;
{
register INT16 width, delta;
INT16 lowerBoundary;
register INT8 * end, * start;
INT8 * previousEnd, * stripPtr;
INT16 oldWidth;
INT32 forcedBreak;
INT32 wordCount;
INT16 stringWidth;
INT16 x, y;
/* Set up the variables we'll need to draw the instance */
delta = fontPtr->ascent + fontPtr->descent + fontPtr->leading;
width = rectPtr->width;
start = end = string;
if (draw)
{
lowerBoundary = rectPtr->y + rectPtr->height - fontPtr->descent -
fontPtr->ascent; /* This is a release 10 fix */
y = rectPtr->y; /* + fontPtr->ascent; */
}
else
y = 0;
/* Draw the static raster instance */
while (1)
{
wordCount = 0;
oldWidth = 0;
forcedBreak = FALSE;
/* If doing alignment, then strip leading spaces */
if (textAlignment != XrNO_ALIGNMENT)
{
while (*start == ' ') start++;
end = start;
}
/* Parse out a single line */
while (1)
{
/* Parse out a single word */
if (*end == ' ')
/* Count each space as a word */
end++;
else if ((*end=='\n') ||(*end=='\r') || (*end=='\f') || (*end=='\013'))
{
/* Force to a new line */
forcedBreak = TRUE;
break;
}
else if (*end == NULL)
{
/* End of string reached */
if (wordCount == 0)
{
if (draw == FALSE)
rectPtr->height = y - fontPtr->leading;
return (TRUE);
}
break;
}
else
/* Extract a word upto a separator */
while ((*end != NULL) && (*end != ' ') && (*end != '\n') &&
(*end != '\r') && (*end != '\f') && (*end != '\013')) end++;
stringWidth = XrStringWidth(fontPtr->fontInfo, start, end - start,0,0);
wordCount++;
/* See if we have surpassed the rectangle right border */
if (stringWidth > width)
{
/*
* Back track to the last word which fit, unless this
* is the only word on the line.
*/
if (wordCount > 1)
{
end = previousEnd;
stringWidth= oldWidth;
}
else if (wordCount == 1)
{
xrErrno = XrINVALIDRECT;
return (FALSE);
}
break;
}
previousEnd = end;
oldWidth = stringWidth;
}
/* Display the line, if one was extracted */
if ((wordCount > 0) && (draw))
{
if (y > lowerBoundary)
break;
/* If doing alignment, then strip trailing spaces */
stripPtr = end - 1;
if (textAlignment != XrNO_ALIGNMENT)
{
while ((*stripPtr == ' ') && (stripPtr > start+1)) stripPtr--;
stringWidth = XrStringWidth(fontPtr->fontInfo, start,
stripPtr - start + 1, 0, 0);
}
/* Justify the line of text */
switch (textAlignment)
{
case XrCENTER_ALIGNED:
x = rectPtr->x + (width >> 1) - (stringWidth >> 1);
break;
case XrRIGHT_ALIGNED:
x = rectPtr->x + rectPtr->width - 1 - stringWidth;
break;
case XrNO_ALIGNMENT:
case XrLEFT_ALIGNED:
x = rectPtr->x;
break;
}
/* Display the string */
_XrImageText8 (windowId, xrEditorGC1, stripPtr + 1 - start,
x, y, start);
}
if (forcedBreak)
end++;
/* Continue with the next line */
y += delta;
start = end;
}
return (TRUE);
}
\f
/*************************************<->*************************************
*
* static
* INT32
* processSText (staticText, event, returnEvent)
*
* xrEditor * staticText;
* XButtonEvent * event;
* xrEvent * returnEvent;
*
* Description:
* -----------
* This is the event processing routine for the static text editor.
* Since we already know by this point that the event was a SELECT,
* and that it occurred within the instance, we simply need to
* fill in the return event structure, so that it can be pushed onto
* the input queue.
*
*
* Inputs:
* ------
* staticText = Points to the instance structure.
*
* event = Points to the SELECT event being processed.
*
* returnEvent = Points to the X-ray event structure, which will
* be pushed onto the input queue on return.
*
* Outputs:
* -------
*
* Procedures Called
* -----------------
*
*************************************<->***********************************/
static
INT32
processSText (staticText, event, returnEvent)
xrEditor * staticText;
XButtonEvent * event;
xrEvent * returnEvent;
{
returnEvent->value1 = XrSELECT;
}