Beispiel #1
0
/*ARGSUSED*/
void
XawTextSinkClearToBackground(Widget w,
#if NeedWidePrototypes
			     int x, int y,
			     unsigned int width, unsigned int height
#else
			     Position x, Position y,
			     Dimension width, Dimension height
#endif
)
{
    _XawTextSinkClearToBackground(w, x, y, width, height);
}
/*
 * Function:
 *	PaintText
 *
 * Parameters:
 *	w   - text sink object
 *	gc  - gc to paint text
 *	x   - location to paint the text
 *	y   - ""
 *	buf - buffer and length of text to paint
 *	len - ""
 *	clear_bg - clear background before drawing ?
 *
 * Description:
 *	Actually paints the text into the window.
 *
 * Returns:
 *	The width of the text painted
 */
static unsigned int
PaintText(Widget w, GC gc, int x, int y, wchar_t *buf, int len, Bool clear_bg)
{
    MultiSinkObject sink = (MultiSinkObject)w;
    TextWidget ctx = (TextWidget)XtParent(w);
    XFontSet fontset = sink->multi_sink.fontset;
    unsigned int width = XwcTextEscapement(fontset, buf, len);

    if (((int)width) <= -x)		/* Don't draw if we can't see it */
	return (width);

    if (clear_bg) {
	XFontSetExtents *ext = XExtentsOfFontSet(fontset);

	_XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y),
				      width, ext->max_logical_extent.height);
	XwcDrawString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len);
    }
    else
	XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc,
			   x, y, buf, len);

    return (width);
}
/*
 * The following procedure manages the "insert" cursor
 */
static void
InsertCursor(Widget w, int x, int y, XawTextInsertState state)
{
    MultiSinkObject sink = (MultiSinkObject)w;
    XFontSet fontset = sink->multi_sink.fontset;
    Widget ctx = XtParent(w);
    XawTextPosition position = XawTextGetInsertionPoint(ctx);

    if (XtIsRealized(ctx)) {
	int fheight, fdiff;
	XawTextBlock block;
	wchar_t c;
	XawTextPosition selection_start, selection_end;
	Boolean has_selection;
	XFontSetExtents *ext = XExtentsOfFontSet(fontset);

	XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end);
	has_selection = selection_start != selection_end;

	fheight = ext->max_logical_extent.height;
	fdiff = fheight - abs(ext->max_logical_extent.y);

	if ((sink->multi_sink.cursor_position != position || state == XawisOff)
	    && !has_selection && sink->multi_sink.laststate != XawisOff) {
	    wchar_t *ochar;

	    (void)XawTextSourceRead(XawTextGetSource(ctx),
				    sink->multi_sink.cursor_position,
				    &block, 1);
	    if (!block.length)
		ochar = NULL;
	    else {
		c = ((wchar_t *)block.ptr)[0];
		if (c == _Xaw_atowc(XawLF))
		    ochar = NULL;
		else if (c == _Xaw_atowc(XawTAB))
		    ochar = wspace;
		else
		    ochar = (wchar_t *)block.ptr;
	    }

	    if (!ochar)
		_XawTextSinkClearToBackground(w, sink->multi_sink.cursor_x,
					      (sink->multi_sink.cursor_y - 1 -
					      fheight), CharWidth(sink, fontset,
								  0, wspace[0]),
					      fheight);
	    else {
		if (XwcTextEscapement(sink->multi_sink.fontset, ochar, 1) != 0)
		    DisplayText(w, sink->multi_sink.cursor_x,
				sink->multi_sink.cursor_y - 1 - fheight,
				sink->multi_sink.cursor_position,
				sink->multi_sink.cursor_position + 1,
				False);
		else
		    PaintText(w, sink->multi_sink.normgc,
			      sink->multi_sink.cursor_x,
			      sink->multi_sink.cursor_y - 1 - fdiff,
			      ochar, 1,
			      ctx->core.background_pixmap != XtUnspecifiedPixmap);
	    }
	}

	if (!has_selection && state != XawisOff) {
	    wchar_t *nchar;
	    Boolean focus = ((TextWidget)ctx)->text.hasfocus;

	    (void)XawTextSourceRead(XawTextGetSource(ctx),
				    position, &block, 1);
	    c = ((wchar_t *)block.ptr)[0];
	    if (!block.length || c == _Xaw_atowc(XawLF)
		|| c == _Xaw_atowc(XawTAB))
		nchar = wspace;
	    else
		nchar = (wchar_t *)block.ptr;

	    if (focus) {
		if (XwcTextEscapement(sink->multi_sink.fontset, nchar, 1) != 0)
		    XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx),
				       fontset, sink->multi_sink.invgc,
				       x, (y - 1 - fdiff), nchar, 1);
		else
		    DisplayText(w, x, y - 1 - fheight,
				position, position + 1, True);
	    }
	    else
		XDrawRectangle(XtDisplay(ctx), XtWindow(ctx),
			       sink->multi_sink.xorgc ?
			       sink->multi_sink.xorgc : sink->multi_sink.normgc,
			       x, y - 1 - fheight,
			       CharWidth(sink, fontset, 0, *nchar) - 1,
			       fheight - 1);
	  }
      }

    sink->multi_sink.cursor_x = x;
    sink->multi_sink.cursor_y = y;
    sink->multi_sink.laststate = state;
    sink->multi_sink.cursor_position = position;
}
/*
 * This function does not know about drawing more than one line of text
 */
static void
DisplayText(Widget w, int x, int y,
	    XawTextPosition pos1, XawTextPosition pos2, Bool highlight)
{
    TextWidget ctx = (TextWidget)XtParent(w);
    MultiSinkObject sink = (MultiSinkObject)w;
    XFontSet fontset = sink->multi_sink.fontset;
    Widget source = XawTextGetSource(XtParent(w));
    wchar_t buf[256];
    XFontSetExtents *ext = XExtentsOfFontSet(fontset);
    int j, k;
    XawTextBlock blk;
    GC gc, invgc, tabgc;
    int max_x;
    Bool clear_bg;

    if (!sink->multi_sink.echo || !ctx->text.lt.lines)
	return;

    max_x = (int)XtWidth(ctx) - ctx->text.r_margin.right;
    clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap;

    gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc;
    invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc;

    if (highlight && sink->multi_sink.xorgc)
	tabgc = sink->multi_sink.xorgc;
    else
	tabgc = invgc;

    y += abs(ext->max_logical_extent.y);
    for (j = 0; pos1 < pos2;) {
	pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1);
	for (k = 0; k < blk.length; k++) {
	    if ((unsigned) j >= (sizeof(buf) / sizeof(wchar_t)) - 1) {
		/* buffer full, dump the text */
		if ((x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x)
		    return;
		j = 0;
	    }
	    buf[j] = ((wchar_t *)blk.ptr)[k];
	    if (buf[j] == _Xaw_atowc(XawLF))
		continue;

	    else if (buf[j] == _Xaw_atowc(XawTAB)) {
		unsigned int width;

		if (j != 0 &&
		    (x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x)
		    return;

		width = CharWidth(sink, fontset, x, _Xaw_atowc(XawTAB));
		if (clear_bg)
		    _XawTextSinkClearToBackground(w,
					x, y - abs(ext->max_logical_extent.y),
					width, ext->max_logical_extent.height);
		else
		    XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
				   tabgc, x,
				   y - abs(ext->max_logical_extent.y),
				   width,
				   ext->max_logical_extent.height);
		x += width;
		j = -1;
	    }
	    else if (XwcTextEscapement(sink->multi_sink.fontset, &buf[j], 1)
		     == 0) {
		if (sink->multi_sink.display_nonprinting)
		    buf[j] = _Xaw_atowc('@');
		else
		    buf[j] = _Xaw_atowc(XawSP);
	    }
	    j++;
	}
    }

    if (j > 0)
	(void)PaintText(w, gc, x, y, buf, j, clear_bg);
}