/*
 * Implementation
 */
static int
CharWidth(MultiSinkObject sink, XFontSet fontset, int x, wchar_t c)
{
    int width = 0;

    if (c == _Xaw_atowc(XawLF))
	return (0);

    if (c == _Xaw_atowc(XawTAB)) {
	int i;
	Position *tab;

	width = x;
	/* Adjust for Left Margin. */
	x -= ((TextWidget)XtParent((Widget)sink))->text.left_margin;

	i = 0;
	tab = sink->text_sink.tabs;
	/*CONSTCOND*/
	while (1) {
	    if (x < *tab)
		return (*tab - x);
	    /* Start again */
	    if (++i >= sink->text_sink.tab_count) {
		x -= *tab;
		i = 0;
		tab = sink->text_sink.tabs;
		if (width == x)
		    return (0);
	    }
	    else
		++tab;
	}
	/*NOTREACHED*/
    }

    if (XwcTextEscapement(fontset, &c, 1) == 0) {
	if (sink->multi_sink.display_nonprinting)
	    c = _Xaw_atowc('@');
	else
	    c = _Xaw_atowc(XawSP);
    }

      /*
       * if more efficiency(suppose one column is one ASCII char)

      width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) *
	      fontset->font_struct_list[0]->min_bounds.width;
       *
       * WARNING: Very Slower!!!
       *
       * Li Yuhong.
       */

    width = XwcTextEscapement(fontset, &c, 1);

    return (width);
}
예제 #2
0
static int
CharWidth(Widget w, int x, wchar_t c)
{
    int i, width;
    MultiSinkObject sink = (MultiSinkObject) w;
    XFontSet fontset = sink->multi_sink.fontset;
    Position *tab;

    if (c == _Xaw_atowc(XawLF))
	return (0);

    if (c == _Xaw_atowc(XawTAB)) {
	/* Adjust for Left Margin. */
	x -= ((TextWidget) XtParent(w))->text.margin.left;

	if (x >= (int) XtParent(w)->core.width)
	    return 0;
	for (i = 0, tab = sink->text_sink.tabs;
	     i < sink->text_sink.tab_count; i++, tab++) {
	    if (x < *tab) {
		if (*tab < (int) XtParent(w)->core.width)
		    return *tab - x;
		else
		    return 0;
	    }
	}
	return 0;
    }

    if (XwcTextEscapement(fontset, &c, 1) == 0) {
	if (sink->multi_sink.display_nonprinting)
	    c = _Xaw_atowc('@');
	else {
	    c = _Xaw_atowc(XawSP);
	}
    }

    /*
     * if more efficiency(suppose one column is one ASCII char)

     width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) *
     fontset->font_struct_list[0]->min_bounds.width;
     *
     * WARNING: Very Slower!!!
     *
     * Li Yuhong.
     */

    width = XwcTextEscapement(fontset, &c, 1);

    return width;
}
예제 #3
0
/*	Function Name: PaintText
 *	Description: Actually paints the text into the windoe.
 *	Arguments: w - the text widget.
 *                 gc - gc to paint text with.
 *                 x, y - location to paint the text.
 *                 buf, len - buffer and length of text to paint.
 *	Returns: the width of the text painted, or 0.
 *
 * NOTE:  If this string attempts to paint past the end of the window
 *        then this function will return zero.
 */
static Dimension
PaintText(Widget w, GC gc, Position x, Position y, wchar_t *buf, int len)
{
    MultiSinkObject sink = (MultiSinkObject) w;
    TextWidget ctx = (TextWidget) XtParent(w);

    XFontSet fontset = sink->multi_sink.fontset;
    Position max_x;
    Dimension width = (Dimension) XwcTextEscapement(fontset, buf, len);
    XFontSetExtents *ext = XExtentsOfFontSet(fontset);
    max_x = (Position) ctx->core.width;

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

    XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc,
		       (int) x, (int) y, buf, len);
    if ((((Position) width + x) > max_x) && (ctx->text.margin.right != 0)) {
	x = (Position) (ctx->core.width - ctx->text.margin.right);
	width = (Dimension) ctx->text.margin.right;
	XFillRectangle(XtDisplay((Widget) ctx), XtWindow((Widget) ctx),
		       sink->multi_sink.normgc, (int) x,
		       (int) y - abs(ext->max_logical_extent.y),
		       (unsigned int) width,
		       (unsigned int) ext->max_logical_extent.height);
	return (0);
    }
    return (width);
}
/*
 * 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);
}
예제 #5
0
/*
 * This function does not know about drawing more than one line of text.
 */
static void
DisplayText(
	       Widget w,
	       Position x,
	       Position y,
	       XawTextPosition pos1,
	       XawTextPosition pos2,
	       Boolean highlight)
{
    MultiSinkObject sink = (MultiSinkObject) w;
    Widget source = XawTextGetSource(XtParent(w));
    wchar_t buf[BUFSIZ];
    XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);

    int j, k;
    XawTextBlock blk;
    GC gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc;
    GC invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc;

    if (!sink->multi_sink.echo)
	return;

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

	    else if (buf[j] == _Xaw_atowc(XawTAB)) {
		Position temp = 0;
		Dimension width;

		if ((j != 0)
		    && ((temp = (Position) PaintText(w, gc, x, y, buf, j)
			) == 0))
		    return;

		x = (Position) (x + temp);
		width = (Dimension) CharWidth(w, x, _Xaw_atowc(XawTAB));
		XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
			       invgc, (int) x,
			       (int) y - abs(ext->max_logical_extent.y),
			       (unsigned int) width,
			       (unsigned int) ext->max_logical_extent.height);
		x = (Position) (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(' ');
	    }
	    j++;
	}
    }
    if (j > 0)
	(void) PaintText(w, gc, x, y, buf, j);
}
/*
 * 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);
}