1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16
17 #include "opennurbs.h"
18
19 // {EA2EFFD2-C9A9-4cb1-BE15-D2F46290F1A1}
20 //const ON_UUID ON_MaterialRef::material_from_layer =
21 //{ 0xea2effd2, 0xc9a9, 0x4cb1, { 0xbe, 0x15, 0xd2, 0xf4, 0x62, 0x90, 0xf1, 0xa1 } };
22
23
24
25 // {86EDFDE4-8AAF-4bcd-AB7C-F7111978D7FE}
26 //const ON_UUID ON_MaterialRef::material_from_parent =
27 //{ 0x86edfde4, 0x8aaf, 0x4bcd, { 0xab, 0x7c, 0xf7, 0x11, 0x19, 0x78, 0xd7, 0xfe } };
28
29
30 // on_stricmp() is a wrapper for case insensitive string compare
31 // and calls one of _stricmp(), stricmp(), or strcasecmp()
32 // depending on OS.
on_stricmp(const char * s1,const char * s2)33 int on_stricmp(const char * s1, const char * s2)
34 {
35 #if defined(ON_OS_WINDOWS)
36 //return stricmp(s1,s2);
37 return _stricmp(s1,s2);
38 #else
39 return strcasecmp(s1,s2);
40 #endif
41 }
42
43 // on_strupr() calls _strupr() or strupr() depending on OS
on_strupr(char * s)44 char* on_strupr(char* s)
45 {
46 #if defined(ON_OS_WINDOWS)
47 return _strupr(s); // ANSI name
48 #else
49 if (s) {
50 while (*s) {
51 *s = toupper(*s);
52 s++;
53 }
54 }
55 return s;
56 #endif
57 }
58
59 // on_strlwr() calls _strlwr() or strlwr() depending on OS
on_strlwr(char * s)60 char* on_strlwr(char* s)
61 {
62 #if defined(ON_OS_WINDOWS)
63 return _strlwr(s); // ANSI name
64 #else
65 if (s) {
66 while (*s) {
67 *s = tolower(*s);
68 s++;
69 }
70 }
71 return s;
72 #endif
73 }
74
75 // on_strrev() calls _strrev() or strrev() depending on OS
on_strrev(char * s)76 char* on_strrev(char* s)
77 {
78 #if defined(ON_OS_WINDOWS)
79 return _strrev(s); // ANSI name
80 #else
81 int i, j;
82 char c;
83 for ( i = 0, j = ((int)strlen(s))-1; i < j; i++, j-- ) {
84 c = s[i];
85 s[i] = s[j];
86 s[j] = c;
87 }
88 return s;
89 #endif
90 }
91
92 // Windows code page support
93 // Only ON_SetStringConversionWindowsLocaleID,
94 // ON_GetStringConversionWindowsLocaleID, and
95 // on_wcsicmp should look at g_s__windows_locale_id
96 // and g_s__windows_locale_os.
97 static unsigned int g_s__windows_locale_id = 0;
98 static unsigned int g_s__windows_locale_os = 0; // 0 = Win 95/98/ME...
99 // 1 = Win NT/2000/XP...
100
ON_SetStringConversionWindowsLocaleID(unsigned int locale_id,ON_BOOL32 bWin9X)101 unsigned int ON_SetStringConversionWindowsLocaleID(unsigned int locale_id, ON_BOOL32 bWin9X)
102 {
103 unsigned int rc = g_s__windows_locale_id;
104 g_s__windows_locale_os = bWin9X ? 0 : 1;
105 g_s__windows_locale_id = locale_id?true:false;
106 return rc;
107 }
108
ON_GetStringConversionWindowsLocaleID()109 unsigned int ON_GetStringConversionWindowsLocaleID()
110 {
111 return g_s__windows_locale_id;
112 }
113
114
on__hack__tolower(int c)115 static int on__hack__tolower(int c)
116 {
117 // This tolower is a simple "hack" to provide something that
118 // sort of works when OpenNURBS is used with a compiler that
119 // fails to provide functional localization tools.
120
121
122 // TODO:
123 // Expand these switch statments as users provide support
124 // for symbols. This is not the correct way to solve this
125 // problem, but it will work in some simple cases.
126 // If you are using Microsoft Developer studio in Windows,
127 // then this code is never called.
128 //
129 // Before you get too carried away, study
130 //
131 // http://www.microsoft.com/globaldev/wrguide/WRG_sort.asp
132 //
133 // and make sure what you are attempting to do is worth the
134 // trouble. In short, this approach is doomed to fail
135 // and is not good enough for robust applications that want
136 // to work well with most languages.
137 //
138 // That said, please post your additions to the OpenNURBS
139 // newsgroup so they can be included in future
140 // distrubutions.
141
142 int i;
143 if ( c <= 0 )
144 {
145 i = c;
146 }
147 else if ( c <= 127 )
148 {
149 // ASCII character
150 i = tolower(c);
151 }
152 else if ( c <= 255 )
153 {
154 // "extended" ASCII character
155 switch(c)
156 {
157 case 192: // UNICODE Latin capital letter A with grave (A`)
158 i = 224; // UNICODE Latin small letter A with grave (a`)
159 break;
160
161 case 193: // UNICODE Latin capital letter A with acute (A')
162 i = 225; // UNICODE Latin small letter A with acute (a')
163 break;
164
165 case 194: // UNICODE Latin capital letter A with circumflex (A^)
166 i = 226; // UNICODE Latin small letter A with circumflex (a^)
167 break;
168
169 case 195: // UNICODE Latin capital letter A with tilde (A~)
170 i = 227; // UNICODE Latin small letter A with tilde (a~)
171 break;
172
173 case 196: // UNICODE Latin capital letter A with diaeresis (A")
174 i = 228; // UNICODE Latin small letter A with diaeresis (a")
175 break;
176
177 case 197: // UNICODE Latin capital letter A with ring above (A ring above)
178 i = 229; // UNICODE Latin small letter A with ring above (a ring above)
179 break;
180
181 case 198: // UNICODE Latin capital letter Ae
182 i = 230; // UNICODE Latin small letter Ae
183 break;
184
185 case 199: // UNICODE Latin capital letter C with cedilla (C,)
186 i = 231; // UNICODE Latin small letter C with cedilla (c,)
187 break;
188
189 case 200: // UNICODE Latin capital letter E with grave (E`)
190 i = 232; // UNICODE Latin small letter E with grave (e`)
191 break;
192
193 case 201: // UNICODE Latin capital letter E with acute (E')
194 i = 233; // UNICODE Latin small letter E with acute (e')
195 break;
196
197 case 202: // UNICODE Latin capital letter E with circumflex (E^)
198 i = 234; // UNICODE Latin small letter E with circumflex (e^)
199 break;
200
201 case 203: // UNICODE Latin capital letter E with diaeresis (E")
202 i = 235; // UNICODE Latin small letter E with diaeresis (e")
203 break;
204
205 case 204: // UNICODE Latin capital letter I with grave (I`)
206 i = 236; // UNICODE Latin small letter I with grave (i`)
207 break;
208
209 case 205: // UNICODE Latin capital letter I with acute (I')
210 i = 237; // UNICODE Latin small letter I with acute (i')
211 break;
212
213 case 206: // UNICODE Latin capital letter I with circumflex (I^)
214 i = 238; // UNICODE Latin small letter I with circumflex (i^)
215 break;
216
217 case 207: // UNICODE Latin capital letter I with diaeresis (I")
218 i = 239; // UNICODE Latin small letter I with diaeresis (i")
219 break;
220
221 case 208: // UNICODE Latin capital letter Eth (ED)
222 i = 240; // UNICODE Latin small letter Eth (ed)
223 break;
224
225 case 209: // UNICODE Latin capital letter N with tilde (N~)
226 i = 241; // UNICODE Latin small letter n with tilde (n~)
227 break;
228
229 case 210: // UNICODE Latin capital letter O with grave (O`)
230 i = 242; // UNICODE Latin small letter O with grave (o`)
231 break;
232
233 case 211: // UNICODE Latin capital letter O with acute (O')
234 i = 243; // UNICODE Latin small letter O with acute (o')
235 break;
236
237 case 212: // UNICODE Latin capital letter O with circumflex (O^)
238 i = 244; // UNICODE Latin small letter O with circumflex (o^)
239 break;
240
241 case 213: // UNICODE Latin capital letter O with tilde (O~)
242 i = 245; // UNICODE Latin small letter O with tilde (o~)
243 break;
244
245 case 214: // UNICODE Latin capital letter O with diaeresis (O")
246 i = 246; // UNICODE Latin small letter O with diaeresis (o")
247 break;
248
249 case 216: // UNICODE Latin capital letter O with stroke (O/)
250 i = 248; // UNICODE Latin small letter O with stroke (o/)
251 break;
252
253 case 217: // UNICODE Latin capital letter U with grave (U`)
254 i = 249; // UNICODE Latin small letter U with grave (u`)
255 break;
256
257 case 218: // UNICODE Latin capital letter U with acute (U')
258 i = 250; // UNICODE Latin small letter U with acute (u')
259 break;
260
261 case 219: // UNICODE Latin capital letter U with circumflex (U^)
262 i = 251; // UNICODE Latin small letter U with circumflex (u^)
263 break;
264
265 case 220: // UNICODE Latin capital letter U with diaeresis (U")
266 i = 252; // UNICODE Latin small letter U with diaeresis (u")
267 break;
268
269 case 221: // UNICODE Latin capital letter Y with acute (Y')
270 i = 253; // UNICODE Latin small letter Y with acute (y')
271 break;
272
273 case 222: // UNICODE Latin capital letter Thorn (P|)
274 i = 254; // UNICODE Latin small letter Thorn (p|)
275 break;
276
277 default:
278 i = c;
279 break;
280 }
281 }
282 else if ( c <= 0x0177 )
283 {
284 if ( 0 == (c % 2) )
285 i = c+1;
286 else
287 i = c;
288 }
289 else if ( c <= 0x0192 )
290 {
291 switch( c)
292 {
293 case 0x0178: // UNICODE Latin capital letter Y with diaeresis (Y")
294 i = 0x00FF; // UNICODE Latin small letter Y with diaeresis (y")
295 break;
296
297 case 0x0179: // UNICODE Latin capital letter Z with acute (Z')
298 i = 0x017A; // UNICODE Latin small letter Z with acute (z')
299 break;
300
301 case 0x017B: // UNICODE Latin capital letter Z with dot above
302 i = 0x017C; // UNICODE Latin small letter Z with dot above
303 break;
304
305 case 0x017D: // UNICODE Latin capital letter Z with caron
306 i = 0x017E; // UNICODE Latin small letter Z with caron
307 break;
308
309 case 0x018F: // UNICODE Latin capital letter Schwa
310 i = 0x0259; // UNICODE Latin small letter Schwa
311 break;
312
313 default:
314 i = c;
315 break;
316 }
317 }
318 else if ( c <= 0x01FF )
319 {
320 if ( 0 == (c % 2) )
321 i = c+1;
322 else
323 i = c;
324 }
325 else
326 {
327 // My apologies to those of you whose languages use these symbols.
328 // I am too ignorant to make good guesses at what to do here.
329 // Please fill in as needed and post your changes so I can include
330 // them in future versions of OpenNURBS.
331 switch (c)
332 {
333 // example
334 case 0x0391: // UNICODE Greek capital letter alpha
335 i = 0x03B1; // UNICODE Greek small letter alpha
336 break;
337
338 default:
339 i = c;
340 }
341 }
342
343 return i;
344 }
345
346 static
on__hack__wcsicmp(const wchar_t * s1,const wchar_t * s2)347 int on__hack__wcsicmp( const wchar_t* s1, const wchar_t* s2)
348 {
349 // This "hack" case insensitive wchar_t compare tool is used
350 // when OpenNURBS is compiled in a development environment
351 // that does not provide proper localization support.
352
353 // handle NULL strings consistently and without crashing.
354 if ( !s1 )
355 {
356 return s2 ? -1 : 0;
357 }
358 else if ( !s2 )
359 {
360 return 1;
361 }
362
363 int rc, c1, c2;
364
365 do
366 {
367 c1 = on__hack__tolower(*s1++);
368 c2 = on__hack__tolower(*s2++);
369 rc = c1-c2;
370 }
371 while( 0 == rc && c1 && c2 );
372
373 return rc;
374 }
375
376 #if defined(ON_COMPILER_MSC)
377 // Disable the MSC /W4 unreachable code warning for the call to on__hack__wcsicmp()
378 #pragma warning( push )
379 #pragma warning( disable : 4702 )
380 #endif
381
on_wcsicmp(const wchar_t * s1,const wchar_t * s2)382 int on_wcsicmp( const wchar_t* s1, const wchar_t* s2)
383 {
384 // handle NULL strings consistently and without crashing.
385 if ( !s1 )
386 {
387 return s2 ? -1 : 0;
388 }
389 else if ( !s2 )
390 {
391 return 1;
392 }
393
394 #if defined(ON_OS_WINDOWS)
395
396 #if defined(ON_COMPILER_BORLAND)
397 // Borland's compiler / C library
398 return wcscmpi(s1,s2);
399 #else
400 // Microsoft compiler
401
402 if ( 0 != g_s__windows_locale_id )
403 {
404 if ( 0 == g_s__windows_locale_os )
405 {
406 // On Win 95/98/ME, CompareStringW() doesn't work
407 // and CompareStringA() is glacial. So we test
408 // strings and use wcsicmp() whenever it will return
409 // the right answer.
410 {
411 const wchar_t* c1 = s1;
412 const wchar_t* c2 = s2;
413 while ( *c1 > 0 && *c1 < 128 && *c2 > 0 && *c2 < 128 )
414 {
415 c1++;
416 c2++;
417 }
418 if ( 0 == *c1 || 0 == *c2 )
419 {
420 #if defined(ON_COMPILER_MSC1400)
421 return _wcsicmp(s1,s2);
422 #else
423 return wcsicmp(s1,s2);
424 #endif
425 }
426 }
427
428 // These convert UNICODE to wide character strings
429 ON_String a(s1);
430 ON_String b(s2);
431
432 // Wide char conversion
433 int rc = ::CompareStringA(g_s__windows_locale_id,
434 NORM_IGNORECASE | NORM_IGNOREWIDTH,
435 a.Array(),
436 -1,
437 b.Array(),
438 -1);
439 if (rc == CSTR_LESS_THAN)
440 return -1;
441 if (rc == CSTR_EQUAL)
442 return 0;
443 if (rc == CSTR_GREATER_THAN)
444 return 1;
445 }
446 else
447 {
448 // a version of Windows with working UNICODE support
449 int rc = ::CompareStringW(g_s__windows_locale_id,
450 NORM_IGNORECASE | NORM_IGNOREWIDTH,
451 s1,
452 -1,
453 s2,
454 -1);
455
456 if (rc == CSTR_LESS_THAN)
457 return -1;
458 if (rc == CSTR_EQUAL)
459 return 0;
460 if (rc == CSTR_GREATER_THAN)
461 return 1;
462 }
463 }
464
465 // Microsoft's wcsicmp() doesn't work right for
466 // upper/lower case accented latin characters,
467 // upper/lower case cyrillic, upper/lower case Greek,
468 // Asian characters, etc.
469 //
470 // Basically, if the character code >= 127 or you are
471 // using a language other than US english, then
472 // Microsoft's wcsicmp() blows it.
473 //
474 #if defined(ON_COMPILER_MSC1400)
475 return _wcsicmp(s1,s2); // Microsoft's compiler / C library
476 #else
477 return wcsicmp(s1,s2); // Microsoft's compiler / C library
478 #endif
479
480 #endif
481
482
483 #endif
484
485 // If your compiler does not have a way to perform
486 // a case insensitive compare of UNICODE strings,
487 // then use the "hack" version below.
488 return on__hack__wcsicmp(s1,s2);
489 }
490
491 #if defined(ON_COMPILER_MSC)
492 #pragma warning( pop )
493 #endif
494
on_wcsupr(wchar_t * s)495 wchar_t* on_wcsupr(wchar_t* s)
496 {
497 #if defined(ON_OS_WINDOWS)
498 #if defined(ON_COMPILER_BORLAND)
499 // Borland's compiler / C library
500 return _wcsupr(s);
501 #else
502 // Microsoft compiler
503 return _wcsupr(s);
504 #endif
505 #else
506 if (s)
507 {
508 wchar_t c;
509 while (*s)
510 {
511 if ( 0 != (c = toupper(*s)) )
512 *s = c;
513 s++;
514 }
515 }
516 return s;
517 #endif
518 }
519
520 // on_wcslwr() calls _wcslwr() or wcslwr() depending on OS
on_wcslwr(wchar_t * s)521 wchar_t* on_wcslwr(wchar_t* s)
522 {
523 #if defined(ON_OS_WINDOWS)
524 #if defined(ON_COMPILER_BORLAND)
525 // Borland's compiler / C library
526 return _wcslwr(s);
527 #else
528 // Microsoft compiler
529 return _wcslwr(s);
530 #endif
531 #else
532 if (s)
533 {
534 wchar_t c;
535 while (*s)
536 {
537 if ( 0 != (c = tolower(*s)) )
538 *s = c;
539 s++;
540 }
541 }
542 return s;
543 #endif
544 }
545
MakeUpper()546 void ON_wString::MakeUpper()
547 {
548 if ( !IsEmpty() )
549 {
550 #if defined(ON_OS_WINDOWS)
551 if ( 0 != g_s__windows_locale_id )
552 {
553 if ( 0 == g_s__windows_locale_os )
554 {
555 // On Win 95/98/ME, LCMapStringW() doesn't work.
556 // (I hope you don't need the right answer in a hurry on Win9X.)
557
558 // These convert UNICODE to wide character strings
559 ON_String in(*this);
560 int len_in = in.Length();
561 int max_len_out = 2*len_in+16; // if 2x for wide char expansion
562 ON_String out;
563 out.ReserveArray(max_len_out+1);
564 out.SetLength(max_len_out+1);
565
566 // Wide char conversion
567 int rc = ::LCMapStringA(g_s__windows_locale_id,
568 LCMAP_UPPERCASE,
569 in.Array(),
570 len_in,
571 out.Array(),
572 max_len_out);
573 if (rc > 0 && rc <= max_len_out)
574 {
575 out.SetLength(rc);
576 operator=(out); // multi-byte to wchar conversion
577 return;
578 }
579 }
580 else
581 {
582 // a version of Windows with working UNICODE support
583 int len_in = Length();
584 int max_len_out = len_in+16;
585 ON_wString out;
586 out.ReserveArray(max_len_out+1);
587 out.SetLength(max_len_out+1);
588
589 // Wide char conversion
590 int rc = ::LCMapStringW(g_s__windows_locale_id,
591 LCMAP_UPPERCASE,
592 Array(),
593 len_in,
594 out.Array(),
595 max_len_out);
596 if (rc > 0 && rc <= max_len_out)
597 {
598 out.SetLength(rc);
599 operator=(out); // very fast - simply changes reference count
600 return;
601 }
602 }
603 }
604 #endif
605
606 // If ::LCMapStringA() or ::LCMapStringW() failed or we are
607 // running on a non-Windows OS, then we fall through to the
608 // wcslwr() function which will handle most most characters
609 // in most Western European languages but is not adequate for
610 // commercial quality software.
611 CopyArray();
612 on_wcsupr(m_s);
613 }
614 }
615
MakeLower()616 void ON_wString::MakeLower()
617 {
618 if ( !IsEmpty() )
619 {
620 #if defined(ON_OS_WINDOWS)
621 if ( 0 != g_s__windows_locale_id )
622 {
623 if ( 0 == g_s__windows_locale_os )
624 {
625 // On Win 95/98/ME, LCMapStringW() doesn't work.
626 // (I hope you don't need the right answer in a hurry on Win9X.)
627
628 // These convert UNICODE to wide character strings
629 ON_String in(*this);
630 int len_in = in.Length();
631 int max_len_out = 2*len_in+16; // if 2x for wide char expansion
632 ON_String out;
633 out.ReserveArray(max_len_out+1);
634 out.SetLength(max_len_out+1);
635
636 // Wide char conversion to multi-byte lower case string
637 int rc = ::LCMapStringA(g_s__windows_locale_id,
638 LCMAP_LOWERCASE,
639 in.Array(),
640 len_in,
641 out.Array(),
642 max_len_out);
643 if (rc > 0 && rc <= max_len_out)
644 {
645 out.SetLength(rc);
646 operator=(out); // multi-byte to wchar conversion
647 return;
648 }
649 }
650 else
651 {
652 // a version of Windows with working UNICODE support
653 int len_in = Length();
654 int max_len_out = len_in+16;
655
656 // ReserveArray(max_len_out+1) allocates max_len_out+2
657 // wchars (room for the NULL terminator is allocatcated).
658 // The +1 is just in case LCMapStringW() has a bug and
659 // writes an extra wchar or puts a NULL terminator
660 // in s[max_len_out]. This is a lot of paranoia, but
661 // the memory cost is negligable and it will prevent
662 // difficult to diagnose crashes if MS releases a buggy
663 // version of LCMapStringW().
664 ON_wString out;
665 out.ReserveArray(max_len_out+1);
666 out.SetLength(max_len_out+1);
667
668 // Wide char conversion to lower case.
669 // Note that changing to lower case in some languages
670 // can change the string length.
671 int rc = ::LCMapStringW(g_s__windows_locale_id,
672 LCMAP_LOWERCASE,
673 Array(),
674 len_in,
675 out.Array(),
676 max_len_out);
677 if (rc > 0 && rc <= max_len_out)
678 {
679 out.SetLength(rc);
680 operator=(out); // very fast - simply changes reference count
681 return;
682 }
683 }
684 }
685 #endif
686
687 // If ::LCMapStringA() or ::LCMapStringW() failed or we are
688 // running on a non-Windows OS, then we fall through to the
689 // wcslwr() function which will handle most most characters
690 // in most Western European languages but is not adequate for
691 // commercial quality software.
692 CopyArray();
693 on_wcslwr(m_s);
694 }
695 }
696
on_wcsrev(wchar_t * s)697 wchar_t* on_wcsrev(wchar_t* s)
698 {
699 if ( !s )
700 return 0;
701 int i, j;
702 wchar_t w;
703 for ( j = 0; 0 != s[j]; j++ )
704 {
705 // empty for body
706 }
707
708 for ( i = 0, j--; i < j; i++, j-- )
709 {
710 w = s[i];
711 if ( w >= 0xD800 && w <= 0xDBFF && s[i+1] >= 0xDC00 && s[i+1] <= 0xDFFF )
712 {
713 // UTF-16 surrogate pair
714 if ( i+1 < j-1 )
715 {
716 s[i] = s[j-1];
717 s[j-1] = w;
718 w = s[i+1];
719 s[i+1] = s[j];
720 s[j] = w;
721 }
722 i++;
723 j--;
724 }
725 else
726 {
727 s[i] = s[j];
728 s[j] = w;
729 }
730 }
731 return s;
732 }
733
on_WideCharToMultiByte(const wchar_t * lpWideCharStr,int cchWideChar,char * lpMultiByteStr,int cchMultiByte)734 int on_WideCharToMultiByte(
735 const wchar_t* lpWideCharStr,
736 int cchWideChar,
737 char* lpMultiByteStr,
738 int cchMultiByte
739 )
740 {
741 // 14 March 2011 Dale Lear
742 // It turns out that Windows WideCharToMultiByte does correctly
743 // convert UTF-16 to UTF-8 in Windows 7 when the code page
744 // is CP_ACP and calls with CP_UTF8 sometimes fail to do
745 // any conversion. So, I wrote ON_ConvertWideCharToUTF8()
746 // and opennurbs will use ON_ConvertWideCharToUTF8 to get
747 // consistent results on all platforms.
748 unsigned int error_status = 0;
749 unsigned int error_mask = 0xFFFFFFFF;
750 ON__UINT32 error_code_point = 0xFFFD;
751 const wchar_t* p1 = 0;
752 int count = ON_ConvertWideCharToUTF8(false,lpWideCharStr,cchWideChar,lpMultiByteStr,cchMultiByte,
753 &error_status,error_mask,error_code_point,&p1);
754 if ( 0 != error_status )
755 {
756 ON_ERROR("Error converting UTF-16 encoded wchar_t string to UTF-8 encoded char string.");
757 }
758 return count;
759 }
760
on_MultiByteToWideChar(const char * lpMultiByteStr,int cchMultiByte,wchar_t * lpWideCharStr,int cchWideChar)761 int on_MultiByteToWideChar(
762 const char* lpMultiByteStr,
763 int cchMultiByte,
764 wchar_t* lpWideCharStr,
765 int cchWideChar
766 )
767 {
768 // 14 March 2011 Dale Lear
769 // It turns out that Windows WideCharToMultiByte does not correctly
770 // convert UTF-8 to UTF-16 in Windows 7 when the code page
771 // is CP_ACP and calls with CP_UTF8 sometimes fail to do
772 // any conversion. So, I wrote ON_ConvertUTF8ToWideChar()
773 // and opennurbs will use ON_ConvertUTF8ToWideChar to get
774 // consistent results on all platforms.
775 unsigned int error_status = 0;
776 unsigned int error_mask = 0xFFFFFFFF;
777 ON__UINT32 error_code_point = 0xFFFD;
778 const char* p1 = 0;
779 int count = ON_ConvertUTF8ToWideChar(false,lpMultiByteStr,cchMultiByte,lpWideCharStr,cchWideChar,
780 &error_status,error_mask,error_code_point,&p1);
781 if ( 0 != error_status )
782 {
783 ON_ERROR("Error converting UTF-8 encoded char string to UTF-16 encoded wchar_t string.");
784 }
785 return count;
786 }
787
on_vsnprintf(char * buffer,size_t count,const char * format,va_list argptr)788 int on_vsnprintf( char *buffer, size_t count, const char *format, va_list argptr )
789 {
790 #if defined(ON_OS_WINDOWS)
791
792 #if defined(ON_COMPILER_BORLAND)
793 return vsprintf( buffer, format, argptr );
794 #else
795 return _vsnprintf( buffer, count, format, argptr );
796 #endif
797
798 #else
799 return vsnprintf( buffer, count, format, argptr );
800 #endif
801 }
802
on_vsnwprintf(wchar_t * buffer,size_t count,const wchar_t * format,va_list argptr)803 int on_vsnwprintf( wchar_t *buffer, size_t count, const wchar_t *format, va_list argptr )
804 {
805 #if defined(ON_OS_WINDOWS)
806
807 #if defined(ON_COMPILER_BORLAND)
808 return vswprintf( buffer, format, argptr );
809 #else
810 return _vsnwprintf( buffer, count, format, argptr );
811 #endif
812
813 #else
814 // if an OS doesn't support vsnwprintf(), use ASCII and hope for the best
815
816 ON_String aformat = format; // convert format from UNICODE to ASCII
817
818 // format an ASCII buffer
819 char* abuffer = (char*)onmalloc(4*count*sizeof(*abuffer));
820 int rc = on_vsnprintf( abuffer, 4*count, aformat.Array(), argptr );
821
822 // convert formatted ASCII buffer to UNICODE
823 on_MultiByteToWideChar( abuffer, (int)strlen(abuffer), buffer, (int)count );
824 onfree(abuffer);
825 return rc;
826 #endif
827 }
828
on_splitpath(const char * path,const char ** drive,const char ** dir,const char ** fname,const char ** ext)829 void on_splitpath(
830 const char* path,
831 const char** drive,
832 const char** dir,
833 const char** fname,
834 const char** ext
835 )
836 {
837 // The "const char* path" parameter is a UTF-8 encoded string.
838 // Since the unicode code point values for the characters we
839 // are searching for ( '/' '\' '.' ':' A-Z a-z) are all > 0
840 // and < 128, we can simply check for an array element having
841 // the character value and not have to worry about dealing
842 // with UTF-8 continuation values (>= 128).
843
844 const char slash1 = '/';
845 const char slash2 = '\\'; // do this even with the os is unix because
846 // we might be parsing a file name saved
847 // in Windows.
848
849 const char* f;
850 const char* e;
851 const char* s;
852 const char* s1;
853
854 if ( 0 != drive )
855 *drive = 0;
856 if ( 0 != dir )
857 *dir = 0;
858 if ( 0 != fname )
859 *fname = 0;
860 if ( 0 != ext )
861 *ext = 0;
862
863 if ( 0 != path && 0 != *path )
864 {
865 // deal with Windows' drive letter (even when the os is unix)
866 if ( ':' == path[1] )
867 {
868 if ( (path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z') )
869 {
870 if ( drive )
871 *drive = path;
872 path += 2;
873 if ( 0 == *path )
874 return;
875 }
876 }
877 }
878
879 if ( 0 != path && 0 != *path )
880 {
881 e = 0;
882 f = 0;
883 s1 = path;
884 while ( 0 != *s1 )
885 s1++;
886 s = (s1 > path) ? s1 - 1 : path;
887
888 while ( s > path && '.' != *s && slash1 != *s && slash2 != *s )
889 s--;
890
891 if ( '.' == *s && 0 != s[1] )
892 {
893 // extensions must have something after the dot.
894 e = s;
895 s1 = e;
896 s--;
897 }
898
899 while ( s > path && slash1 != *s && slash2 != *s )
900 s--;
901
902 if ( s >= path && s < s1 )
903 {
904 if (slash1 == *s || slash2 == *s )
905 {
906 if ( s+1 < s1 )
907 f = s+1;
908 }
909 else if ( s == path )
910 {
911 f = s;
912 }
913 }
914
915 if ( 0 == f )
916 {
917 // must have a non-empty filename in order to have and "extension"
918 f = e;
919 e = 0;
920 }
921
922 if ( 0 != dir && (0 == f || path < f) )
923 *dir = path;
924
925 if ( 0 != f && 0 != fname )
926 *fname = f;
927
928 if ( 0 != e && 0 != ext )
929 *ext = e;
930 }
931
932 }
933
on_wsplitpath(const wchar_t * path,const wchar_t ** drive,const wchar_t ** dir,const wchar_t ** fname,const wchar_t ** ext)934 void on_wsplitpath(
935 const wchar_t* path,
936 const wchar_t** drive,
937 const wchar_t** dir,
938 const wchar_t** fname,
939 const wchar_t** ext
940 )
941 {
942 // The "const wchar_t* path" parameter is a UTF-8, UTF-16 or UTF-32
943 // encoded string. Since the unicode code point values for the
944 // characters we are searching for ( '/' '\' '.' ':' A-Z a-z) are
945 // all > 0 and < 128, we can simply check for an array element
946 // having the character value and not have to worry about dealing
947 // with UTF-16 surrogate pair values (0xD800-0xDBFF and DC00-DFFF)
948 // and UTF-8 continuation values (>= 128).
949
950 const wchar_t slash1 = '/';
951 const wchar_t slash2 = '\\'; // do this even with the os is unix because
952 // we might be parsing a file name saved
953 // in Windows.
954
955 const wchar_t* f;
956 const wchar_t* e;
957 const wchar_t* s;
958 const wchar_t* s1;
959
960 if ( 0 != drive )
961 *drive = 0;
962 if ( 0 != dir )
963 *dir = 0;
964 if ( 0 != fname )
965 *fname = 0;
966 if ( 0 != ext )
967 *ext = 0;
968
969 if ( 0 != path && 0 != *path )
970 {
971 // deal with Windows' drive letter (even when the os is unix)
972 if ( ':' == path[1] )
973 {
974 if ( (path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z') )
975 {
976 if ( drive )
977 *drive = path;
978 path += 2;
979 if ( 0 == *path )
980 return;
981 }
982 }
983 }
984
985 if ( 0 != path && 0 != *path )
986 {
987 e = 0;
988 f = 0;
989 s1 = path;
990 while ( 0 != *s1 )
991 s1++;
992 s = (s1 > path) ? s1 - 1 : path;
993
994 while ( s > path && '.' != *s && slash1 != *s && slash2 != *s )
995 s--;
996
997 if ( '.' == *s && 0 != s[1] )
998 {
999 // extensions must have something after the dot.
1000 e = s;
1001 s1 = e;
1002 s--;
1003 }
1004
1005 while ( s > path && slash1 != *s && slash2 != *s )
1006 s--;
1007
1008 if ( s >= path && s < s1 )
1009 {
1010 if (slash1 == *s || slash2 == *s )
1011 {
1012 if ( s+1 < s1 )
1013 f = s+1;
1014 }
1015 else if ( s == path )
1016 {
1017 f = s;
1018 }
1019 }
1020
1021 if ( 0 == f )
1022 {
1023 // must have a non-empty filename in order to have and "extension"
1024 f = e;
1025 e = 0;
1026 }
1027
1028 if ( 0 != dir && (0 == f || path < f) )
1029 *dir = path;
1030
1031 if ( 0 != f && 0 != fname )
1032 *fname = f;
1033
1034 if ( 0 != e && 0 != ext )
1035 *ext = e;
1036 }
1037
1038 }
1039
1040
1041
Version()1042 int ON::Version()
1043 {
1044 #define OPENNURBS_VERSION_DEFINITION
1045 #include "opennurbs_version.h"
1046 return OPENNURBS_VERSION;
1047 #undef OPENNURBS_VERSION
1048 #undef OPENNURBS_VERSION_DEFINITION
1049 }
1050
SourceRevision()1051 const char* ON::SourceRevision()
1052 {
1053 return OPENNURBS_SRC_SVN_REVISION;
1054 }
1055
SourceBranch()1056 const char* ON::SourceBranch()
1057 {
1058 return OPENNURBS_SRC_SVN_BRANCH;
1059 }
1060
DocumentationRevision()1061 const char* ON::DocumentationRevision()
1062 {
1063 return OPENNURBS_DOC_SVN_REVISION;
1064 }
1065
DocumentationBranch()1066 const char* ON::DocumentationBranch()
1067 {
1068 return OPENNURBS_DOC_SVN_BRANCH;
1069 }
1070
OpenFile(const char * filename,const char * filemode)1071 FILE* ON::OpenFile( // like fopen() - needed when OpenNURBS is used as a DLL
1072 const char* filename, // file name
1073 const char* filemode // file mode
1074 )
1075 {
1076 return ON_FileStream::Open(filename,filemode);
1077 }
1078
OpenFile(const wchar_t * filename,const wchar_t * filemode)1079 FILE* ON::OpenFile( // like fopen() - needed when OpenNURBS is used as a DLL
1080 const wchar_t* filename, // file name
1081 const wchar_t* filemode // file mode
1082 )
1083 {
1084 return ON_FileStream::Open(filename,filemode);
1085 }
1086
CloseFile(FILE * fp)1087 int ON::CloseFile( // like fclose() - needed when OpenNURBS is used as a DLL
1088 FILE* fp // pointer returned by OpenFile()
1089 )
1090 {
1091 return ON_FileStream::Close(fp);
1092 }
1093
CloseAllFiles()1094 int ON::CloseAllFiles()
1095 {
1096 // returns number of files closed or EOF for error
1097 #if defined(ON_OS_WINDOWS)
1098 return _fcloseall(); // ANSI C name
1099 #else
1100 // I can't find an fcloseall() or _fcloseall() in
1101 // gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
1102 return EOF;
1103 #endif
1104 }
1105
1106
1107
ActiveSpace(int i)1108 ON::active_space ON::ActiveSpace(int i)
1109 {
1110 ON::active_space as;
1111
1112 switch(i)
1113 {
1114 case no_space: as = no_space; break;
1115 case model_space: as = model_space; break;
1116 case page_space: as = page_space; break;
1117 default: as = no_space; break;
1118 }
1119
1120 return as;
1121 }
1122
1123
UnitSystem(int i)1124 ON::unit_system ON::UnitSystem(int i)
1125 {
1126 unit_system us = no_unit_system;
1127 switch(i) {
1128 case no_unit_system: us = no_unit_system; break;
1129
1130 case angstroms: us = angstroms; break;
1131
1132 case nanometers: us = nanometers; break;
1133 case microns: us = microns; break;
1134 case millimeters: us = millimeters; break;
1135 case centimeters: us = centimeters; break;
1136 case decimeters: us = decimeters; break;
1137 case meters: us = meters; break;
1138 case dekameters: us = dekameters; break;
1139 case hectometers: us = hectometers; break;
1140 case kilometers: us = kilometers; break;
1141 case megameters: us = megameters; break;
1142 case gigameters: us = gigameters; break;
1143 case microinches: us = microinches; break;
1144 case mils: us = mils; break;
1145 case inches: us = inches; break;
1146 case feet: us = feet; break;
1147 case yards: us = yards; break;
1148 case miles: us = miles; break;
1149 case printer_point: us = printer_point; break;
1150 case printer_pica: us = printer_pica; break;
1151 case nautical_mile: us = nautical_mile; break;
1152 case astronomical: us = astronomical; break;
1153 case lightyears: us = lightyears; break;
1154 case parsecs: us = parsecs; break;
1155 case custom_unit_system: us = custom_unit_system; break;
1156 default: us = no_unit_system; break;
1157 }
1158 return us;
1159 }
1160
UnitScale(const class ON_3dmUnitsAndTolerances & u_and_t_from,const class ON_3dmUnitsAndTolerances & u_and_t_to)1161 double ON::UnitScale(
1162 const class ON_3dmUnitsAndTolerances& u_and_t_from,
1163 const class ON_3dmUnitsAndTolerances& u_and_t_to
1164 )
1165 {
1166 return ON::UnitScale( u_and_t_from.m_unit_system, u_and_t_to.m_unit_system );
1167 }
1168
UnitScale(ON::unit_system us_from,const class ON_UnitSystem & us_to)1169 double ON::UnitScale(
1170 ON::unit_system us_from,
1171 const class ON_UnitSystem& us_to
1172 )
1173 {
1174 double scale = 1.0;
1175 ON::unit_system us1 = us_to.m_unit_system;
1176 if ( ON::custom_unit_system == us1 )
1177 {
1178 if ( us_to.m_custom_unit_scale > 0.0 && ON_IsValid(us_to.m_custom_unit_scale) )
1179 {
1180 scale *= us_to.m_custom_unit_scale;
1181 us1 = ON::meters;
1182 }
1183 }
1184 return scale*ON::UnitScale(us_from,us1);
1185 }
1186
UnitScale(const class ON_UnitSystem & us_from,ON::unit_system us_to)1187 double ON::UnitScale(
1188 const class ON_UnitSystem& us_from,
1189 ON::unit_system us_to
1190 )
1191 {
1192 double scale = 1.0;
1193 ON::unit_system us0 = us_from.m_unit_system;
1194 if ( ON::custom_unit_system == us0 )
1195 {
1196 if ( us_from.m_custom_unit_scale > 0.0 && ON_IsValid(us_from.m_custom_unit_scale) )
1197 {
1198 scale /= us_from.m_custom_unit_scale;
1199 us0 = ON::meters;
1200 }
1201 }
1202 return scale*ON::UnitScale(us0,us_to);
1203 }
1204
UnitScale(const class ON_UnitSystem & u_and_t_from,const class ON_UnitSystem & u_and_t_to)1205 double ON::UnitScale(
1206 const class ON_UnitSystem& u_and_t_from,
1207 const class ON_UnitSystem& u_and_t_to
1208 )
1209 {
1210 double scale = 1.0;
1211 ON::unit_system us_from = u_and_t_from.m_unit_system;
1212 ON::unit_system us_to = u_and_t_to.m_unit_system;
1213
1214 if ( ON::no_unit_system != us_from && ON::no_unit_system != us_to )
1215 {
1216 if ( ON::custom_unit_system == us_from
1217 && ON_IsValid(u_and_t_from.m_custom_unit_scale)
1218 && u_and_t_from.m_custom_unit_scale > 0.0 )
1219 {
1220 scale /= u_and_t_from.m_custom_unit_scale;
1221 us_from = ON::meters;
1222 }
1223
1224 if ( ON::custom_unit_system == us_to
1225 && ON_IsValid(u_and_t_to.m_custom_unit_scale)
1226 && u_and_t_to.m_custom_unit_scale > 0.0 )
1227 {
1228 scale *= u_and_t_to.m_custom_unit_scale;
1229 us_to = ON::meters;
1230 }
1231
1232 scale *= ON::UnitScale( us_from, us_to );
1233 }
1234
1235 return scale;
1236 }
1237
IsEnglishUnit(ON::unit_system us)1238 static bool IsEnglishUnit( ON::unit_system us )
1239 {
1240 return (
1241 ON::microinches == us
1242 || ON::mils == us
1243 || ON::inches == us
1244 || ON::feet == us
1245 || ON::yards == us
1246 || ON::miles == us
1247 || ON::printer_point == us
1248 || ON::printer_pica == us
1249 );
1250 }
1251
UnitScale(ON::unit_system u0,ON::unit_system u1)1252 double ON::UnitScale(
1253 ON::unit_system u0, // from
1254 ON::unit_system u1 // to
1255 )
1256 {
1257 // Scale factor for changing unit systems
1258 // Examples
1259 // 100.0 = UnitScale( ON::meters, ON::centimeters )
1260 // 2.54 = UnitScale( ON::inches, ON::centimeters )
1261 // 12.0 = UnitScale( ON::feet, ON::inches )
1262
1263 // the default cases are here to keep lint quiet
1264 double scale = 1.0;
1265
1266 if ( u0 != u1
1267 && u1 != ON::custom_unit_system
1268 && ((int)u1) > 0 && ((int)u1) < 26
1269 // switch weeds out bogus values of u0
1270 )
1271 switch( u0 )
1272 {
1273 case ON::angstroms:
1274 scale = UnitScale( meters, u1)*1.0e-10;
1275 break;
1276
1277 case ON::nanometers:
1278 scale = UnitScale( meters, u1)*1.0e-9;
1279 break;
1280
1281 case ON::microns:
1282 scale = UnitScale( meters, u1)*1.0e-6;
1283 break;
1284
1285 case ON::millimeters:
1286 switch( u1 )
1287 {
1288 case ON::meters: scale = 1.0e-3; break;
1289 case ON::microns: scale = 1.0e+3; break;
1290 case ON::centimeters: scale = 1.0e-1; break;
1291
1292 default:
1293 scale = IsEnglishUnit(u1)
1294 ? UnitScale( inches, u1 )/25.4
1295 : UnitScale( meters, u1 )*1.0e-3;
1296 break;
1297 }
1298 break;
1299
1300 case ON::centimeters:
1301 switch( u1 )
1302 {
1303 case ON::meters: scale = 1.0e-2; break;
1304 case ON::millimeters: scale = 1.0e+1; break;
1305
1306 default:
1307 scale = IsEnglishUnit(u1)
1308 ? UnitScale( inches, u1 )/2.54
1309 : UnitScale( meters, u1 )*1.0e-2;
1310 break;
1311 }
1312 break;
1313
1314 case ON::decimeters:
1315 scale = IsEnglishUnit(u1)
1316 ? UnitScale( inches, u1 )/0.254
1317 : UnitScale( meters, u1 )*1.0e-1;
1318 break;
1319
1320 case ON::meters:
1321 switch( u1 )
1322 {
1323 case ON::angstroms: scale = 1.0e+10; break;
1324 case ON::nanometers: scale = 1.0e+9; break;
1325 case ON::microns: scale = 1.0e+6; break;
1326 case ON::millimeters: scale = 1.0e+3; break;
1327 case ON::centimeters: scale = 1.0e+2; break;
1328 case ON::decimeters: scale = 1.0e1; break;
1329 case ON::meters: scale = 1.0; break;
1330 case ON::dekameters: scale = 1.0e-1; break;
1331 case ON::hectometers: scale = 1.0e-2; break;
1332 case ON::kilometers: scale = 1.0e-3; break;
1333 case ON::megameters: scale = 1.0e-6; break;
1334 case ON::gigameters: scale = 1.0e-9; break;
1335
1336 case ON::nautical_mile: scale = 1.0/1852.0; break;
1337 case ON::astronomical: scale = 1.0/1.4959787e+11; break;
1338 case ON::lightyears: scale = 1.0/9.4607304725808e+15; break;
1339 case ON::parsecs: scale = 1.0/3.08567758e+16; break;
1340
1341 default:
1342 if ( IsEnglishUnit(u1) )
1343 scale = UnitScale( inches, u1 )/0.0254;
1344 break;
1345 }
1346 break;
1347
1348 case ON::dekameters:
1349 scale = UnitScale( meters, u1 )*10.0;
1350 break;
1351
1352 case ON::hectometers:
1353 scale = UnitScale( meters, u1 )*100.0;
1354 break;
1355
1356 case ON::kilometers:
1357 scale = IsEnglishUnit(u1)
1358 ? UnitScale( inches, u1 )/0.0000254
1359 : UnitScale( meters, u1 )*1000.0;
1360 break;
1361
1362 case ON::megameters:
1363 scale = UnitScale( meters, u1 )*1.0e6;
1364 break;
1365
1366 case ON::gigameters:
1367 scale = UnitScale( meters, u1 )*1.0e9;
1368 break;
1369
1370 case ON::microinches:
1371 scale = UnitScale( inches, u1 )*1.0e-6;
1372 break;
1373
1374 case ON::mils:
1375 scale = UnitScale( inches, u1 )*1.0e-3;
1376 break;
1377
1378 case ON::inches:
1379 switch( u1 )
1380 {
1381 case ON::angstroms: scale = 2.54e+8; break;
1382 case ON::nanometers: scale = 2.54e+7; break;
1383 case ON::microns: scale = 2.54e+4; break;
1384 case ON::millimeters: scale = 25.4; break;
1385 case ON::centimeters: scale = 2.54; break;
1386 case ON::decimeters: scale = 2.54e-1; break;
1387 case ON::meters: scale = 2.54e-2; break;
1388 case ON::dekameters: scale = 2.54e-3; break;
1389 case ON::hectometers: scale = 2.54e-4; break;
1390 case ON::kilometers: scale = 2.54e-5; break;
1391 case ON::megameters: scale = 2.54e-8; break;
1392 case ON::gigameters: scale = 2.54e-11; break;
1393
1394 case ON::printer_point: scale = 72.0; break;
1395 case ON::printer_pica: scale = 6.0; break;
1396 case ON::microinches: scale = 1.0e+6; break;
1397 case ON::mils: scale = 1.0e+3; break;
1398 case ON::inches: scale = 1.0; break;
1399 case ON::feet: scale = 1.0/12.0; break;
1400 case ON::yards: scale = 1.0/36.0; break;
1401 case ON::miles: scale = 1.0/(12.0*5280.0); break;
1402
1403 default:
1404 scale = UnitScale( meters, u1 )*2.54e-2;
1405 break;
1406 }
1407 break;
1408
1409 case ON::feet:
1410 switch( u1 )
1411 {
1412 case ON::yards: scale = 1.0/3.0; break;
1413 case ON::miles: scale = 1.0/5280.0; break;
1414 default:
1415 scale = UnitScale( inches, u1 )*12.0;
1416 break;
1417 }
1418 break;
1419
1420 case ON::yards:
1421 switch( u1 )
1422 {
1423 case ON::feet: scale = 3.0; break;
1424 case ON::miles: scale = 1.0/1760.0; break;
1425 default:
1426 scale = UnitScale( inches, u1 )*36.0;
1427 break;
1428 }
1429 break;
1430
1431 case ON::miles:
1432 if ( ON::feet == u1 )
1433 {
1434 scale = 5280.0;
1435 }
1436 else
1437 {
1438 scale = IsEnglishUnit(u1)
1439 ? UnitScale( inches, u1 )*12.0*5280.0
1440 : UnitScale( meters, u1 )*1609.344;
1441 }
1442 break;
1443
1444 case ON::printer_point:
1445 scale = UnitScale( inches, u1 )/72.0;
1446 break;
1447
1448 case ON::printer_pica:
1449 scale = UnitScale( inches, u1 )/6.0;
1450 break;
1451
1452 case ON::nautical_mile:
1453 scale = UnitScale( meters, u1 )*1852.0;
1454 break;
1455
1456 case ON::astronomical:
1457 // 1.4959787e+11 http://en.wikipedia.org/wiki/Astronomical_unit
1458 // 1.495979e+11 http://units.nist.gov/Pubs/SP811/appenB9.htm
1459 // An astronomical unit (au) is the mean distance from the
1460 // center of the earth to the center of the sun.
1461 scale = UnitScale( meters, u1 )*1.4959787e+11;
1462 break;
1463
1464 case ON::lightyears:
1465 // 9.4607304725808e+15 http://en.wikipedia.org/wiki/Light_year
1466 // 9.46073e+15 meters http://units.nist.gov/Pubs/SP811/appenB9.htm
1467 // A light year is the distance light travels in one Julian year.
1468 // The speed of light is exactly 299792458 meters/second.
1469 // A Julian year is exactly 365.25 * 86400 seconds and is
1470 // approximately the time it takes for one earth orbit.
1471 scale = UnitScale( meters, u1 )*9.4607304725808e+15;
1472 break;
1473
1474 case ON::parsecs:
1475 // 3.08567758e+16 // http://en.wikipedia.org/wiki/Parsec
1476 // 3.085678e+16 // http://units.nist.gov/Pubs/SP811/appenB9.htm
1477 scale = UnitScale( meters, u1 )*3.08567758e+16;
1478 break;
1479
1480 case ON::custom_unit_system:
1481 case ON::no_unit_system:
1482 // nothing to do here
1483 break;
1484 }
1485
1486 return scale;
1487 }
1488
1489
1490 //// distance_display_mode ///////////////////////////////////
1491 enum distance_display_mode
1492 {
1493 decimal = 0,
1494 fractional = 1,
1495 feet_inches = 2
1496 };
1497
DistanceDisplayMode(int i)1498 ON::distance_display_mode ON::DistanceDisplayMode(int i)
1499 {
1500 distance_display_mode dm = decimal;
1501 switch (i)
1502 {
1503 case decimal:
1504 dm = decimal;
1505 break;
1506 case fractional:
1507 dm = fractional;
1508 break;
1509 case feet_inches:
1510 dm = feet_inches;
1511 break;
1512 }
1513 return dm;
1514 }
1515
1516
PointStyle(int i)1517 ON::point_style ON::PointStyle(int i)
1518 {
1519 //convertintegertopoint_styleenum
1520 point_style ps = unknown_point_style;
1521 switch (i) {
1522 case not_rational: ps = not_rational; break;
1523 case homogeneous_rational: ps = homogeneous_rational; break;
1524 case euclidean_rational: ps = euclidean_rational; break;
1525 default: ps = unknown_point_style; break;
1526 }
1527 return ps;
1528 }
1529
1530
KnotStyle(int i)1531 ON::knot_style ON::KnotStyle(int i)
1532 {
1533 //convertintegertoknot_styleenum
1534 knot_style ks = unknown_knot_style;
1535 switch (i) {
1536 case uniform_knots: ks = uniform_knots; break;
1537 case quasi_uniform_knots: ks = quasi_uniform_knots; break;
1538 case piecewise_bezier_knots: ks = piecewise_bezier_knots; break;
1539 case clamped_end_knots: ks = clamped_end_knots; break;
1540 case non_uniform_knots: ks = non_uniform_knots; break;
1541 default: ks = unknown_knot_style; break;
1542 }
1543 return ks;
1544 }
1545
Continuity(int i)1546 ON::continuity ON::Continuity(int i)
1547 {
1548 continuity c = unknown_continuity;
1549
1550 switch(i)
1551 {
1552 case unknown_continuity: c = unknown_continuity; break;
1553 case C0_continuous: c = C0_continuous; break;
1554 case C1_continuous: c = C1_continuous; break;
1555 case C2_continuous: c = C2_continuous; break;
1556 case G1_continuous: c = G1_continuous; break;
1557 case G2_continuous: c = G2_continuous; break;
1558
1559 // 30 March 2003 Dale Lear added these
1560 case C0_locus_continuous: c = C0_locus_continuous; break;
1561 case C1_locus_continuous: c = C1_locus_continuous; break;
1562 case C2_locus_continuous: c = C2_locus_continuous; break;
1563 case G1_locus_continuous: c = G1_locus_continuous; break;
1564 case G2_locus_continuous: c = G2_locus_continuous; break;
1565
1566 case Cinfinity_continuous: c = Cinfinity_continuous; break;
1567
1568 case Gsmooth_continuous: c = Gsmooth_continuous; break;
1569 };
1570
1571 return c;
1572 }
1573
ParametricContinuity(int i)1574 ON::continuity ON::ParametricContinuity(int i)
1575 {
1576 // "erase" the locus setting.
1577 continuity c = unknown_continuity;
1578
1579 switch(i)
1580 {
1581 case unknown_continuity: c = unknown_continuity; break;
1582 case C0_continuous: c = C0_continuous; break;
1583 case C1_continuous: c = C1_continuous; break;
1584 case C2_continuous: c = C2_continuous; break;
1585 case G1_continuous: c = G1_continuous; break;
1586 case G2_continuous: c = G2_continuous; break;
1587 case C0_locus_continuous: c = C0_continuous; break;
1588 case C1_locus_continuous: c = C1_continuous; break;
1589 case C2_locus_continuous: c = C2_continuous; break;
1590 case G1_locus_continuous: c = G1_continuous; break;
1591 case G2_locus_continuous: c = G2_continuous; break;
1592 case Cinfinity_continuous: c = Cinfinity_continuous; break;
1593 case Gsmooth_continuous: c = Gsmooth_continuous; break;
1594 };
1595
1596 return c;
1597 }
1598
1599
PolylineContinuity(int i)1600 ON::continuity ON::PolylineContinuity(int i)
1601 {
1602 continuity c = unknown_continuity;
1603
1604 switch(i)
1605 {
1606 case unknown_continuity: c = unknown_continuity; break;
1607 case C0_continuous: c = C0_continuous; break;
1608 case C1_continuous: c = C1_continuous; break;
1609 case C2_continuous: c = C1_continuous; break;
1610 case G1_continuous: c = G1_continuous; break;
1611 case G2_continuous: c = G1_continuous; break;
1612 case C0_locus_continuous: c = C0_locus_continuous; break;
1613 case C1_locus_continuous: c = C1_locus_continuous; break;
1614 case C2_locus_continuous: c = C1_locus_continuous; break;
1615 case G1_locus_continuous: c = G1_locus_continuous; break;
1616 case G2_locus_continuous: c = G1_locus_continuous; break;
1617 case Cinfinity_continuous: c = C1_continuous; break;
1618 case Gsmooth_continuous: c = G1_continuous; break;
1619 };
1620
1621 return c;
1622 }
1623
1624
CurveStyle(int i)1625 ON::curve_style ON::CurveStyle(int i)
1626 {
1627 //convertintegertocurve_styleenum
1628 curve_style cs = unknown_curve_style;
1629 switch (i) {
1630 case line: cs = line; break;
1631 case circle: cs = circle; break;
1632 case ellipse: cs = ellipse; break;
1633 case parabola: cs = parabola; break;
1634 case hyperbola: cs = hyperbola; break;
1635 case planar_polyline: cs = planar_polyline; break;
1636 case polyline: cs = polyline; break;
1637 case planar_freeform_curve: cs = planar_freeform_curve; break;
1638 case freeform_curve: cs = freeform_curve; break;
1639 default: cs = unknown_curve_style; break;
1640 }
1641 return cs;
1642 }
1643
SurfaceStyle(int i)1644 ON::surface_style ON::SurfaceStyle(int i)
1645 {
1646 //convertintegertosurface_styleenum
1647 surface_style ss = unknown_surface_style;
1648
1649 switch (i) {
1650 case plane: ss = plane; break;
1651 case circular_cylinder: ss = circular_cylinder; break;
1652 case elliptical_cylinder: ss = elliptical_cylinder; break;
1653 case circular_cone: ss = circular_cone; break;
1654 case elliptical_cone: ss = elliptical_cone; break;
1655 case sphere: ss = sphere; break;
1656 case torus: ss = torus; break;
1657 case surface_of_revolution: ss = surface_of_revolution; break;
1658 case ruled_surface: ss = ruled_surface; break;
1659 case freeform_surface: ss = freeform_surface; break;
1660 default: ss = unknown_surface_style; break;
1661 }
1662 return ss;
1663 }
1664
SortAlgorithm(int i)1665 ON::sort_algorithm ON::SortAlgorithm(int i)
1666 {
1667 sort_algorithm sa = ON::quick_sort;
1668
1669 switch (i) {
1670 case ON::heap_sort: sa = ON::heap_sort; break;
1671 case ON::quick_sort: sa = ON::quick_sort; break;
1672 default: sa = ON::quick_sort; break;
1673 }
1674 return sa;
1675 }
1676
Endian(int i)1677 ON::endian ON::Endian(int i)
1678 { // convert integer to endian enum
1679 endian e = (i<=0) ? little_endian : big_endian;
1680 return e;
1681 }
1682
Endian()1683 ON::endian ON::Endian()
1684 {
1685 // returns endian-ness of cpu.
1686 union {
1687 int i;
1688 unsigned char b[sizeof(int)];
1689 } u;
1690 u.i = 1;
1691 return (u.b[0] == 1) ? little_endian : big_endian;
1692 }
1693
ArchiveMode(int i)1694 ON::archive_mode ON::ArchiveMode(int i)
1695 {
1696 // convert integer to endian enum
1697 archive_mode a = read;
1698 switch(i) {
1699 case read: a = read; break;
1700 case write: a = write; break;
1701 case readwrite: a = readwrite; break;
1702 case read3dm: a = read3dm; break;
1703 case write3dm: a = write3dm; break;
1704 }
1705 return a;
1706 }
1707
ViewProjection(int i)1708 ON::view_projection ON::ViewProjection(int i)
1709 {
1710 // convert integer to view_projection enum
1711 view_projection v = ON::unknown_view;
1712 switch(i)
1713 {
1714 case ON::parallel_view: v = ON::parallel_view; break;
1715 case ON::perspective_view: v = ON::perspective_view; break;
1716 }
1717 return v;
1718 }
1719
IsParallelProjection(ON::view_projection proj)1720 bool ON::IsParallelProjection( ON::view_projection proj )
1721 {
1722 return ON::parallel_view == proj;
1723 }
1724
IsPerspectiveProjection(ON::view_projection proj)1725 bool ON::IsPerspectiveProjection( ON::view_projection proj )
1726 {
1727 return ( ON::perspective_view == proj );
1728 }
1729
CoordinateSystem(int i)1730 ON::coordinate_system ON::CoordinateSystem(int i)
1731 {
1732 // convert integer to coordinate_system enum
1733 coordinate_system cs = world_cs;
1734 switch(i) {
1735 case world_cs: cs = world_cs; break;
1736 case camera_cs: cs = camera_cs; break;
1737 case clip_cs: cs = clip_cs; break;
1738 case screen_cs: cs = screen_cs; break;
1739 }
1740 return cs;
1741 }
1742
ExceptionType(int i)1743 ON::exception_type ON::ExceptionType(int i)
1744 {
1745 // convert integer to exception_type enum
1746 ON::exception_type e = unknown_exception;
1747 switch(i) {
1748 case out_of_memory: e = out_of_memory; break;
1749 case unable_to_write_archive: e = unable_to_write_archive; break;
1750 case unable_to_read_archive: e = unable_to_read_archive; break;
1751 case unable_to_seek_archive: e = unable_to_seek_archive; break;
1752 case unexpected_end_of_archive: e = unexpected_end_of_archive; break;
1753 case unexpected_value_in_archive: e = unexpected_value_in_archive; break;
1754 };
1755 return e;
1756 }
1757
LayerMode(int i)1758 ON::layer_mode ON::LayerMode(int i)
1759 {
1760 ON::layer_mode m = normal_layer;
1761 switch(i)
1762 {
1763 case normal_layer: m = normal_layer; break;
1764 case hidden_layer: m = hidden_layer; break;
1765 case locked_layer: m = locked_layer; break;
1766 }
1767 return m;
1768 }
1769
ObjectMode(int i)1770 ON::object_mode ON::ObjectMode(int i)
1771 {
1772 ON::object_mode m = normal_object;
1773 switch(i)
1774 {
1775 case normal_object: m = normal_object; break;
1776 case hidden_object: m = hidden_object; break;
1777 case locked_object: m = locked_object; break;
1778 case idef_object: m = idef_object; break;
1779 }
1780 return m;
1781 }
1782
ObjectColorSource(int i)1783 ON::object_color_source ON::ObjectColorSource(int i)
1784 {
1785 // convert integer to object_mode enum
1786 ON::object_color_source cs = color_from_layer;
1787 switch (i)
1788 {
1789 case color_from_layer: // use color assigned to layer
1790 cs = color_from_layer;
1791 break;
1792 case color_from_object: // use color assigned to object
1793 cs = color_from_object;
1794 break;
1795 case color_from_material: // use diffuse render material color
1796 cs = color_from_material;
1797 break;
1798 case color_from_parent:
1799 cs = color_from_parent;
1800 break;
1801 }
1802 return cs;
1803 }
1804
PlotColorSource(int i)1805 ON::plot_color_source ON::PlotColorSource(int i)
1806 {
1807 // convert integer to object_mode enum
1808 ON::plot_color_source cs = plot_color_from_layer;
1809 switch (i)
1810 {
1811 case plot_color_from_layer:
1812 cs = plot_color_from_layer;
1813 break;
1814 case plot_color_from_object:
1815 cs = plot_color_from_object;
1816 break;
1817 case plot_color_from_display:
1818 cs = plot_color_from_display;
1819 break;
1820 case plot_color_from_parent:
1821 cs = plot_color_from_parent;
1822 break;
1823 }
1824 return cs;
1825 }
1826
PlotWeightSource(int pw)1827 ON::plot_weight_source ON::PlotWeightSource(int pw)
1828 {
1829 switch(pw)
1830 {
1831 case plot_weight_from_layer: return plot_weight_from_layer; break;
1832 case plot_weight_from_object: return plot_weight_from_object; break;
1833 case plot_weight_from_parent: return plot_weight_from_parent; break;
1834 }
1835 return plot_weight_from_layer;
1836 }
1837
1838
ObjectLinetypeSource(int i)1839 ON::object_linetype_source ON::ObjectLinetypeSource(int i)
1840 {
1841 // convert integer to object_mode enum
1842 ON::object_linetype_source ls = linetype_from_layer;
1843 switch (i) {
1844 case linetype_from_layer: // use linetype assigned to layer
1845 ls = linetype_from_layer;
1846 break;
1847 case linetype_from_object: // use linetype assigned to object
1848 ls = linetype_from_object;
1849 break;
1850 case linetype_from_parent:
1851 ls = linetype_from_parent;
1852 break;
1853 }
1854 return ls;
1855 }
1856
ObjectMaterialSource(int i)1857 ON::object_material_source ON::ObjectMaterialSource(int i)
1858 {
1859 ON::object_material_source ms = material_from_layer;
1860 switch(i) {
1861 case material_from_layer:
1862 ms = material_from_layer;
1863 break;
1864 case material_from_object:
1865 ms = material_from_object;
1866 break;
1867 case material_from_parent:
1868 ms = material_from_parent;
1869 break;
1870 }
1871 return ms;
1872 }
1873
LightStyle(int i)1874 ON::light_style ON::LightStyle(int i)
1875 {
1876 // convert integer to light_style enum
1877 light_style ls = unknown_light_style;
1878 switch(i)
1879 {
1880 case unknown_light_style: ls = unknown_light_style; break;
1881 //case view_directional_light: ls = view_directional_light; break;
1882 //case view_point_light: ls = view_point_light; break;
1883 //case view_spot_light: ls = view_spot_light; break;
1884 case camera_directional_light: ls = camera_directional_light; break;
1885 case camera_point_light: ls = camera_point_light; break;
1886 case camera_spot_light: ls = camera_spot_light; break;
1887 case world_directional_light: ls = world_directional_light; break;
1888 case world_point_light: ls = world_point_light; break;
1889 case world_spot_light: ls = world_spot_light; break;
1890 case ambient_light: ls = ambient_light; break;
1891 case world_linear_light: ls = world_linear_light; break;
1892 case world_rectangular_light: ls = world_rectangular_light; break;
1893 }
1894 return ls;
1895 }
1896
CurvatureStyle(int i)1897 ON::curvature_style ON::CurvatureStyle(int i)
1898 {
1899 // convert integer to light_style enum
1900 ON::curvature_style cs = unknown_curvature_style;
1901 switch(i) {
1902 case gaussian_curvature:
1903 cs = gaussian_curvature;
1904 break;
1905 case mean_curvature:
1906 cs = mean_curvature;
1907 break;
1908 case min_curvature:
1909 // minimum unsigned radius of curvature
1910 cs = min_curvature;
1911 break;
1912 case max_curvature:
1913 // maximum unsigned radius of curvature
1914 cs = max_curvature;
1915 break;
1916 //case section_curvature_x:
1917 // unsigned normal curvature with respect to sections cut perp to world x axis
1918 //cs = section_curvature_x;
1919 //break;
1920 //case section_curvature_y:
1921 // unsigned normal curvature with respect to sections cut perp to world y axis
1922 //cs = section_curvature_y;
1923 //break;
1924 //case section_curvature_z:
1925 // unsigned normal curvature with respect to sections cut perp to world z axis
1926 //cs = section_curvature_z;
1927 //break;
1928 }
1929 return cs;
1930 }
1931
1932 /*enum view_type // This is already in the header. I commented it out to see if it would compile and it does. John Croudy.
1933 {
1934 model_view_type = 0,
1935 plot_page_view_type = 1,
1936 nested_view_type = 2
1937 };*/
1938
ViewType(int vt)1939 ON::view_type ON::ViewType(int vt)
1940 {
1941 switch(vt)
1942 {
1943 case model_view_type: return (model_view_type); break;
1944 case page_view_type: return (page_view_type); break;
1945 case nested_view_type: return (nested_view_type); break;
1946 }
1947
1948 return (model_view_type);
1949 }
1950
1951
DisplayMode(int i)1952 ON::display_mode ON::DisplayMode(int i)
1953 {
1954 // convert integer to light_style enum
1955 ON::display_mode dm = default_display;
1956 switch(i) {
1957 case default_display:
1958 dm = default_display;
1959 break;
1960 case wireframe_display:
1961 dm = wireframe_display;
1962 break;
1963 case shaded_display:
1964 dm = shaded_display;
1965 break;
1966 case renderpreview_display:
1967 dm = renderpreview_display;
1968 break;
1969 }
1970 return dm;
1971 }
1972
TextureMode(int i)1973 ON::texture_mode ON::TextureMode(int i)
1974 {
1975 // convert integer to texture_mode enum
1976 ON::texture_mode tm;
1977 switch (i) {
1978 case no_texture:
1979 tm = no_texture;
1980 break;
1981 case modulate_texture:
1982 tm = modulate_texture;
1983 break;
1984 case decal_texture:
1985 tm = decal_texture;
1986 break;
1987 default:
1988 tm = no_texture;
1989 break;
1990 }
1991 return tm;
1992 }
1993
ObjectType(int i)1994 ON::object_type ON::ObjectType(int i)
1995 {
1996 // convert integer to object_type enum
1997 object_type ot = unknown_object_type;
1998 switch(i)
1999 {
2000 case unknown_object_type: ot = unknown_object_type; break;
2001
2002 case point_object: ot = point_object; break;
2003 case pointset_object: ot = pointset_object; break;
2004 case curve_object: ot = curve_object; break;
2005 case surface_object: ot = surface_object; break;
2006 case brep_object: ot = brep_object; break;
2007 case mesh_object: ot = mesh_object; break;
2008 case layer_object: ot = layer_object; break;
2009 case material_object: ot = material_object; break;
2010 case light_object: ot = light_object; break;
2011 case annotation_object: ot = annotation_object; break;
2012 case userdata_object: ot = userdata_object; break;
2013 case instance_definition: ot = instance_definition; break;
2014 case instance_reference: ot = instance_reference; break;
2015 case text_dot: ot = text_dot; break;
2016 case grip_object: ot = grip_object; break;
2017 case detail_object: ot = detail_object; break;
2018 case hatch_object: ot = hatch_object; break;
2019 case morph_control_object: ot = morph_control_object; break;
2020 case loop_object: ot = loop_object; break;
2021 case polysrf_filter: ot = polysrf_filter; break;
2022 case edge_filter: ot = edge_filter; break;
2023 case polyedge_filter: ot = polyedge_filter; break;
2024 case meshvertex_object: ot = meshvertex_object; break;
2025 case meshedge_object: ot = meshedge_object; break;
2026 case meshface_object: ot = meshface_object; break;
2027 case cage_object: ot = cage_object; break;
2028 case phantom_object: ot = phantom_object; break;
2029 case extrusion_object: ot = extrusion_object; break;
2030
2031 default: ot = unknown_object_type; break;
2032 }
2033
2034 return ot;
2035 }
2036
BitmapType(int i)2037 ON::bitmap_type ON::BitmapType(int i)
2038 {
2039 // convert integer to object_type enum
2040 bitmap_type bt = unknown_bitmap_type;
2041 switch(i) {
2042 case unknown_bitmap_type: bt = unknown_bitmap_type; break;
2043 case windows_bitmap: bt = windows_bitmap; break;
2044 case opengl_bitmap: bt = opengl_bitmap; break;
2045 case png_bitmap: bt = png_bitmap; break;
2046 default: bt = unknown_bitmap_type; break;
2047 }
2048 return bt;
2049 }
2050
ObjectDecoration(int i)2051 ON::object_decoration ON::ObjectDecoration(int i)
2052 {
2053 ON::object_decoration d;
2054 switch(i)
2055 {
2056 case no_object_decoration: d = no_object_decoration; break;
2057 case start_arrowhead: d = start_arrowhead; break;
2058 case end_arrowhead: d = end_arrowhead; break;
2059 case both_arrowhead: d = both_arrowhead; break;
2060 default: d = no_object_decoration; break;
2061 }
2062 return d;
2063 }
2064
2065
OSnapMode(int i)2066 ON::osnap_mode ON::OSnapMode(int i)
2067 {
2068 ON::osnap_mode osm;
2069 switch((unsigned int)i)
2070 {
2071 case os_none: osm = os_none; break;
2072 case os_near: osm = os_near; break;
2073 case os_focus: osm = os_focus; break;
2074 case os_center: osm = os_center; break;
2075 case os_vertex: osm = os_vertex; break;
2076 case os_knot: osm = os_knot; break;
2077 case os_quadrant: osm = os_quadrant; break;
2078 case os_midpoint: osm = os_midpoint; break;
2079 case os_intersection: osm = os_intersection; break;
2080 case os_end: osm = os_end; break;
2081 case os_perpendicular: osm = os_perpendicular; break;
2082 case os_tangent: osm = os_tangent; break;
2083 case os_point: osm = os_point; break;
2084 case os_all_snaps: osm = os_all_snaps; break;
2085 default:
2086 osm = os_none;
2087 break;
2088 };
2089 return osm;
2090 }
2091
2092
CubicLoftEndCondition(int i)2093 ON::cubic_loft_end_condition ON::CubicLoftEndCondition(int i)
2094 {
2095 ON::cubic_loft_end_condition e;
2096 switch(i)
2097 {
2098 case cubic_loft_ec_quadratic:
2099 e = ON::cubic_loft_ec_quadratic;
2100 break;
2101 case cubic_loft_ec_linear:
2102 e = ON::cubic_loft_ec_linear;
2103 break;
2104 case cubic_loft_ec_cubic:
2105 e = ON::cubic_loft_ec_cubic;
2106 break;
2107 case cubic_loft_ec_natural:
2108 e = ON::cubic_loft_ec_natural;
2109 break;
2110 case cubic_loft_ec_unit_tangent:
2111 e = ON::cubic_loft_ec_unit_tangent;
2112 break;
2113 case cubic_loft_ec_1st_derivative:
2114 e = ON::cubic_loft_ec_1st_derivative;
2115 break;
2116 case cubic_loft_ec_2nd_derivative:
2117 e = ON::cubic_loft_ec_2nd_derivative;
2118 break;
2119 case cubic_loft_ec_free_cv:
2120 e = ON::cubic_loft_ec_free_cv;
2121 break;
2122 default:
2123 ON_ERROR("ON::CubicLoftEndCondition(i) value of i is not valid.");
2124 e = ON::cubic_loft_ec_quadratic;
2125 break;
2126 }
2127 return e;
2128 }
2129
2130
MeshType(int i)2131 ON::mesh_type ON::MeshType(int i)
2132 {
2133 mesh_type mt = default_mesh;
2134 switch(i)
2135 {
2136 case default_mesh: mt = default_mesh; break;
2137 case render_mesh: mt = render_mesh; break;
2138 case analysis_mesh: mt = analysis_mesh; break;
2139 case preview_mesh: mt = preview_mesh; break;
2140 case any_mesh: mt = any_mesh; break;
2141 default: mt = default_mesh; break;
2142 }
2143 return mt;
2144 }
2145
2146
AnnotationType(int i)2147 ON::eAnnotationType ON::AnnotationType(int i)
2148 {
2149 // convert integer to eAnnotationType enum
2150 eAnnotationType at = dtNothing;
2151 switch(i) {
2152 case dtNothing:
2153 at = dtNothing;
2154 break;
2155 case dtDimLinear:
2156 at = dtDimLinear;
2157 break;
2158 case dtDimAligned:
2159 at = dtDimAligned;
2160 break;
2161 case dtDimAngular:
2162 at = dtDimAngular;
2163 break;
2164 case dtDimDiameter:
2165 at = dtDimDiameter;
2166 break;
2167 case dtDimRadius:
2168 at = dtDimRadius;
2169 break;
2170 case dtLeader:
2171 at = dtLeader;
2172 break;
2173 case dtTextBlock:
2174 at = dtTextBlock;
2175 break;
2176 case dtDimOrdinate:
2177 at = dtDimOrdinate;
2178 break;
2179 }
2180 return at;
2181 }
2182
TextDisplayMode(int i)2183 ON::eTextDisplayMode ON::TextDisplayMode( int i)
2184 {
2185 eTextDisplayMode m = dtAboveLine;
2186 switch( i)
2187 {
2188 case dtHorizontal:
2189 m = dtHorizontal;
2190 break;
2191 case dtAboveLine:
2192 m = dtAboveLine;
2193 break;
2194 case dtInLine:
2195 m = dtInLine;
2196 break;
2197 }
2198 return m;
2199 }
2200
2201
2202 // Windows code page support
2203 // Only ON_SetStringConversionWindowsCodePage
2204 // and ON_GetStringConversionWindowsCodePage
2205 // should look at g_s__windows_code_page.
2206 static unsigned int g_s__windows_code_page = 0;
2207
ON_SetStringConversionWindowsCodePage(unsigned int code_page)2208 unsigned int ON_SetStringConversionWindowsCodePage( unsigned int code_page )
2209 {
2210 unsigned int prev_cp = g_s__windows_code_page;
2211 g_s__windows_code_page = code_page;
2212 return prev_cp;
2213 }
2214
ON_GetStringConversionWindowsCodePage()2215 unsigned int ON_GetStringConversionWindowsCodePage()
2216 {
2217 return g_s__windows_code_page;
2218 }
2219
2220 /*
2221 ON_TimeLimit::ON_TimeLimit()
2222 {
2223 m_time_limit[0] = 0;
2224 m_time_limit[1] = 0;
2225 }
2226
2227 ON_TimeLimit::ON_TimeLimit(ON__UINT64 time_limit_seconds)
2228 {
2229 SetTimeLimit(time_limit_seconds);
2230 }
2231
2232 void ON_TimeLimit::SetTimeLimit(ON__UINT64 time_limit_seconds)
2233 {
2234 m_time_limit[0] = 0;
2235 m_time_limit[1] = 0;
2236 if ( time_limit_seconds > 0 )
2237 {
2238 // This is a crude implementation that works
2239 // unless clock() is close to wrapping around
2240 // or time_limit_seconds is unreasonably large.
2241 clock_t max_ticks = (clock_t)(time_limit_seconds*((double)CLOCKS_PER_SEC));
2242 if ( max_ticks > 0 )
2243 {
2244 clock_t now_clock = ::clock();
2245 clock_t max_clock = max_ticks + now_clock;
2246 time_t ::time()
2247 if ( now_clock < max_clock )
2248 {
2249 *((clock_t*)(&m_time_limit[0])) = max_clock;
2250 }
2251 }
2252 }
2253 }
2254
2255 bool ON_TimeLimit::Continue() const
2256 {
2257 clock_t max_clock = *((clock_t*)&m_time_limit[0]);
2258 return ( max_clock <= 0 || ::clock() <= max_clock );
2259 }
2260
2261 bool ON_TimeLimit::IsSet() const
2262 {
2263 clock_t max_clock = *((clock_t*)&m_time_limit[0]);
2264 return ( max_clock > 0 );
2265 }
2266 */
2267