]> git.saurik.com Git - wxWidgets.git/blob - utils/ogl/src/misc.cpp
spurious error messages from wxRegKey::HasValue() suppressed
[wxWidgets.git] / utils / ogl / src / misc.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: misc.cpp
3 // Purpose: Miscellaneous OGL support functions
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 12/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "misc.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include <wx/wxprec.h>
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include <wx/wx.h>
25 #endif
26
27 #ifdef PROLOGIO
28 #include <wx/wxexpr.h>
29 #endif
30
31 #include <wx/types.h>
32
33 #if USE_IOSTREAMH
34 #include <iostream.h>
35 #else
36 #include <iostream>
37 #endif
38 #include <ctype.h>
39 #include <math.h>
40 #include <stdlib.h>
41
42 #include "basic.h"
43 #include "basicp.h"
44 #include "misc.h"
45 #include "constrnt.h"
46 #include "composit.h"
47
48 wxFont *g_oglNormalFont;
49
50 wxPen *black_pen;
51 wxPen *white_background_pen;
52 wxPen *transparent_pen;
53 wxBrush *white_background_brush;
54 wxPen *black_foreground_pen;
55
56 char *GraphicsBuffer = NULL;
57 wxCursor *GraphicsBullseyeCursor = NULL;
58
59 wxList wxObjectCopyMapping(wxKEY_INTEGER);
60
61 void wxOGLInitialize()
62 {
63 GraphicsBullseyeCursor = new wxCursor(wxCURSOR_BULLSEYE);
64
65 g_oglNormalFont = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL);
66
67 black_pen = new wxPen("BLACK", 1, wxSOLID);
68
69 white_background_pen = new wxPen("WHITE", 1, wxSOLID);
70 transparent_pen = new wxPen("WHITE", 1, wxTRANSPARENT);
71 white_background_brush = new wxBrush("WHITE", wxSOLID);
72 black_foreground_pen = new wxPen("BLACK", 1, wxSOLID);
73
74 OGLInitializeConstraintTypes();
75
76 // Initialize big buffer used when writing images
77 GraphicsBuffer = new char[3000];
78
79 if (!oglPopupDivisionMenu)
80 {
81 oglPopupDivisionMenu = new wxMenu("", (wxFunction)oglGraphicsDivisionMenuProc);
82 oglPopupDivisionMenu->Append(DIVISION_MENU_SPLIT_HORIZONTALLY, "Split horizontally");
83 oglPopupDivisionMenu->Append(DIVISION_MENU_SPLIT_VERTICALLY, "Split vertically");
84 oglPopupDivisionMenu->AppendSeparator();
85 oglPopupDivisionMenu->Append(DIVISION_MENU_EDIT_LEFT_EDGE, "Edit left edge");
86 oglPopupDivisionMenu->Append(DIVISION_MENU_EDIT_TOP_EDGE, "Edit top edge");
87 }
88 }
89
90 void wxOGLCleanUp()
91 {
92 if (GraphicsBuffer)
93 {
94 delete[] GraphicsBuffer;
95 GraphicsBuffer = NULL;
96 }
97 GraphicsBuffer = NULL;
98 if (oglPopupDivisionMenu)
99 {
100 delete oglPopupDivisionMenu;
101 oglPopupDivisionMenu = NULL;
102 }
103 if (g_oglNormalFont)
104 {
105 delete g_oglNormalFont;
106 g_oglNormalFont = NULL;
107 }
108 if (black_pen)
109 {
110 delete black_pen;
111 black_pen = NULL;
112 }
113 if (white_background_pen)
114 {
115 delete white_background_pen;
116 white_background_pen = NULL;
117 }
118 if (transparent_pen)
119 {
120 delete transparent_pen;
121 transparent_pen = NULL;
122 }
123 if (white_background_brush)
124 {
125 delete white_background_brush;
126 white_background_brush = NULL;
127 }
128 if (black_foreground_pen)
129 {
130 delete black_foreground_pen;
131 black_foreground_pen = NULL;
132 }
133
134 OGLCleanUpConstraintTypes();
135 }
136
137 wxFont *MatchFont(int point_size)
138 {
139 wxFont *font = wxTheFontList->FindOrCreateFont(point_size, wxSWISS, wxNORMAL, wxNORMAL);
140 #if 0
141 switch (point_size)
142 {
143 case 4:
144 font = swiss_font_4;
145 break;
146 case 6:
147 font = swiss_font_6;
148 break;
149 case 8:
150 font = swiss_font_8;
151 break;
152 case 12:
153 font = swiss_font_12;
154 break;
155 case 14:
156 font = swiss_font_14;
157 break;
158 case 18:
159 font = swiss_font_18;
160 break;
161 case 24:
162 font = swiss_font_24;
163 break;
164 default:
165 case 10:
166 font = swiss_font_10;
167 break;
168 }
169 #endif
170 return font;
171 }
172
173 int FontSizeDialog(wxFrame *parent, int old_size)
174 {
175 if (old_size <= 0)
176 old_size = 10;
177 char buf[40];
178 sprintf(buf, "%d", old_size);
179 wxString ans = wxGetTextFromUser("Enter point size", "Font size", buf, parent);
180 if (ans == "")
181 return 0;
182
183 int new_size = atoi(ans);
184 if ((new_size <= 0) || (new_size > 40))
185 {
186 wxMessageBox("Invalid point size!", "Error", wxOK);
187 return 0;
188 }
189 return new_size;
190 /*
191 char *strings[8];
192 strings[0] = "4";
193 strings[1] = "6";
194 strings[2] = "8";
195 strings[3] = "10";
196 strings[4] = "12";
197 strings[5] = "14";
198 strings[6] = "18";
199 strings[7] = "24";
200 char *ans = wxGetSingleChoice("Choose", "Choose a font size", 8, strings, parent);
201 if (ans)
202 {
203 int size;
204 sscanf(ans, "%d", &size);
205 return MatchFont(size);
206 }
207 else return NULL;
208 */
209 }
210
211 // Centre a list of strings in the given box. xOffset and yOffset are the
212 // the positions that these lines should be relative to, and this might be
213 // the same as m_xpos, m_ypos, but might be zero if formatting from left-justifying.
214 void CentreText(wxDC& dc, wxList *text_list,
215 float m_xpos, float m_ypos, float width, float height,
216 int formatMode)
217 {
218 int n = text_list->Number();
219
220 if (!text_list || (n == 0))
221 return;
222
223 // First, get maximum dimensions of box enclosing text
224
225 float char_height = 0;
226 float max_width = 0;
227 float current_width = 0;
228
229 // Store text extents for speed
230 float *widths = new float[n];
231
232 wxNode *current = text_list->First();
233 int i = 0;
234 while (current)
235 {
236 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
237 dc.GetTextExtent(line->GetText(), &current_width, &char_height);
238 widths[i] = current_width;
239
240 if (current_width > max_width)
241 max_width = current_width;
242 current = current->Next();
243 i ++;
244 }
245
246 float max_height = n*char_height;
247
248 float xoffset, yoffset, xOffset, yOffset;
249
250 if (formatMode & FORMAT_CENTRE_VERT)
251 {
252 if (max_height < height)
253 yoffset = (float)(m_ypos - (height/2.0) + (height - max_height)/2.0);
254 else
255 yoffset = (float)(m_ypos - (height/2.0));
256 yOffset = m_ypos;
257 }
258 else
259 {
260 yoffset = 0.0;
261 yOffset = 0.0;
262 }
263
264 if (formatMode & FORMAT_CENTRE_HORIZ)
265 {
266 xoffset = (float)(m_xpos - width/2.0);
267 xOffset = m_xpos;
268 }
269 else
270 {
271 xoffset = 0.0;
272 xOffset = 0.0;
273 }
274
275 current = text_list->First();
276 i = 0;
277
278 while (current)
279 {
280 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
281
282 float x;
283 if ((formatMode & FORMAT_CENTRE_HORIZ) && (widths[i] < width))
284 x = (float)((width - widths[i])/2.0 + xoffset);
285 else
286 x = xoffset;
287 float y = (float)(i*char_height + yoffset);
288
289 line->SetX( x - xOffset ); line->SetY( y - yOffset );
290 current = current->Next();
291 i ++;
292 }
293
294 delete widths;
295 }
296
297 // Centre a list of strings in the given box
298 void CentreTextNoClipping(wxDC& dc, wxList *text_list,
299 float m_xpos, float m_ypos, float width, float height)
300 {
301 int n = text_list->Number();
302
303 if (!text_list || (n == 0))
304 return;
305
306 // First, get maximum dimensions of box enclosing text
307
308 float char_height = 0;
309 float max_width = 0;
310 float current_width = 0;
311
312 // Store text extents for speed
313 float *widths = new float[n];
314
315 wxNode *current = text_list->First();
316 int i = 0;
317 while (current)
318 {
319 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
320 dc.GetTextExtent(line->GetText(), &current_width, &char_height);
321 widths[i] = current_width;
322
323 if (current_width > max_width)
324 max_width = current_width;
325 current = current->Next();
326 i ++;
327 }
328
329 float max_height = n*char_height;
330
331 float yoffset = (float)(m_ypos - (height/2.0) + (height - max_height)/2.0);
332
333 float xoffset = (float)(m_xpos - width/2.0);
334
335 current = text_list->First();
336 i = 0;
337
338 while (current)
339 {
340 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
341
342 float x = (float)((width - widths[i])/2.0 + xoffset);
343 float y = (float)(i*char_height + yoffset);
344
345 line->SetX( x - m_xpos ); line->SetY( y - m_ypos );
346 current = current->Next();
347 i ++;
348 }
349 delete widths;
350 }
351
352 void GetCentredTextExtent(wxDC& dc, wxList *text_list,
353 float m_xpos, float m_ypos, float width, float height,
354 float *actual_width, float *actual_height)
355 {
356 int n = text_list->Number();
357
358 if (!text_list || (n == 0))
359 {
360 *actual_width = 0;
361 *actual_height = 0;
362 return;
363 }
364
365 // First, get maximum dimensions of box enclosing text
366
367 float char_height = 0;
368 float max_width = 0;
369 float current_width = 0;
370
371 wxNode *current = text_list->First();
372 int i = 0;
373 while (current)
374 {
375 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
376 dc.GetTextExtent(line->GetText(), &current_width, &char_height);
377
378 if (current_width > max_width)
379 max_width = current_width;
380 current = current->Next();
381 i ++;
382 }
383
384 *actual_height = n*char_height;
385 *actual_width = max_width;
386 }
387
388 // Format a string to a list of strings that fit in the given box.
389 // Interpret %n and 10 or 13 as a new line.
390 wxList *FormatText(wxDC& dc, const wxString& text, float width, float height, int formatMode)
391 {
392 // First, parse the string into a list of words
393 wxList word_list;
394
395 // Make new lines into NULL strings at this point
396 int i = 0; int j = 0; int len = strlen(text);
397 char word[200]; word[0] = 0;
398 bool end_word = FALSE; bool new_line = FALSE;
399 while (i < len)
400 {
401 switch (text[i])
402 {
403 case '%':
404 {
405 i ++;
406 if (i == len)
407 { word[j] = '%'; j ++; }
408 else
409 {
410 if (text[i] == 'n')
411 { new_line = TRUE; end_word = TRUE; i++; }
412 else
413 { word[j] = '%'; j ++; word[j] = text[i]; j ++; i ++; }
414 }
415 break;
416 }
417 case 10:
418 {
419 new_line = TRUE; end_word = TRUE; i++;
420 break;
421 }
422 case 13:
423 {
424 new_line = TRUE; end_word = TRUE; i++;
425 }
426 case ' ':
427 {
428 end_word = TRUE;
429 i ++;
430 break;
431 }
432 default:
433 {
434 word[j] = text[i];
435 j ++; i ++;
436 break;
437 }
438 }
439 if (i == len) end_word = TRUE;
440 if (end_word)
441 {
442 word[j] = 0;
443 j = 0;
444 word_list.Append((wxObject *)copystring(word));
445 end_word = FALSE;
446 }
447 if (new_line)
448 {
449 word_list.Append((wxObject *)NULL);
450 new_line = FALSE;
451 }
452 }
453 // Now, make a list of strings which can fit in the box
454 wxList *string_list = new wxList;
455
456 char buffer[400];
457 buffer[0] = 0;
458 wxNode *node = word_list.First();
459 float x, y;
460
461 while (node)
462 {
463 char *keep_string = copystring(buffer);
464
465 char *s = (char *)node->Data();
466 if (!s)
467 {
468 // FORCE NEW LINE
469 if (strlen(keep_string) > 0)
470 string_list->Append((wxObject *)keep_string);
471 else
472 delete[] keep_string;
473
474 buffer[0] = 0;
475 }
476 else
477 {
478 if (buffer[0] != 0)
479 strcat(buffer, " ");
480
481 strcat(buffer, s);
482 dc.GetTextExtent(buffer, &x, &y);
483
484 // Don't fit within the bounding box if we're fitting shape to contents
485 if ((x > width) && !(formatMode & FORMAT_SIZE_TO_CONTENTS))
486 {
487 // Deal with first word being wider than box
488 if (strlen(keep_string) > 0)
489 string_list->Append((wxObject *)keep_string);
490 else
491 delete[] keep_string;
492
493 buffer[0] = 0;
494 strcat(buffer, s);
495 delete[] s;
496 }
497 else
498 delete[] keep_string;
499 }
500
501 node = node->Next();
502 }
503 if (buffer[0] != 0)
504 string_list->Append((wxObject *)copystring(buffer));
505
506 return string_list;
507 }
508
509 void DrawFormattedText(wxDC& dc, wxList *text_list,
510 float m_xpos, float m_ypos, float width, float height,
511 int formatMode)
512 {
513 float xoffset, yoffset;
514 if (formatMode & FORMAT_CENTRE_HORIZ)
515 xoffset = m_xpos;
516 else
517 xoffset = (float)(m_xpos - (width / 2.0));
518
519 if (formatMode & FORMAT_CENTRE_VERT)
520 yoffset = m_ypos;
521 else
522 yoffset = (float)(m_ypos - (height / 2.0));
523
524 dc.SetClippingRegion(
525 (float)(m_xpos - width/2.0), (float)(m_ypos - height/2.0),
526 (float)width, (float)height);
527
528 wxNode *current = text_list->First();
529 while (current)
530 {
531 wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
532
533 dc.DrawText(line->GetText(), xoffset + line->GetX(), yoffset + line->GetY());
534 current = current->Next();
535 }
536
537 dc.DestroyClippingRegion();
538 }
539
540 /*
541 * Find centroid given list of points comprising polyline
542 *
543 */
544
545 void find_polyline_centroid(wxList *points, float *x, float *y)
546 {
547 float xcount = 0;
548 float ycount = 0;
549
550 wxNode *node = points->First();
551 while (node)
552 {
553 wxRealPoint *point = (wxRealPoint *)node->Data();
554 xcount += point->x;
555 ycount += point->y;
556 node = node->Next();
557 }
558
559 *x = (xcount/points->Number());
560 *y = (ycount/points->Number());
561 }
562
563 /*
564 * Check that (x1, y1) -> (x2, y2) hits (x3, y3) -> (x4, y4).
565 * If so, ratio1 gives the proportion along the first line
566 * that the intersection occurs (or something like that).
567 * Used by functions below.
568 *
569 */
570 void check_line_intersection(float x1, float y1, float x2, float y2,
571 float x3, float y3, float x4, float y4,
572 float *ratio1, float *ratio2)
573 {
574 float denominator_term = (y4 - y3)*(x2 - x1) - (y2 - y1)*(x4 - x3);
575 float numerator_term = (x3 - x1)*(y4 - y3) + (x4 - x3)*(y1 - y3);
576
577 float line_constant;
578 float length_ratio = 1.0;
579 float k_line = 1.0;
580
581 // Check for parallel lines
582 if ((denominator_term < 0.005) && (denominator_term > -0.005))
583 line_constant = -1.0;
584 else
585 line_constant = numerator_term/denominator_term;
586
587 // Check for intersection
588 if ((line_constant < 1.0) && (line_constant > 0.0))
589 {
590 // Now must check that other line hits
591 if (((y4 - y3) < 0.005) && ((y4 - y3) > -0.005))
592 k_line = ((x1 - x3) + line_constant*(x2 - x1))/(x4 - x3);
593 else
594 k_line = ((y1 - y3) + line_constant*(y2 - y1))/(y4 - y3);
595
596 if ((k_line >= 0.0) && (k_line < 1.0))
597 length_ratio = line_constant;
598 else
599 k_line = 1.0;
600 }
601 *ratio1 = length_ratio;
602 *ratio2 = k_line;
603 }
604
605 /*
606 * Find where (x1, y1) -> (x2, y2) hits one of the lines in xvec, yvec.
607 * (*x3, *y3) is the point where it hits.
608 *
609 */
610 void find_end_for_polyline(float n, float xvec[], float yvec[],
611 float x1, float y1, float x2, float y2, float *x3, float *y3)
612 {
613 int i;
614 float lastx = xvec[0];
615 float lasty = yvec[0];
616
617 float min_ratio = 1.0;
618 float line_ratio;
619 float other_ratio;
620
621 for (i = 1; i < n; i++)
622 {
623 check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],
624 &line_ratio, &other_ratio);
625 lastx = xvec[i];
626 lasty = yvec[i];
627
628 if (line_ratio < min_ratio)
629 min_ratio = line_ratio;
630 }
631
632 // Do last (implicit) line if last and first floats are not identical
633 if (!(xvec[0] == lastx && yvec[0] == lasty))
634 {
635 check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],
636 &line_ratio, &other_ratio);
637
638 if (line_ratio < min_ratio)
639 min_ratio = line_ratio;
640 }
641
642 *x3 = (x1 + (x2 - x1)*min_ratio);
643 *y3 = (y1 + (y2 - y1)*min_ratio);
644
645 }
646
647 /*
648 * Find where the line hits the box.
649 *
650 */
651
652 void find_end_for_box(float width, float height,
653 float x1, float y1, // Centre of box (possibly)
654 float x2, float y2, // other end of line
655 float *x3, float *y3) // End on box edge
656 {
657 float xvec[5];
658 float yvec[5];
659
660 xvec[0] = (float)(x1 - width/2.0);
661 yvec[0] = (float)(y1 - height/2.0);
662 xvec[1] = (float)(x1 - width/2.0);
663 yvec[1] = (float)(y1 + height/2.0);
664 xvec[2] = (float)(x1 + width/2.0);
665 yvec[2] = (float)(y1 + height/2.0);
666 xvec[3] = (float)(x1 + width/2.0);
667 yvec[3] = (float)(y1 - height/2.0);
668 xvec[4] = (float)(x1 - width/2.0);
669 yvec[4] = (float)(y1 - height/2.0);
670
671 find_end_for_polyline(5, xvec, yvec, x2, y2, x1, y1, x3, y3);
672 }
673
674 /*
675 * Find where the line hits the circle.
676 *
677 */
678
679 void find_end_for_circle(float radius,
680 float x1, float y1, // Centre of circle
681 float x2, float y2, // Other end of line
682 float *x3, float *y3)
683 {
684 float H = (float)sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
685
686 if (H == 0.0)
687 {
688 *x3 = x1;
689 *y3 = y1;
690 }
691 else
692 {
693 *y3 = radius * (y2 - y1)/H + y1;
694 *x3 = radius * (x2 - x1)/H + x1;
695 }
696 }
697
698 /*
699 * Given the line (x1, y1) -> (x2, y2), and an arrow size of given length and width,
700 * return the position of the tip of the arrow and the left and right vertices of the arrow.
701 *
702 */
703
704 void get_arrow_points(float x1, float y1, float x2, float y2,
705 float length, float width,
706 float *tip_x, float *tip_y,
707 float *side1_x, float *side1_y,
708 float *side2_x, float *side2_y)
709 {
710 float l = (float)sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
711
712 if (l < 0.01)
713 l = (float) 0.01;
714
715 float i_bar = (x2 - x1)/l;
716 float j_bar = (y2 - y1)/l;
717
718 float x3 = (- length*i_bar) + x2;
719 float y3 = (- length*j_bar) + y2;
720
721 *side1_x = width*(-j_bar) + x3;
722 *side1_y = width*i_bar + y3;
723
724 *side2_x = -width*(-j_bar) + x3;
725 *side2_y = -width*i_bar + y3;
726
727 *tip_x = x2; *tip_y = y2;
728 }
729
730 /*
731 * Given an ellipse and endpoints of a line, returns the point at which
732 * the line touches the ellipse in values x4, y4.
733 * This function assumes that the centre of the ellipse is at x1, y1, and the
734 * ellipse has a width of width1 and a height of height1. It also assumes you are
735 * wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3.
736 * This function calculates the x,y coordinates of the intersection point of
737 * the arc with the ellipse.
738 * Author: Ian Harrison
739 */
740
741 void draw_arc_to_ellipse(float x1, float y1, float width1, float height1, float x2, float y2, float x3, float y3,
742 float *x4, float *y4)
743 {
744 float a1 = (float)(width1/2.0);
745 float b1 = (float)(height1/2.0);
746
747 // These are required to give top left x and y coordinates for DrawEllipse
748 // float top_left_x1 = (float)(x1 - a1);
749 // float top_left_y1 = (float)(y1 - b1);
750 /*
751 // Check for vertical line
752 if (fabs(x2 - x3) < 0.05)
753 {
754 *x4 = x3;
755 if (y2 < y3)
756 *y4 = (float)(y1 - b1);
757 else
758 *y4 = (float)(y1 + b1);
759 return;
760 }
761 */
762 // Check that x2 != x3
763 if (fabs(x2 - x3) < 0.05)
764 {
765 *x4 = x2;
766 if (y3 > y2)
767 *y4 = (float)(y1 - sqrt((b1*b1 - (((x2-x1)*(x2-x1))*(b1*b1)/(a1*a1)))));
768 else
769 *y4 = (float)(y1 + sqrt((b1*b1 - (((x2-x1)*(x2-x1))*(b1*b1)/(a1*a1)))));
770 return;
771 }
772
773 // Calculate the x and y coordinates of the point where arc intersects ellipse
774
775 float A, B, C, D, E, F, G, H, K;
776 float ellipse1_x, ellipse1_y;
777
778 A = (float)(1/(a1 * a1));
779 B = (float)((y3 - y2) * (y3 - y2)) / ((x3 - x2) * (x3 - x2) * b1 * b1);
780 C = (float)(2 * (y3 - y2) * (y2 - y1)) / ((x3 - x2) * b1 * b1);
781 D = (float)((y2 - y1) * (y2 - y1)) / (b1 * b1);
782 E = (float)(A + B);
783 F = (float)(C - (2 * A * x1) - (2 * B * x2));
784 G = (float)((A * x1 * x1) + (B * x2 * x2) - (C * x2) + D - 1);
785 H = (float)((y3 - y2) / (x3 - x2));
786 K = (float)((F * F) - (4 * E * G));
787
788 if (K >= 0)
789 // In this case the line intersects the ellipse, so calculate intersection
790 {
791 if(x2 >= x1)
792 {
793 ellipse1_x = (float)(((F * -1) + sqrt(K)) / (2 * E));
794 ellipse1_y = (float)((H * (ellipse1_x - x2)) + y2);
795 }
796 else
797 {
798 ellipse1_x = (float)(((F * -1) - sqrt(K)) / (2 * E));
799 ellipse1_y = (float)((H * (ellipse1_x - x2)) + y2);
800 }
801 }
802 else
803 // in this case, arc does not intersect ellipse, so just draw arc
804 {
805 ellipse1_x = x3;
806 ellipse1_y = y3;
807 }
808 *x4 = ellipse1_x;
809 *y4 = ellipse1_y;
810
811 /*
812 // Draw a little circle (radius = 2) at the end of the arc where it hits
813 // the ellipse .
814
815 float circle_x = ellipse1_x - 2.0;
816 float circle_y = ellipse1_y - 2.0;
817 m_canvas->DrawEllipse(circle_x, circle_y, 4.0, 4.0);
818 */
819 }
820
821 // Update a list item from a list of strings
822 void UpdateListBox(wxListBox *item, wxList *list)
823 {
824 item->Clear();
825 if (!list)
826 return;
827
828 wxNode *node = list->First();
829 while (node)
830 {
831 char *s = (char *)node->Data();
832 item->Append(s);
833 node = node->Next();
834 }
835 }
836
837 /*
838 * Hex<->Dec conversion
839 */
840
841 // Array used in DecToHex conversion routine.
842 static char sg_HexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
843 'C', 'D', 'E', 'F' };
844
845 // Convert 2-digit hex number to decimal
846 unsigned int oglHexToDec(char* buf)
847 {
848 int firstDigit, secondDigit;
849
850 if (buf[0] >= 'A')
851 firstDigit = buf[0] - 'A' + 10;
852 else
853 firstDigit = buf[0] - '0';
854
855 if (buf[1] >= 'A')
856 secondDigit = buf[1] - 'A' + 10;
857 else
858 secondDigit = buf[1] - '0';
859
860 return firstDigit * 16 + secondDigit;
861 }
862
863 // Convert decimal integer to 2-character hex string
864 void oglDecToHex(unsigned int dec, char *buf)
865 {
866 int firstDigit = (int)(dec/16.0);
867 int secondDigit = (int)(dec - (firstDigit*16.0));
868 buf[0] = sg_HexArray[firstDigit];
869 buf[1] = sg_HexArray[secondDigit];
870 buf[2] = 0;
871 }
872
873 // 3-digit hex to wxColour
874 wxColour oglHexToColour(const wxString& hex)
875 {
876 if (hex.Length() == 6)
877 {
878 char buf[7];
879 strncpy(buf, hex, 7);
880 unsigned int r = oglHexToDec((char *)buf);
881 unsigned int g = oglHexToDec((char *)(buf+2));
882 unsigned int b = oglHexToDec((char *)(buf+4));
883 return wxColour(r, g, b);
884 }
885 else
886 return wxColour(0,0,0);
887 }
888
889 // RGB to 3-digit hex
890 wxString oglColourToHex(const wxColour& colour)
891 {
892 char buf[7];
893 unsigned int red = colour.Red();
894 unsigned int green = colour.Green();
895 unsigned int blue = colour.Blue();
896
897 oglDecToHex(red, buf);
898 oglDecToHex(green, buf+2);
899 oglDecToHex(blue, buf+4);
900
901 return wxString(buf);
902 }
903
904