Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtTerm / TermPrim / TermPrimRenderLineDraw.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 #ifndef lint
24 #ifdef  VERBOSE_REV_INFO
25 static char rcs_id[] = "$XConsortium: TermPrimRenderLineDraw.c /main/1 1996/04/21 19:18:59 drk $";
26 #endif  /* VERBOSE_REV_INFO */
27 #endif  /* lint */
28
29 /*                                                                      *
30  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
31  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
32  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
33  * (c) Copyright 1993, 1994 Novell, Inc.                                *
34  */
35
36 #include "TermHeader.h"
37 #include "TermPrimP.h"
38 #include "TermPrimDebug.h"
39 #include "TermPrimRenderP.h"
40 #include "TermPrimRenderLineDraw.h"
41 #include "TermPrimLineDrawP.h"
42
43 static void
44 LineDrawRenderFunction(
45     Widget                w,
46     TermFont              font,
47     Pixel                 fg,
48     Pixel                 bg,
49     unsigned long         flags,
50     int                   x,
51     int                   y,
52     unsigned char        *rawString,
53     int                   len
54 )
55 {
56     DtTermPrimitiveWidget tw = (DtTermPrimitiveWidget) w;
57     struct termData *tpd = tw->term.tpd;
58     XGCValues values;
59     unsigned long valueMask;
60     LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
61     unsigned char *string;
62
63     if (tpd->mbCurMax > 1) {
64         /* we have a string of wide chars that need to be converted to
65          * chars...
66          */
67         wchar_t                  *wPtr;
68         unsigned char            *ptr;
69         int                       i1;
70         unsigned char             mbChar[MB_LEN_MAX];
71
72         /* we will need to convert 2 column characters to 2 spaces in
73          * order to preserve character positions...
74          */
75         string = (unsigned char *) XtMalloc(2 * len);
76         for (ptr = string, wPtr = (wchar_t *) rawString, i1 = 0; i1 < len;
77                 i1++, wPtr++) {
78             switch (wcwidth(*wPtr)) {
79             case 1:
80                 if (wctomb((char *) mbChar, *wPtr) == 1) {
81                     *ptr++ = *mbChar;
82                 } else {
83                     *ptr++ = ' ';
84                 }
85                 break;
86
87             case 2:
88                 *ptr++ = ' ';
89                 *ptr++ = ' ';
90                 break;
91
92             default:
93                 *ptr++ = ' ';
94                 break;
95             }
96         }
97
98         len = ptr - string;
99     } else {
100         string = rawString;
101     }
102
103     /* set the renderGC... */
104     valueMask = (unsigned long) 0;
105
106     /* set the foreground... */
107     if (TermIS_SECURE(flags)) {
108         if (tpd->renderGC.foreground != bg) {
109             tpd->renderGC.foreground = bg;
110             values.foreground = bg;
111             valueMask |= GCForeground;
112         }
113     } else {
114         if (tpd->renderGC.foreground != fg) {
115             tpd->renderGC.foreground = fg;
116             values.foreground = fg;
117             valueMask |= GCForeground;
118         }
119     }
120
121     /* set background... */
122     if (tpd->renderGC.background != bg) {
123         tpd->renderGC.background = bg;
124         values.background = bg;
125         valueMask |= GCBackground;
126     }
127
128     if (valueMask) {
129         (void) XChangeGC(XtDisplay(w), tpd->renderGC.gc, valueMask,
130                 &values);
131     }
132
133     /* we need a clear GC as well...
134      */
135     valueMask = (unsigned long) 0;
136     if (tpd->renderReverseGC.foreground != bg) {
137         tpd->renderReverseGC.foreground = bg;
138         values.foreground = bg;
139         valueMask |= GCForeground;
140     }
141     if (valueMask) {
142         (void) XChangeGC(XtDisplay(w),
143                 tpd->renderReverseGC.gc, valueMask, &values);
144     }
145
146     /* line draw a line of text... */
147     if (isDebugFSet('t', 1)) {
148 #ifdef  BBA
149 #pragma BBA_IGNORE
150 #endif  /*BBA*/
151         /* Fill in the text area so we can see what is going to
152          * be displayed...
153          */
154         (void) XFillRectangle(XtDisplay(w),
155                 XtWindow(w),
156                 tpd->renderGC.gc,
157                 x,
158                 y,
159                 tpd->cellWidth * len,
160                 tpd->cellHeight);
161         (void) XSync(XtDisplay(w), False);
162         (void) shortSleep(100000);
163     }
164                         
165     (void) _DtTermPrimLineDrawImageString(
166             XtDisplay(w),                       /* Display              */
167             XtWindow(w),                        /* Drawable             */
168             lineDrawFont,                       /* LineDrawFont         */
169             tpd->renderGC.gc,                   /* GC                   */
170             tpd->renderReverseGC.gc,            /* clearGC              */
171             x,                                  /* x                    */
172             y + lineDrawFont->ascent,           /* y                    */
173             string,                             /* string               */
174             len);                               /* length               */
175
176     /* we don't support overstrike for line draw... */
177
178     /* handle the underline enhancement... */
179     /* draw the underline... */
180     if (TermIS_UNDERLINE(flags)) {
181         XDrawLine(XtDisplay(w),                 /* Display              */
182                 XtWindow(w),                    /* Window               */
183                 tpd->renderGC.gc,               /* GC                   */
184                 x,                              /* X1                   */
185                 y + tpd->cellHeight - 1,                /* Y1                   */
186                 x + len * tpd->cellWidth,       /* X2                   */
187                 y + tpd->cellHeight - 1);       /* Y2                   */
188     }
189
190     if (rawString != string) {
191         (void) XtFree((char *) string);
192     }
193 }
194
195 static void
196 LineDrawDestroyFunction(
197     Widget                w,
198     TermFont              font
199 )
200 {
201     LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
202
203     (void) _DtTermPrimLineDrawFreeFont(lineDrawFont);
204     (void) XtFree((char *) font);
205 }
206
207 static void
208 LineDrawExtentsFunction(
209     Widget                w,
210     TermFont              font,
211     unsigned char        *string,
212     int                   len,
213     int                  *widthReturn,
214     int                  *heightReturn,
215     int                  *ascentReturn
216 )
217 {
218     LineDrawFont lineDrawFont = (LineDrawFont) font->fontInfo;
219
220     if (widthReturn) {
221         *widthReturn = len * lineDrawFont->width;
222     }
223     if (heightReturn) {
224         *heightReturn = lineDrawFont->height;
225     }
226     if (ascentReturn) {
227         *ascentReturn = lineDrawFont->ascent;
228     }
229     return;
230 }
231
232 TermFont
233 _DtTermPrimRenderLineDrawCreate(
234     Widget                w,
235     GlyphInfo             glyphInfo,
236     int                   numGlyphs,
237     int                   width,
238     int                   ascent,
239     int                   descent
240 )
241 {
242     TermFont termFont;
243
244     termFont = (TermFont) XtMalloc(sizeof(TermFontRec));
245     termFont->renderFunction = LineDrawRenderFunction;
246     termFont->destroyFunction = LineDrawDestroyFunction;
247     termFont->extentsFunction = LineDrawExtentsFunction;
248     termFont->fontInfo =
249       (XtPointer)_DtTermPrimLineDrawCreateFont(w, glyphInfo, numGlyphs,
250                                                width, ascent, descent);
251     return(termFont);
252 }