]> git.lyx.org Git - lyx.git/blob - src/lyxdraw.C
fix some of the bugs reported, should hopefully be a bit better now.
[lyx.git] / src / lyxdraw.C
1 #include <config.h>
2
3 #include "lyxdraw.h"
4 #include "debug.h"
5
6 extern int reverse_video;
7 extern int mono_video;
8 extern char label_color[];
9 extern char math_color[];
10 extern char math_frame_color[];
11 extern char latex_color[];
12 extern char foot_color[];
13 extern char new_line_color[];
14 extern char fill_color[];
15 extern int fast_selection;
16 extern char on_off_line_color[];
17 extern string background_color;
18 extern char lighted_color[];
19 extern char selection_color[];
20 extern char note_color[];
21 extern char note_frame_color[];
22
23 Colormap color_map = 0;
24 long int background_pixels;
25
26 // X11 color names
27 char const * const X11Color[11] = 
28 { "black", "black", "white", "red", "green", "blue", "cyan", "magenta", 
29   "yellow", "black", "black" };
30  
31 // Different graphic contexts
32 static GC clear_gc = 0;
33 static GC latex_gc = 0;
34 static GC foot_gc = 0;
35 static GC new_line_gc = 0;
36 static GC math_gc = 0;
37 static GC math_frame_gc = 0;
38 static GC fill_gc = 0;
39 static GC note_gc = 0;
40 static GC note_frame_gc = 0;
41 static GC copy_gc = 0;
42 static GC select_gc = 0;
43 static GC on_off_line_gc = 0;
44 static GC thin_on_off_line_gc = 0;
45 static GC thick_line_gc = 0;
46 static GC lighted_gc = 0;
47 static GC selection_gc = 0;
48 static GC accent_gc[10] = { 0, 0, 0, 0, 0,
49                             0, 0, 0, 0, 0 };
50 static GC color_gc[11] = { 0, 0, 0, 0, 0, 0,
51                            0, 0, 0, 0, 0 };
52 static GC minipage_gc = 0;
53
54
55 // Allocates color and sets it as foreground
56 // Returns "false" if unsuccesful
57 bool setForegroundColor(char const * const color, XGCValues & val)
58 {
59         XColor xcol;
60         if (!color_map) {
61                 color_map = fl_state[fl_get_vclass()].colormap;
62         }
63         if (!mono_video) {
64                 if (XParseColor(fl_display, color_map, color, &xcol)
65                     && XAllocColor(fl_display, color_map, &xcol))
66                         {
67                                 val.foreground = xcol.pixel;
68                         } else {
69                                 lyxerr << "LyX: Couldn't get color "
70                                        << color << endl;
71                                 return false;
72                         }
73         }
74         return true;
75 }
76
77
78 static
79 void do_reverse_video(XGCValues &val)
80 {
81         if (reverse_video) {
82                 val.foreground= WhitePixel(fl_display,
83                                            DefaultScreen(fl_display));
84                 val.background= BlackPixel(fl_display,
85                                            DefaultScreen(fl_display));
86         } else {
87                 val.foreground= BlackPixel(fl_display,
88                                            DefaultScreen(fl_display));
89                 val.background= WhitePixel(fl_display,
90                                            DefaultScreen(fl_display));
91         }
92 }
93
94
95 static
96 GC make_normal_gc(const char* color)
97 {
98         XGCValues val;
99         do_reverse_video(val);
100         val.function = GXcopy;
101         val.graphics_exposures = false;
102         setForegroundColor(color, val);
103         return XCreateGC(fl_display, fl_root,
104                          GCBackground | GCForeground | GCFunction |
105                          GCGraphicsExposures, &val);
106 }
107
108
109 static
110 GC GetNoteGC()
111 {
112         if (note_gc) return note_gc;
113         
114         note_gc = make_normal_gc(note_color);
115
116         return note_gc;
117 }
118
119
120 static
121 GC GetNoteFrameGC()
122 {
123         if (note_frame_gc) return note_frame_gc;
124         
125         note_frame_gc = make_normal_gc(note_frame_color);
126
127         return note_frame_gc;
128 }
129
130
131 static
132 GC GetMathGC()
133 {
134         if (math_gc) return math_gc;
135         
136         math_gc = make_normal_gc(math_color);
137
138         return math_gc;
139 }
140
141
142 static
143 GC GetLatexGC()
144 {
145         if (latex_gc) return latex_gc;
146
147         XGCValues val;
148         if (reverse_video ^ mono_video) {
149                 val.foreground= WhitePixel(fl_display,
150                                            DefaultScreen(fl_display));
151                 val.background= BlackPixel(fl_display,
152                                            DefaultScreen(fl_display));
153         } else {
154                 val.foreground= BlackPixel(fl_display,
155                                            DefaultScreen(fl_display));
156                 val.background= WhitePixel(fl_display,
157                                            DefaultScreen(fl_display));
158         }
159         val.function= GXcopy;
160         val.graphics_exposures = false;
161         setForegroundColor(latex_color, val);
162         latex_gc = XCreateGC(fl_display, fl_root, GCBackground 
163                              | GCForeground | GCFunction
164                              | GCGraphicsExposures, 
165                              &val);
166         XFlush(fl_display);
167         
168         return latex_gc;
169 }
170
171
172 static
173 GC GetFootGC()
174 {
175         if (foot_gc) return foot_gc;
176         
177         foot_gc = make_normal_gc(foot_color);
178         
179         return foot_gc;
180 }
181
182
183 static
184 GC GetNewLineGC()
185 {
186         if (new_line_gc) return new_line_gc;
187  
188         new_line_gc = make_normal_gc(new_line_color);
189  
190         return new_line_gc;
191 }
192  
193  
194 static
195 GC GetMathFrameGC()
196 {
197         if (math_frame_gc) return math_frame_gc;
198         
199         math_frame_gc = make_normal_gc(math_frame_color);
200         
201         return math_frame_gc;
202 }
203
204
205 static
206 GC GetFillGC()
207 {
208         if (fill_gc) return fill_gc;
209         
210         fill_gc = make_normal_gc(fill_color);
211         
212         return fill_gc;
213 }
214
215
216 static
217 GC GetClearGC()
218 {
219         if (clear_gc) return clear_gc;
220         
221         XGCValues val;
222
223         if (reverse_video) {
224                 val.foreground= BlackPixel(fl_display,
225                                            DefaultScreen(fl_display));
226                 val.background= WhitePixel(fl_display,
227                                            DefaultScreen(fl_display));
228         } else {
229                 val.background= BlackPixel(fl_display,
230                                            DefaultScreen(fl_display));
231                 val.foreground= WhitePixel(fl_display,
232                                            DefaultScreen(fl_display));
233         }
234         val.function = GXcopy;
235         val.graphics_exposures = false;
236         if (!fast_selection && background_color != "white") {
237                 setForegroundColor(background_color.c_str(), val);
238         }
239         background_pixels = val.foreground;
240         
241         clear_gc = XCreateGC(fl_display, fl_root, GCBackground 
242                              | GCForeground | GCFunction
243                              | GCGraphicsExposures, 
244                              &val);
245         XFlush(fl_display);
246         
247         return clear_gc;
248 }
249
250
251 static
252 GC GetOnOffLineGC()
253 {
254         if (on_off_line_gc) return on_off_line_gc;
255         
256         XGCValues val;
257         do_reverse_video(val);
258
259         val.function= GXcopy;
260         val.graphics_exposures = false;
261         setForegroundColor(on_off_line_color, val);
262         val.line_width = 0;
263         val.line_style = LineOnOffDash;
264         on_off_line_gc = XCreateGC(fl_display, fl_root,
265                                    GCBackground | GCForeground | GCFunction |
266                                    GCGraphicsExposures | GCLineWidth |
267                                    GCLineStyle , &val);
268         XFlush(fl_display);
269
270         return on_off_line_gc;
271 }
272
273
274 static
275 GC GetThickLineGC()
276 {
277         if (thick_line_gc) return thick_line_gc;
278         XGCValues val;
279         do_reverse_video(val);
280
281         val.function= GXcopy;
282         val.graphics_exposures = false;
283         val.line_width = 2;
284         val.line_style = LineSolid;
285         thick_line_gc = XCreateGC(fl_display, fl_root, GCBackground 
286                                   | GCForeground | GCFunction
287                                   | GCGraphicsExposures
288                                   | GCLineWidth | GCLineStyle , &val);
289         XFlush(fl_display);
290         
291         return thick_line_gc;
292 }
293
294
295 static
296 GC GetThinOnOffLineGC()
297 {
298         if (thin_on_off_line_gc) return thin_on_off_line_gc;
299         XGCValues val;
300         do_reverse_video(val);
301
302         val.function= GXcopy;
303         val.graphics_exposures = false;
304         val.line_style = LineOnOffDash;
305         val.line_width = 0;
306         thin_on_off_line_gc = 
307                 XCreateGC(fl_display, fl_root, GCBackground
308                           | GCForeground | GCFunction | GCGraphicsExposures
309                           | GCLineWidth | GCLineStyle , &val);
310         XFlush(fl_display);
311         
312         return thin_on_off_line_gc;
313 }
314
315
316 static
317 GC GetCopyGC()
318 {
319         if (copy_gc) return copy_gc;
320         XGCValues val;
321         do_reverse_video(val);
322
323         val.function= GXcopy;
324         val.graphics_exposures = false;
325         val.line_style = LineSolid;
326         val.line_width = 0;
327         copy_gc = XCreateGC(fl_display, fl_root, GCBackground
328                             | GCForeground | GCFunction | GCGraphicsExposures
329                             | GCLineWidth | GCLineStyle , &val);
330         XFlush(fl_display);
331
332         return copy_gc;
333 }
334
335
336 static
337 GC GetSelectGC()
338 {
339         if (select_gc) return select_gc;
340         XGCValues val;
341         unsigned int a = BlackPixel(fl_display, DefaultScreen(fl_display));
342         unsigned int b = WhitePixel(fl_display, DefaultScreen(fl_display)); 
343         val.plane_mask = a^b;
344         val.line_style = LineSolid;
345         val.line_width = 2;
346         val.graphics_exposures = false;
347         val.function= GXinvert;
348         select_gc = XCreateGC(fl_display, fl_root,
349                               GCFunction | GCGraphicsExposures | GCPlaneMask
350                               | GCLineWidth | GCLineStyle , &val);
351         XFlush(fl_display);
352
353         return select_gc; 
354 }
355
356
357 static
358 GC GetSelectionGC()
359 {
360         if (selection_gc) return selection_gc;
361         
362         XGCValues val;
363
364         if (!reverse_video) {
365                 val.foreground= BlackPixel(fl_display,
366                                            DefaultScreen(fl_display));
367                 val.background= WhitePixel(fl_display,
368                                            DefaultScreen(fl_display));
369         } else {
370                 val.background= BlackPixel(fl_display,
371                                            DefaultScreen(fl_display));
372                 val.foreground= WhitePixel(fl_display,
373                                            DefaultScreen(fl_display));
374         }
375         val.function= GXcopy;
376         val.graphics_exposures = false;
377         if (!fast_selection && selection_color[0] != 0) {
378                 if (!setForegroundColor(selection_color, val)) {
379                         fast_selection = True;
380                         if (clear_gc) clear_gc = 0;
381                         lyxerr << "     Will use FastSelection-method."
382                                << endl;
383                 }
384         }
385         selection_gc = XCreateGC(fl_display, fl_root,
386                                  GCBackground | GCForeground | GCFunction
387                                  | GCGraphicsExposures, &val);
388
389         return selection_gc;
390 }
391
392
393 static
394 GC GetLightedGC()
395 {
396         if (lighted_gc) return lighted_gc;
397         XGCValues val;
398         if (reverse_video) {
399                 val.background= BlackPixel(fl_display,
400                                            DefaultScreen(fl_display));
401         } else {
402                 val.background= WhitePixel(fl_display,
403                                            DefaultScreen(fl_display));
404         }
405         val.foreground= val.background;
406         val.function= GXcopy;
407         val.graphics_exposures = false;
408         val.line_style = LineSolid;
409         val.line_width = 0;
410         setForegroundColor(lighted_color, val);
411         lighted_gc = XCreateGC(fl_display, fl_root, GCBackground
412                                | GCForeground | GCFunction
413                                | GCGraphicsExposures
414                                | GCLineWidth | GCLineStyle , &val);
415         XFlush(fl_display);
416
417         return lighted_gc;
418 }
419
420
421 GC GetColorGC(LyXFont::FONT_COLOR color)
422 {
423         if (color_gc[color]) return color_gc[color];
424                        
425         XGCValues val;
426         do_reverse_video(val);
427
428         val.function= GXcopy;
429         val.graphics_exposures = false;
430         setForegroundColor(X11Color[color], val);
431         val.line_width = 0;
432         val.line_style = LineSolid;
433         color_gc[color] = XCreateGC(fl_display, fl_root,
434                                     GCBackground | GCForeground | GCFunction |
435                                     GCGraphicsExposures | GCLineWidth |
436                                     GCLineStyle , &val);
437         XFlush(fl_display);
438
439         return color_gc[color];
440 }
441
442
443 GC GetAccentGC(LyXFont const &f, int line_width)
444 {
445         if (line_width >= 10) line_width = 9;
446         
447         if (accent_gc[line_width]) return accent_gc[line_width];
448         
449         // Build this one from normal text GC, but change linewidth.
450         XGCValues val;
451         GC gc = f.getGC();
452         XGetGCValues(fl_display, gc, GCBackground | GCForeground | 
453                      GCFunction | GCGraphicsExposures | GCLineWidth | 
454                      GCLineStyle | GCPlaneMask, &val);
455
456         val.line_width = line_width;
457         val.cap_style = CapRound;
458         val.join_style = JoinRound;
459         
460         GC ac = XCreateGC(fl_display, fl_root, 
461                           GCBackground | GCForeground | GCFunction | 
462                           GCGraphicsExposures | GCLineWidth | 
463                           GCLineStyle | GCPlaneMask, &val);
464         
465         XFlush(fl_display);
466         accent_gc[line_width] = ac;
467
468         return accent_gc[line_width];
469 }
470
471
472 static
473 GC GetMinipageGC()
474 {
475         if (minipage_gc) return minipage_gc;
476         XGCValues val;
477         do_reverse_video(val);
478
479         val.function= GXcopy;
480         val.graphics_exposures = false;
481         val.line_style = LineOnOffDash;
482         val.line_width = 0;
483         setForegroundColor(fill_color, val);
484         minipage_gc = XCreateGC(fl_display, fl_root,
485                                 GCBackground | GCForeground | GCFunction |
486                                 GCGraphicsExposures | GCLineWidth |
487                                 GCLineStyle , &val);
488         XFlush(fl_display);
489
490         return minipage_gc;
491 }
492
493
494 GC getGC(gc_type typ)
495 {
496         GC gc = 0;
497         switch(typ) {
498         case gc_clear:
499                 gc = GetClearGC();
500                 break;
501         case gc_latex:
502                 gc = GetLatexGC();
503                 break;
504         case gc_foot:
505                 gc = GetFootGC();
506                 break;
507         case gc_new_line:
508                 gc = GetNewLineGC();
509                 break;
510         case gc_math:
511                 gc = GetMathGC();
512                 break;
513         case gc_math_frame:
514                 gc = GetMathFrameGC();
515                 break;
516         case gc_fill:
517                 gc = GetFillGC();
518                 break;
519         case gc_copy:
520                 gc = GetCopyGC();
521                 break;
522         case gc_select:
523                 gc = GetSelectGC();
524                 break;
525         case gc_on_off_line:
526                 gc = GetOnOffLineGC();
527                 break;
528         case gc_thin_on_off_line:
529                 gc = GetThinOnOffLineGC();
530                 break;
531         case gc_thick_line:
532                 gc = GetThickLineGC();
533                 break;
534         case gc_lighted:
535                 gc = GetLightedGC();
536                 break;
537         case gc_selection:
538                 gc = GetSelectionGC();
539                 break;
540         case gc_minipage:
541                 gc = GetMinipageGC();
542                 break;
543         case gc_note:
544                 gc = GetNoteGC();
545                 break;
546         case gc_note_frame:
547                 gc = GetNoteFrameGC();
548                 break;
549         }
550         return gc;
551 }