1
/* $Xorg: MultiSink.c,v 1.4 2001/02/09 02:03:44 xorgcvs Exp $ */
4
* Copyright 1991 by OMRON Corporation
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of OMRON not be used in advertising
11
* or publicity pertaining to distribution of the software without specific,
12
* written prior permission. OMRON makes no representations about the
13
* suitability of this software for any purpose. It is provided "as is"
14
* without express or implied warranty.
16
* OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
* EVENT SHALL OMRON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
* TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
* PERFORMANCE OF THIS SOFTWARE.
24
* Author: Li Yuhong OMRON Corporation
27
/***********************************************************
29
Copyright 1987, 1988, 1994, 1998 The Open Group
31
Permission to use, copy, modify, distribute, and sell this software and its
32
documentation for any purpose is hereby granted without fee, provided that
33
the above copyright notice appear in all copies and that both that
34
copyright notice and this permission notice appear in supporting
37
The above copyright notice and this permission notice shall be included in
38
all copies or substantial portions of the Software.
40
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
43
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
44
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
45
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47
Except as contained in this notice, the name of The Open Group shall not be
48
used in advertising or otherwise to promote the sale, use or other dealings
49
in this Software without prior written authorization from The Open Group.
52
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
56
Permission to use, copy, modify, and distribute this software and its
57
documentation for any purpose and without fee is hereby granted,
58
provided that the above copyright notice appear in all copies and that
59
both that copyright notice and this permission notice appear in
60
supporting documentation, and that the name of Digital not be
61
used in advertising or publicity pertaining to distribution of the
62
software without specific, written prior permission.
64
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
65
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
66
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
67
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
68
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
69
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
72
******************************************************************/
73
/* $XFree86: xc/lib/Xaw/MultiSink.c,v 1.20 2001/12/14 19:54:41 dawes Exp $ */
75
#include <X11/IntrinsicP.h>
76
#include <X11/StringDefs.h>
77
#include <X11/Xatom.h>
78
#include <X11/Xaw/XawInit.h>
79
#include <X11/Xaw/MultiSinkP.h>
80
#include <X11/Xaw/MultiSrcP.h>
81
#include <X11/Xaw/TextP.h>
88
#undef GETLASTPOS /* We will use our own GETLASTPOS */
92
XawTextSourceScan(source, 0, XawstAll, XawsdRight, 1, True)
97
static void XawMultiSinkClassInitialize(void);
98
static void XawMultiSinkInitialize(Widget, Widget, ArgList, Cardinal*);
99
static void XawMultiSinkDestroy(Widget);
100
static void XawMultiSinkResize(Widget);
101
static Boolean XawMultiSinkSetValues(Widget, Widget, Widget,
103
static int MaxLines(Widget, unsigned int);
104
static int MaxHeight(Widget, int);
105
static void SetTabs(Widget, int, short*);
106
static void DisplayText(Widget, int, int,
107
XawTextPosition, XawTextPosition, Bool);
108
static void InsertCursor(Widget, int, int, XawTextInsertState);
109
static void FindPosition(Widget, XawTextPosition, int, int, Bool,
110
XawTextPosition*, int*, int*);
111
static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*,
112
XawTextPosition*, int*);
113
static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*);
114
static void GetCursorBounds(Widget, XRectangle*);
119
static void GetGC(MultiSinkObject);
120
static int CharWidth(MultiSinkObject, XFontSet, int, wchar_t);
121
static unsigned int PaintText(Widget w, GC gc, int x, int y,
122
wchar_t *buf, int len, Bool);
125
* Defined in TextSink.c
127
void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned);
132
static wchar_t wspace[2];
134
#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field)
135
static XtResource resources[] = {
155
XtNdisplayNonprinting,
159
offset(display_nonprinting),
166
#define SuperClass (&textSinkClassRec)
167
MultiSinkClassRec multiSinkClassRec = {
170
(WidgetClass)SuperClass, /* superclass */
171
"MultiSink", /* class_name */
172
sizeof(MultiSinkRec), /* widget_size */
173
XawMultiSinkClassInitialize, /* class_initialize */
174
NULL, /* class_part_initialize */
175
False, /* class_inited */
176
XawMultiSinkInitialize, /* initialize */
177
NULL, /* initialize_hook */
181
resources, /* resources */
182
XtNumber(resources), /* num_resources */
183
NULLQUARK, /* xrm_class */
188
XawMultiSinkDestroy, /* destroy */
189
(XtProc)XawMultiSinkResize, /* obj8 */
191
XawMultiSinkSetValues, /* set_values */
192
NULL, /* set_values_hook */
194
NULL, /* get_values_hook */
196
XtVersion, /* version */
197
NULL, /* callback_private */
201
NULL, /* extension */
205
DisplayText, /* DisplayText */
206
InsertCursor, /* InsertCursor */
207
XtInheritClearToBackground, /* ClearToBackground */
208
FindPosition, /* FindPosition */
209
FindDistance, /* FindDistance */
210
Resolve, /* Resolve */
211
MaxLines, /* MaxLines */
212
MaxHeight, /* MaxHeight */
213
SetTabs, /* SetTabs */
214
GetCursorBounds, /* GetCursorBounds */
218
NULL, /* extension */
222
WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec;
228
CharWidth(MultiSinkObject sink, XFontSet fontset, int x, wchar_t c)
232
if (c == _Xaw_atowc(XawLF))
235
if (c == _Xaw_atowc(XawTAB)) {
240
/* Adjust for Left Margin. */
241
x -= ((TextWidget)XtParent((Widget)sink))->text.left_margin;
244
tab = sink->text_sink.tabs;
250
if (++i >= sink->text_sink.tab_count) {
253
tab = sink->text_sink.tabs;
263
if (XwcTextEscapement(fontset, &c, 1) == 0) {
264
if (sink->multi_sink.display_nonprinting)
267
c = _Xaw_atowc(XawSP);
271
* if more efficiency(suppose one column is one ASCII char)
273
width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) *
274
fontset->font_struct_list[0]->min_bounds.width;
276
* WARNING: Very Slower!!!
281
width = XwcTextEscapement(fontset, &c, 1);
291
* w - text sink object
292
* gc - gc to paint text
293
* x - location to paint the text
295
* buf - buffer and length of text to paint
297
* clear_bg - clear background before drawing ?
300
* Actually paints the text into the window.
303
* The width of the text painted
306
PaintText(Widget w, GC gc, int x, int y, wchar_t *buf, int len, Bool clear_bg)
308
MultiSinkObject sink = (MultiSinkObject)w;
309
TextWidget ctx = (TextWidget)XtParent(w);
310
XFontSet fontset = sink->multi_sink.fontset;
311
unsigned int width = XwcTextEscapement(fontset, buf, len);
313
if (((int)width) <= -x) /* Don't draw if we can't see it */
317
XFontSetExtents *ext = XExtentsOfFontSet(fontset);
319
_XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y),
320
width, ext->max_logical_extent.height);
321
XwcDrawString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len);
324
XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc,
330
/* Sink Object Functions */
332
* This function does not know about drawing more than one line of text
335
DisplayText(Widget w, int x, int y,
336
XawTextPosition pos1, XawTextPosition pos2, Bool highlight)
338
TextWidget ctx = (TextWidget)XtParent(w);
339
MultiSinkObject sink = (MultiSinkObject)w;
340
XFontSet fontset = sink->multi_sink.fontset;
341
Widget source = XawTextGetSource(XtParent(w));
343
XFontSetExtents *ext = XExtentsOfFontSet(fontset);
350
if (!sink->multi_sink.echo || !ctx->text.lt.lines)
353
max_x = (int)XtWidth(ctx) - ctx->text.r_margin.right;
354
clear_bg = !highlight && ctx->core.background_pixmap != XtUnspecifiedPixmap;
356
gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc;
357
invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc;
359
if (highlight && sink->multi_sink.xorgc)
360
tabgc = sink->multi_sink.xorgc;
364
y += abs(ext->max_logical_extent.y);
365
for (j = 0; pos1 < pos2;) {
366
pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1);
367
for (k = 0; k < blk.length; k++) {
368
if ((unsigned) j >= (sizeof(buf) / sizeof(wchar_t)) - 1) {
369
/* buffer full, dump the text */
370
if ((x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x)
374
buf[j] = ((wchar_t *)blk.ptr)[k];
375
if (buf[j] == _Xaw_atowc(XawLF))
378
else if (buf[j] == _Xaw_atowc(XawTAB)) {
382
(x += PaintText(w, gc, x, y, buf, j, clear_bg)) >= max_x)
385
width = CharWidth(sink, fontset, x, _Xaw_atowc(XawTAB));
387
_XawTextSinkClearToBackground(w,
388
x, y - abs(ext->max_logical_extent.y),
389
width, ext->max_logical_extent.height);
391
XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
393
y - abs(ext->max_logical_extent.y),
395
ext->max_logical_extent.height);
399
else if (XwcTextEscapement(sink->multi_sink.fontset, &buf[j], 1)
401
if (sink->multi_sink.display_nonprinting)
402
buf[j] = _Xaw_atowc('@');
404
buf[j] = _Xaw_atowc(XawSP);
411
(void)PaintText(w, gc, x, y, buf, j, clear_bg);
419
* w - text sink object
420
* rect - X rectangle to return the cursor bounds
423
* Returns the size and location of the cursor.
426
GetCursorBounds(Widget w, XRectangle *rect)
428
MultiSinkObject sink = (MultiSinkObject)w;
430
rect->width = CharWidth(sink, sink->multi_sink.fontset, 0, _Xaw_atowc(XawSP));
431
rect->height = (XExtentsOfFontSet(sink->multi_sink.fontset)
432
->max_logical_extent.height);
433
rect->x = sink->multi_sink.cursor_x;
434
rect->y = sink->multi_sink.cursor_y - (short)rect->height;
438
* The following procedure manages the "insert" cursor
441
InsertCursor(Widget w, int x, int y, XawTextInsertState state)
443
MultiSinkObject sink = (MultiSinkObject)w;
444
XFontSet fontset = sink->multi_sink.fontset;
445
Widget ctx = XtParent(w);
446
XawTextPosition position = XawTextGetInsertionPoint(ctx);
448
if (XtIsRealized(ctx)) {
452
XawTextPosition selection_start, selection_end;
453
Boolean has_selection;
454
XFontSetExtents *ext = XExtentsOfFontSet(fontset);
456
XawTextGetSelectionPos((Widget)ctx, &selection_start, &selection_end);
457
has_selection = selection_start != selection_end;
459
fheight = ext->max_logical_extent.height;
460
fdiff = fheight - abs(ext->max_logical_extent.y);
462
if ((sink->multi_sink.cursor_position != position || state == XawisOff)
463
&& !has_selection && sink->multi_sink.laststate != XawisOff) {
466
(void)XawTextSourceRead(XawTextGetSource(ctx),
467
sink->multi_sink.cursor_position,
472
c = ((wchar_t *)block.ptr)[0];
473
if (c == _Xaw_atowc(XawLF))
475
else if (c == _Xaw_atowc(XawTAB))
478
ochar = (wchar_t *)block.ptr;
482
_XawTextSinkClearToBackground(w, sink->multi_sink.cursor_x,
483
(sink->multi_sink.cursor_y - 1 -
484
fheight), CharWidth(sink, fontset,
488
if (XwcTextEscapement(sink->multi_sink.fontset, ochar, 1) != 0)
489
DisplayText(w, sink->multi_sink.cursor_x,
490
sink->multi_sink.cursor_y - 1 - fheight,
491
sink->multi_sink.cursor_position,
492
sink->multi_sink.cursor_position + 1,
495
PaintText(w, sink->multi_sink.normgc,
496
sink->multi_sink.cursor_x,
497
sink->multi_sink.cursor_y - 1 - fdiff,
499
ctx->core.background_pixmap != XtUnspecifiedPixmap);
503
if (!has_selection && state != XawisOff) {
505
Boolean focus = ((TextWidget)ctx)->text.hasfocus;
507
(void)XawTextSourceRead(XawTextGetSource(ctx),
508
position, &block, 1);
509
c = ((wchar_t *)block.ptr)[0];
510
if (!block.length || c == _Xaw_atowc(XawLF)
511
|| c == _Xaw_atowc(XawTAB))
514
nchar = (wchar_t *)block.ptr;
517
if (XwcTextEscapement(sink->multi_sink.fontset, nchar, 1) != 0)
518
XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx),
519
fontset, sink->multi_sink.invgc,
520
x, (y - 1 - fdiff), nchar, 1);
522
DisplayText(w, x, y - 1 - fheight,
523
position, position + 1, True);
526
XDrawRectangle(XtDisplay(ctx), XtWindow(ctx),
527
sink->multi_sink.xorgc ?
528
sink->multi_sink.xorgc : sink->multi_sink.normgc,
530
CharWidth(sink, fontset, 0, *nchar) - 1,
535
sink->multi_sink.cursor_x = x;
536
sink->multi_sink.cursor_y = y;
537
sink->multi_sink.laststate = state;
538
sink->multi_sink.cursor_position = position;
542
* Given two positions, find the distance between them
545
FindDistance(Widget w, XawTextPosition fromPos, int fromx,
546
XawTextPosition toPos, int *resWidth,
547
XawTextPosition *resPos, int *resHeight)
549
MultiSinkObject sink = (MultiSinkObject)w;
550
XFontSet fontset = sink->multi_sink.fontset;
551
TextWidget ctx = (TextWidget)XtParent(w);
552
Widget source = ctx->text.source;
553
XawTextPosition idx, pos;
555
XFontSetExtents *ext = XExtentsOfFontSet(fontset);
559
pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos);
561
for (i = 0, idx = fromPos; idx < toPos; i++, idx++) {
562
if (i >= blk.length) {
564
XawTextSourceRead(source, pos, &blk, toPos - pos);
568
c = ((wchar_t *)blk.ptr)[i];
569
rWidth += CharWidth(sink, fontset, fromx + rWidth, c);
570
if (c == _Xaw_atowc(XawLF)) {
578
*resHeight = ext->max_logical_extent.height;
582
FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width,
583
Bool stopAtWordBreak, XawTextPosition *resPos, int *resWidth,
586
MultiSinkObject sink = (MultiSinkObject)w;
587
TextWidget ctx = (TextWidget)XtParent(w);
588
Widget source = ctx->text.source;
589
XFontSet fontset = sink->multi_sink.fontset;
590
XawTextPosition idx, pos, whiteSpacePosition = 0;
591
int i, lastWidth, whiteSpaceWidth, rWidth;
592
Boolean whiteSpaceSeen;
594
XFontSetExtents *ext = XExtentsOfFontSet(fontset);
597
pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ);
598
rWidth = lastWidth = whiteSpaceWidth = 0;
599
whiteSpaceSeen = False;
602
for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) {
603
if (i >= blk.length) {
605
pos = XawTextSourceRead(source, pos, &blk, BUFSIZ);
609
c = ((wchar_t *)blk.ptr)[i];
611
rWidth += CharWidth(sink, fontset, fromx + rWidth, c);
613
if (c == _Xaw_atowc(XawLF)) {
617
else if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB))
618
&& rWidth <= width) {
619
whiteSpaceSeen = True;
620
whiteSpacePosition = idx;
621
whiteSpaceWidth = rWidth;
625
if (rWidth > width && idx > fromPos) {
628
if (stopAtWordBreak && whiteSpaceSeen) {
629
idx = whiteSpacePosition + 1;
630
rWidth = whiteSpaceWidth;
634
if (idx >= ctx->text.lastPos && c != _Xaw_atowc(XawLF))
635
idx = ctx->text.lastPos + 1;
639
*resHeight = ext->max_logical_extent.height;
643
Resolve(Widget w, XawTextPosition pos, int fromx, int width,
644
XawTextPosition *pos_return)
646
int resWidth, resHeight;
647
Widget source = XawTextGetSource(XtParent(w));
649
FindPosition(w, pos, fromx, width, False, pos_return, &resWidth, &resHeight);
650
if (*pos_return > GETLASTPOS)
651
*pos_return = GETLASTPOS;
655
GetGC(MultiSinkObject sink)
657
XtGCMask valuemask = (GCGraphicsExposures | GCClipXOrigin |
658
GCForeground | GCBackground);
661
/* XXX We dont want do share a gc that will change the clip-mask */
662
values.clip_x_origin = (long)sink;
663
values.clip_mask = None;
664
values.graphics_exposures = False;
666
values.foreground = sink->text_sink.foreground;
667
values.background = sink->text_sink.background;
669
sink->multi_sink.normgc = XtAllocateGC((Widget)sink, 0, valuemask, &values,
670
GCFont | GCClipMask, 0);
672
values.foreground = sink->text_sink.background;
674
values.background = sink->text_sink.cursor_color;
676
values.background = sink->text_sink.foreground;
678
sink->multi_sink.invgc = XtAllocateGC((Widget)sink, 0, valuemask, &values,
679
GCFont | GCClipMask, 0);
681
if (sink->text_sink.cursor_color != sink->text_sink.foreground) {
682
values.foreground = sink->text_sink.cursor_color;
683
values.background = sink->text_sink.foreground;
684
sink->multi_sink.xorgc = XtAllocateGC((Widget)sink, 0, valuemask,
685
&values, GCFont | GCClipMask, 0);
689
sink->multi_sink.xorgc = NULL;
691
XawMultiSinkResize((Widget)sink);
695
XawMultiSinkClassInitialize(void)
697
wspace[0] = _Xaw_atowc(XawSP);
698
XawInitializeWidgetSet();
703
* XawMultiSinkInitialize
706
* request - requested and new values for the object instance
710
* Initializes the TextSink Object.
714
XawMultiSinkInitialize(Widget request, Widget cnew,
715
ArgList args, Cardinal *num_args)
717
MultiSinkObject sink = (MultiSinkObject)cnew;
721
sink->multi_sink.cursor_position = 0;
722
sink->multi_sink.laststate = XawisOff;
723
sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0;
728
* XawMultiSinkDestroy
731
* w - MultiSink Object
734
* This function cleans up when the object is destroyed.
737
XawMultiSinkDestroy(Widget w)
739
MultiSinkObject sink = (MultiSinkObject)w;
741
XtReleaseGC(w, sink->multi_sink.normgc);
742
XtReleaseGC(w, sink->multi_sink.invgc);
743
if (sink->multi_sink.xorgc)
744
XtReleaseGC(w, sink->multi_sink.xorgc);
745
sink->multi_sink.normgc =
746
sink->multi_sink.invgc =
747
sink->multi_sink.xorgc = NULL;
751
XawMultiSinkResize(Widget w)
753
TextWidget ctx = (TextWidget)XtParent(w);
754
MultiSinkObject sink = (MultiSinkObject)w;
758
if (w->core.widget_class != multiSinkObjectClass)
761
rect.x = ctx->text.r_margin.left;
762
rect.y = ctx->text.r_margin.top;
763
width = (int)XtWidth(ctx) -
764
(int)ctx->text.r_margin.right - (int)ctx->text.r_margin.left;
765
height = (int)XtHeight(ctx) -
766
(int)ctx->text.r_margin.top - (int)ctx->text.r_margin.bottom;
768
rect.height = height;
770
if (sink->multi_sink.normgc) {
771
if (width >= 0 && height >= 0)
772
XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.normgc,
773
0, 0, &rect, 1, Unsorted);
775
XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.normgc, None);
777
if (sink->multi_sink.invgc) {
778
if (width >= 0 && height >= 0)
779
XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.invgc,
780
0, 0, &rect, 1, Unsorted);
782
XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.invgc, None);
784
if (sink->multi_sink.xorgc) {
785
if (width >= 0 && height >= 0)
786
XSetClipRectangles(XtDisplay((Widget)ctx), sink->multi_sink.xorgc,
787
0, 0, &rect, 1, Unsorted);
789
XSetClipMask(XtDisplay((Widget)ctx), sink->multi_sink.xorgc, None);
795
* XawMultiSinkSetValues
798
* current - current state of the object
799
* request - what was requested
800
* cnew - what the object will become
803
* Sets the values for the MultiSink.
806
* True if redisplay is needed
810
XawMultiSinkSetValues(Widget current, Widget request, Widget cnew,
811
ArgList args, Cardinal *num_args)
813
MultiSinkObject w = (MultiSinkObject)cnew;
814
MultiSinkObject old_w = (MultiSinkObject)current;
816
/* Font set is not in the GC! Do not make a new GC when font set changes! */
818
if (w->multi_sink.fontset != old_w->multi_sink.fontset) {
819
((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
821
SetTabs((Widget)w, w->text_sink.tab_count, w->text_sink.char_tabs);
825
if (w->text_sink.background != old_w->text_sink.background
826
|| w->text_sink.foreground != old_w->text_sink.foreground
828
|| w->text_sink.cursor_color != old_w->text_sink.cursor_color
831
XtReleaseGC(cnew, w->multi_sink.normgc);
832
XtReleaseGC(cnew, w->multi_sink.invgc);
833
if (w->multi_sink.xorgc)
834
XtReleaseGC(cnew, w->multi_sink.xorgc);
836
((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
838
else if (w->multi_sink.echo != old_w->multi_sink.echo
839
|| w->multi_sink.display_nonprinting
840
!= old_w->multi_sink.display_nonprinting)
841
((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
851
* w - MultiSink Object
852
* height - height to fit lines into
855
* Finds the Maximum number of lines that will fit in a given height.
858
* The number of lines that will fit
862
MaxLines(Widget w, unsigned int height)
864
MultiSinkObject sink = (MultiSinkObject)w;
866
XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
868
font_height = ext->max_logical_extent.height;
869
return (height / font_height);
877
* w - MultiSink Object
878
* lines - number of lines
881
* Finds the Minium height that will contain a given number lines.
887
MaxHeight(Widget w, int lines)
889
MultiSinkObject sink = (MultiSinkObject)w;
890
XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
892
return (lines * ext->max_logical_extent.height);
900
* w - MultiSink Object
901
* tab_count - number of tabs in the list
902
* tabs - text positions of the tabs
905
* Sets the Tab stops.
908
SetTabs(Widget w, int tab_count, short* tabs)
910
MultiSinkObject sink = (MultiSinkObject)w;
912
Atom XA_FIGURE_WIDTH;
913
unsigned long figure_width = 0;
918
* Suppose the first font of fontset stores the unit of column.
920
* By Li Yuhong, Mar. 14, 1991
923
XFontStruct **f_list;
926
(void)XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name);
931
* Find the figure width of the current font
933
XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", False);
934
if (XA_FIGURE_WIDTH != None
935
&& (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)
936
|| figure_width == 0)) {
937
if (font->per_char && font->min_char_or_byte2 <= '$'
938
&& font->max_char_or_byte2 >= '$')
939
figure_width = font->per_char['$' - font->min_char_or_byte2].width;
941
figure_width = font->max_bounds.width;
944
if (tab_count > sink->text_sink.tab_count) {
945
sink->text_sink.tabs = (Position *)
946
XtRealloc((char *)sink->text_sink.tabs,
947
(Cardinal)(tab_count * sizeof(Position)));
948
sink->text_sink.char_tabs = (short *)
949
XtRealloc((char *)sink->text_sink.char_tabs,
950
(Cardinal)(tab_count * sizeof(short)));
953
for (i = 0 ; i < tab_count ; i++) {
954
sink->text_sink.tabs[i] = tabs[i] * figure_width;
955
sink->text_sink.char_tabs[i] = tabs[i];
958
sink->text_sink.tab_count = tab_count;
961
((TextWidget)XtParent(w))->text.redisplay_needed = True;
966
_XawMultiSinkPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y)
968
MultiSinkObject sink = (MultiSinkObject)((TextWidget)w)->text.sink;
969
XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
971
_XawTextPosToXY(w, pos, x, y);
972
*y += abs(ext->max_logical_extent.y);