Initial commit of pristine erwise source
[erwise] / Xl / XlUtil.c
1 /*
2  * XlUtil.c --
3  *
4  * Author: Teemu Rantanen <tvr@cs.hut.fi>
5  * Copyright (c) 1992 Teemu Rantanen
6  *                    All rights reserved
7  *
8  * Created: Tue Mar  3 02:55:55 1992 tvr
9  * Last modified: Mon May 11 00:16:48 1992 tvr
10  *
11  */
12
13
14 #include <stdio.h>
15 #include <sys/types.h>
16
17 #include <X11/Xlib.h>
18
19 #include "HTAnchor.h"
20 #include "HTStyle.h"
21 #include "../HText/HText.h"
22
23 #include "XlStyle.h"
24 #include "XlFormatText.h"
25 #include "XlTypes.h"
26
27 /*
28  *  Does nothing but updates htext-object positions. This has to be
29  *  used after text is reformatted (on window size change).
30  */
31 void XlSetPageCoordinates(virtualx, virtualy, htext)
32 int virtualx, virtualy;
33 HText_t *htext;
34 {
35     htext->xl_global->x = virtualx;
36     htext->xl_global->y = virtualy;
37 }
38
39
40 /*
41  *  Get HTextObject position (virtual position of screen area to display)
42  */
43 void XlGetCoordinates(virtualx, virtualy, htextobject)
44 int *virtualx, *virtualy;
45 HTextObject_t *htextobject;
46 {
47     if (!htextobject)
48         return;
49
50     *virtualx = htextobject->x;
51     *virtualy = htextobject->y;
52 }
53
54
55 /*
56  * Can this object be cursor?
57  */
58 int xl_can_be_cursor(htextobject)
59 HTextObject_t *htextobject;
60 {
61     int i;
62
63     if (htextobject->paragraph)
64         return FALSE;
65
66     for (i = 0; i < htextobject->length; i++)
67         if (htextobject->data[i] != ' ')
68             return TRUE;
69
70     return FALSE;
71 }
72
73
74 /*
75  *  Get pointer to hypertextobject nearest to chosen coordinates
76  */
77 HTextObject_t *
78  XlLocateHTextObject(windowx, windowy, htext)
79 int windowx, windowy;
80 HText_t *htext;
81 {
82     HTextObject_t *p;
83     HTextObject_t *p_closest = NULL;
84
85     int virtualx;
86     int virtualy;
87     int distance;
88
89     virtualx = windowx + htext->xl_global->x;
90     virtualy = windowy + htext->xl_global->y;
91
92     for (p = htext->first; p; p = p->next) {
93         int i = xl_object_on_region(htext, p, windowx, windowy, 0, 0);
94
95         if (xl_can_be_cursor(p)) {
96             if (!i) {
97                 /*
98                  * Point inside object ?
99                  */
100                 p_closest = p;
101                 p = htext->last;
102
103             } else {
104                 /*
105                  * Is this object closest ?
106                  */
107                 if (!p_closest) {
108                     p_closest = p;
109
110                     distance = i;
111                 } else if (i < distance) {
112                     distance = i;
113
114                     p_closest = p;
115                 }
116             }
117         }
118     }
119
120 #ifdef XL_DEBUG
121     if (p_closest) {
122         printf("XlLocateHTextObject(%d, %d) -> (%d, %d) tag %s object '%s'\n",
123                windowx, windowy,
124                p_closest->x, p_closest->y,
125                p_closest->xl_data->style->styletags,
126                p_closest ? p_closest->data : "");
127     }
128 #endif
129     return p_closest;
130 }
131
132 /*
133  * Delete all Xl data from a page. Free all data allocated on Xl-library.
134  */
135 void XlDeleteText(htext)
136 HText_t *htext;
137 {
138     int i;
139
140     /*
141      * Free X11 resources
142      */
143     for (i = 0; i < htext->xl_global->nr_gcs; i++) {
144         XFreeGC(htext->xl_global->dpy, htext->xl_global->gcs[i]);
145         XFreeFont(htext->xl_global->dpy,
146                   htext->xl_global->XlStyles[i].fontinfo);
147     }
148
149     XFreeGC(htext->xl_global->dpy, htext->xl_global->xorgc);
150
151     /*
152      * Free data allocated here
153      */
154
155     {
156         HTextObject_t *p;
157
158         p = htext->first;
159
160         while (p) {
161             free(p->xl_data);
162
163             p = p->next;
164         }
165     }
166
167     free(htext->xl_global->XlStyles);
168
169     free(htext->xl_global->gcs);
170
171     free(htext->xl_global);
172 }
173
174
175 /*
176  * What is the length of this without spaces
177  */
178 int xl_nospacelength(p, data, len)
179 HTextObject_t *p;
180 char *data;
181 int len;
182 {
183     if (xl_object_mode(p) & STYLE_RAW) {
184
185         return len;
186     } else {
187
188         int i;
189
190         for (i = 0; (i < len) && (*data++ != ' '); i++);
191
192         return i;
193     }
194 }
195
196
197 /*
198  * Set up stuff needed to format text intelligently
199  */
200 void XlFormatTextForPrinting(htext, lmargin, rmargin)
201 HText_t *htext;
202 int lmargin;
203 int rmargin;
204 {
205     HTextObject_t *p;
206     int i, struct_len;
207     XlStyle_t *loop = XlStyles;
208     int junk1;
209     int junk2;
210
211     if (!htext)
212         return;
213
214     /*
215      * Set up format info
216      */
217
218     i = 1;
219
220     while (loop->fontname) {
221
222         loop++;
223
224         i++;
225     }
226
227     struct_len = sizeof(XlStyle_t) * i;
228
229     loop = (XlStyle_t *) malloc(struct_len);
230
231     htext->xl_global = (XlGlobalData_t *) malloc(sizeof(XlGlobalData_t));
232
233     htext->xl_global->XlStyles = loop;
234
235     memcpy(loop, XlStyles, struct_len);
236
237     while (--i) {
238
239         loop->char_width = 1;
240
241         loop++;
242     }
243
244     /*
245      * Set up length and width
246      */
247     p = htext->first;
248
249     while (p) {
250         HTStyle *st = NULL;
251
252         XlStyle_t *current;
253
254         p->height = 1;
255
256         if (!st || (st != p->style)) {
257
258             current = (XlStyle_t *) xl_get_style_and_gc(p, NULL, htext);
259
260             st = p->style;
261         }
262         p->xl_data = (XlObjectData_t *) malloc(sizeof(XlObjectData_t));
263
264         p->xl_data->style = current;
265
266         p->width = xl_nospacelength(p, p->data, p->length);
267
268         p = p->next;
269     }
270
271     XlFormatText(lmargin, rmargin - lmargin, 0, &junk1, &junk2, htext);
272
273     /*
274      * Free local stuff
275      */
276
277     p = htext->first;
278
279     while (p) {
280
281         free(p->xl_data);
282
283         p = p->next;
284     }
285
286     free(loop);
287
288     free(htext->xl_global);
289 }