Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
GDI.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
5#include "Stroika/Foundation/Execution/Exceptions.h"
6
7namespace Stroika::Frameworks::Led {
8
9 /*
10 ********************************************************************************
11 ************************************ Point_Base ********************************
12 ********************************************************************************
13 */
14 template <typename COORD_TYPE>
15 constexpr Point_Base<COORD_TYPE>::Point_Base ()
16 : v (COORD_TYPE (0))
17 , h (COORD_TYPE (0))
18 {
19 }
20 template <typename COORD_TYPE>
21 constexpr Point_Base<COORD_TYPE>::Point_Base (COORD_TYPE newV, COORD_TYPE newH)
22 : v (newV)
23 , h (newH)
24 {
25 }
26 template <typename COORD_TYPE>
27 constexpr Point_Base<COORD_TYPE> operator+ (const Point_Base<COORD_TYPE>& lhs, const Point_Base<COORD_TYPE>& rhs)
28 {
29 Led_Point result = lhs;
30 result.v += rhs.v;
31 result.h += rhs.h;
32 return result;
33 }
34
35 /*
36 ********************************************************************************
37 ************************************ Led_Point *********************************
38 ********************************************************************************
39 */
40 inline Led_Point operator- (const Led_Point& lhs, const Led_Point& rhs)
41 {
42 return (Led_Point (lhs.v - rhs.v, lhs.h - rhs.h));
43 }
44
45 /*
46 ********************************************************************************
47 ************************************ Rect_Base *********************************
48 ********************************************************************************
49 */
50 template <typename POINT_TYPE, typename SIZE_TYPE>
51 /*
52 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::Rect_Base
53 @DESCRIPTION: <p>No-argument constructor leaves object uninitialized (garbage data).</p>
54 */
55 constexpr Rect_Base<POINT_TYPE, SIZE_TYPE>::Rect_Base ()
56 : top (CoordinateType (0))
57 , left (CoordinateType (0))
58 , bottom (CoordinateType (0))
59 , right (CoordinateType (0))
60 {
61 }
62 template <typename POINT_TYPE, typename SIZE_TYPE>
63 /*
64 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::Rect_Base
65 @DESCRIPTION: <p>Initialize with argument top, left, height, width.</p>
66 */
67 constexpr Rect_Base<POINT_TYPE, SIZE_TYPE>::Rect_Base (CoordinateType newTop, CoordinateType newLeft, DistanceType newHeight, DistanceType newWidth)
68 : top (newTop)
69 , left (newLeft)
70 , bottom (newTop + newHeight)
71 , right (newLeft + newWidth)
72 {
73 }
74 template <typename POINT_TYPE, typename SIZE_TYPE>
75 constexpr Rect_Base<POINT_TYPE, SIZE_TYPE>::Rect_Base (POINT_TYPE origin, SIZE_TYPE size)
76 : top (origin.v)
77 , left (origin.h)
78 , bottom (origin.v + size.v)
79 , right (origin.h + size.h)
80 {
81 }
82 template <typename POINT_TYPE, typename SIZE_TYPE>
83 /*
84 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetTop
85 @DESCRIPTION: <p>Retrieve top of rectangle.</p>
86 */
87 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::CoordinateType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetTop () const
88 {
89 return top;
90 }
91 template <typename POINT_TYPE, typename SIZE_TYPE>
92 /*
93 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetLeft
94 @DESCRIPTION: <p>Retrieve left of rectangle.</p>
95 */
96 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::CoordinateType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetLeft () const
97 {
98 return left;
99 }
100 template <typename POINT_TYPE, typename SIZE_TYPE>
101 /*
102 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetBottom
103 @DESCRIPTION: <p>Retrieve bottom of rectangle.</p>
104 */
105 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::CoordinateType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetBottom () const
106 {
107 return bottom;
108 }
109 template <typename POINT_TYPE, typename SIZE_TYPE>
110 /*
111 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetRight
112 @DESCRIPTION: <p>Retrieve right of rectangle.</p>
113 */
114 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::CoordinateType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetRight () const
115 {
116 return right;
117 }
118 template <typename POINT_TYPE, typename SIZE_TYPE>
119 /*
120 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::IsEmpty
121 @DESCRIPTION: <p>Returns true if either horizontal or vertical dimentions are less or equal to zero.</p>
122 */
123 inline bool Rect_Base<POINT_TYPE, SIZE_TYPE>::IsEmpty () const
124 {
125 return (right <= left or bottom <= top);
126 }
127 template <typename POINT_TYPE, typename SIZE_TYPE>
128 /*
129 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetHeight
130 @DESCRIPTION: <p>Asserts height is non-negative, and then returns height.</p>
131 */
132 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::DistanceType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetHeight () const
133 {
134 Ensure (bottom >= top);
135 return (bottom - top);
136 }
137 template <typename POINT_TYPE, typename SIZE_TYPE>
138 /*
139 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::GetWidth
140 @DESCRIPTION: <p>Asserts width is non-negative, and then returns width.</p>
141 */
142 inline typename Rect_Base<POINT_TYPE, SIZE_TYPE>::DistanceType Rect_Base<POINT_TYPE, SIZE_TYPE>::GetWidth () const
143 {
144 Ensure (right >= left);
145 return (right - left);
146 }
147 template <typename POINT_TYPE, typename SIZE_TYPE>
148 inline POINT_TYPE Rect_Base<POINT_TYPE, SIZE_TYPE>::GetTopLeft () const
149 {
150 return (POINT_TYPE (top, left));
151 }
152 template <typename POINT_TYPE, typename SIZE_TYPE>
153 inline POINT_TYPE Rect_Base<POINT_TYPE, SIZE_TYPE>::GetTopRight () const
154 {
155 return (POINT_TYPE (top, right));
156 }
157 template <typename POINT_TYPE, typename SIZE_TYPE>
158 inline POINT_TYPE Rect_Base<POINT_TYPE, SIZE_TYPE>::GetBotRight () const
159 {
160 return (POINT_TYPE (bottom, right));
161 }
162 template <typename POINT_TYPE, typename SIZE_TYPE>
163 inline POINT_TYPE Rect_Base<POINT_TYPE, SIZE_TYPE>::GetOrigin () const
164 {
165 return (POINT_TYPE (top, left));
166 }
167 template <typename POINT_TYPE, typename SIZE_TYPE>
168 inline SIZE_TYPE Rect_Base<POINT_TYPE, SIZE_TYPE>::GetSize () const
169 {
170 return (SIZE_TYPE (bottom - top, right - left));
171 }
172 template <typename POINT_TYPE, typename SIZE_TYPE>
173 inline bool Rect_Base<POINT_TYPE, SIZE_TYPE>::Contains (POINT_TYPE p) const
174 {
175 return ((p >= GetTopLeft ()) and (p <= GetBotRight ()));
176 }
177 template <typename POINT_TYPE, typename SIZE_TYPE>
178 inline bool Rect_Base<POINT_TYPE, SIZE_TYPE>::Contains (Rect_Base<POINT_TYPE, SIZE_TYPE> r) const
179 {
180 // could be more terse, but this does it...
181 return (Contains (r.GetTopLeft ()) and Contains (r.GetBotRight ()));
182 }
183 template <typename POINT_TYPE, typename SIZE_TYPE>
184 inline void Rect_Base<POINT_TYPE, SIZE_TYPE>::SetOrigin (POINT_TYPE p)
185 {
186 top = p.v;
187 left = p.h;
188 }
189 template <typename POINT_TYPE, typename SIZE_TYPE>
190 inline void Rect_Base<POINT_TYPE, SIZE_TYPE>::SetTop (CoordinateType t)
191 {
192 this->top = t;
193 }
194 template <typename POINT_TYPE, typename SIZE_TYPE>
195 inline void Rect_Base<POINT_TYPE, SIZE_TYPE>::SetLeft (CoordinateType l)
196 {
197 this->left = l;
198 }
199 template <typename POINT_TYPE, typename SIZE_TYPE>
200 inline void Rect_Base<POINT_TYPE, SIZE_TYPE>::SetBottom (CoordinateType b)
201 {
202 this->bottom = b;
203 }
204 template <typename POINT_TYPE, typename SIZE_TYPE>
205 inline void Rect_Base<POINT_TYPE, SIZE_TYPE>::SetRight (CoordinateType r)
206 {
207 this->right = r;
208 }
209 template <typename POINT_TYPE, typename SIZE_TYPE>
210 inline const Rect_Base<POINT_TYPE, SIZE_TYPE>& Rect_Base<POINT_TYPE, SIZE_TYPE>::operator+= (const POINT_TYPE& delta)
211 {
212 *this = THIS_TYPE (GetTopLeft () + delta, GetSize ()); // simple definition - but could tweek!
213 return *this;
214 }
215 template <typename POINT_TYPE, typename SIZE_TYPE>
216 inline const Rect_Base<POINT_TYPE, SIZE_TYPE>& Rect_Base<POINT_TYPE, SIZE_TYPE>::operator-= (const POINT_TYPE& delta)
217 {
218 *this = THIS_TYPE (GetTopLeft () - delta, GetSize ()); // simple definition - but could tweek!
219 return *this;
220 }
221 template <typename POINT_TYPE, typename SIZE_TYPE>
222 /*
223 @METHOD: Rect_Base<POINT_TYPE,SIZE_TYPE>::operator*=
224 @DESCRIPTION: <p>Intersects this rect with the argument rectangle.</p>
225 */
226 inline const Rect_Base<POINT_TYPE, SIZE_TYPE>& Rect_Base<POINT_TYPE, SIZE_TYPE>::operator*= (const Rect_Base<POINT_TYPE, SIZE_TYPE>& intersectWith)
227 {
228 POINT_TYPE topLeft = max (GetTopLeft (), intersectWith.GetTopLeft ());
229 POINT_TYPE botRight = min (GetBotRight (), intersectWith.GetBotRight ());
230 POINT_TYPE newSize = botRight - topLeft;
231 if (newSize >= Led_Point (0, 0)) {
232 *this = THIS_TYPE (topLeft, SIZE_TYPE (newSize));
233 }
234 else {
235 *this = THIS_TYPE (0, 0, 0, 0);
236 }
237 return *this;
238 }
239 template <typename POINT_TYPE, typename SIZE_TYPE>
240 inline bool Rect_Base<POINT_TYPE, SIZE_TYPE>::operator== (const Rect_Base<POINT_TYPE, SIZE_TYPE>& rhs) const
241 {
242 return ((GetLeft () == rhs.GetLeft ()) and (GetRight () == rhs.GetRight ()) and (GetTop () == rhs.GetTop ()) and
243 (GetBottom () == rhs.GetBottom ()));
244 }
245
246 /*
247 ********************************************************************************
248 ************************************ TWIPS *************************************
249 ********************************************************************************
250 */
251 constexpr inline TWIPS::TWIPS (long v)
252 : fValue (v)
253 {
254 }
255 constexpr TWIPS::operator long () const
256 {
257 return fValue;
258 }
259 inline TWIPS& TWIPS::operator+= (const TWIPS& rhs)
260 {
261 fValue += rhs.fValue;
262 return *this;
263 }
264 inline TWIPS& TWIPS::operator-= (const TWIPS& rhs)
265 {
266 fValue -= rhs.fValue;
267 return *this;
268 }
269 inline TWIPS& TWIPS::operator*= (double rhs)
270 {
271 fValue = static_cast<long> (fValue * rhs);
272 return *this;
273 }
274 inline TWIPS operator+ (const TWIPS& lhs, const TWIPS& rhs)
275 {
276 return TWIPS (static_cast<long> (lhs) + static_cast<long> (rhs));
277 }
278 inline TWIPS operator- (const TWIPS& lhs, const TWIPS& rhs)
279 {
280 return TWIPS (static_cast<long> (lhs) - static_cast<long> (rhs));
281 }
282 inline constexpr TWIPS TWIPS::kPoint = TWIPS{20}; // a printers 'point' (1/72 of an inch)
283 inline constexpr TWIPS TWIPS::kInch = TWIPS{1440};
284 inline constexpr TWIPS TWIPS::kOneInch = TWIPS{1440};
285
286#if qStroika_Foundation_Common_Platform_Windows
287 /*
288 ********************************************************************************
289 ******************************** FontObject ************************************
290 ********************************************************************************
291 */
292 inline FontObject::~FontObject ()
293 {
294 (void)DeleteObject ();
295 }
296 inline FontObject ::operator HFONT () const
297 {
298 return m_hObject;
299 }
300 inline int FontObject ::GetObject (int nCount, LPVOID lpObject) const
301 {
302 Assert (m_hObject != nullptr);
303 return ::GetObject (m_hObject, nCount, lpObject);
304 }
305 inline BOOL FontObject ::DeleteObject ()
306 {
307 if (m_hObject == nullptr)
308 return FALSE;
309 HFONT h = m_hObject;
310 m_hObject = nullptr;
311 return ::DeleteObject (h);
312 }
313 inline BOOL FontObject ::CreateFontIndirect (const LOGFONT* lpLogFont)
314 {
315 return Attach (::CreateFontIndirect (lpLogFont));
316 }
317 inline BOOL FontObject ::Attach (HFONT hObject)
318 {
319 Assert (m_hObject == nullptr); // only attach once, detach on destroy
320 if (hObject == nullptr)
321 return FALSE;
322 m_hObject = hObject;
323 return TRUE;
324 }
325#endif
326
327#if qStroika_Foundation_Common_Platform_Windows
328 /*
329 ********************************************************************************
330 *********************************** Brush **************************************
331 ********************************************************************************
332 */
333 inline Brush::Brush (COLORREF crColor)
334 : m_hObject{nullptr}
335 {
336 if (!Attach (::CreateSolidBrush (crColor)))
337 Foundation::Execution::Throw (bad_alloc{});
338 }
339 inline Brush::~Brush ()
340 {
341 (void)DeleteObject ();
342 }
343 inline Brush::operator HBRUSH () const
344 {
345 return m_hObject;
346 }
347 inline BOOL Brush::Attach (HBRUSH hObject)
348 {
349 Assert (m_hObject == nullptr); // only attach once, detach on destroy
350 if (hObject == nullptr)
351 return FALSE;
352 m_hObject = hObject;
353 return TRUE;
354 }
355 inline BOOL Brush::DeleteObject ()
356 {
357 if (m_hObject == nullptr)
358 return FALSE;
359 HBRUSH h = m_hObject;
360 m_hObject = nullptr;
361 return ::DeleteObject (h);
362 }
363#endif
364
365#if qStroika_Frameworks_Led_SupportGDI
366 /*
367 ********************************************************************************
368 ************************************ Region ************************************
369 ********************************************************************************
370 */
371 inline Region::Region ()
372#if qStroika_Foundation_Common_Platform_Windows
373 : fRgn{::CreateRectRgn (0, 0, 0, 0)}
374#endif
375 {
376#if qStroika_Foundation_Common_Platform_Windows
377 Foundation::Execution::ThrowIfNull (fRgn);
378#endif
379 }
380 inline Region::Region (const Led_Rect& r)
381#if qStroika_Foundation_Common_Platform_Windows
382 : fRgn (::CreateRectRgn (r.GetLeft (), r.GetTop (), r.GetRight (), r.GetBottom ()))
383#endif
384 {
385 Require (r.GetHeight () >= 0);
386 Require (r.GetWidth () >= 0);
387#if qStroika_Foundation_Common_Platform_Windows
388 Foundation::Execution::ThrowIfNull (fRgn);
389#endif
390 Assert (GetBoundingRect () == r or (GetBoundingRect ().IsEmpty () and r.IsEmpty ()));
391 }
392 inline Region::Region (const Region& from)
393#if qStroika_Foundation_Common_Platform_Windows
394 : fRgn (::CreateRectRgn (0, 0, 0, 0))
395#endif
396 {
397#if qStroika_Foundation_Common_Platform_Windows
398 Foundation::Execution::ThrowIfNull (fRgn);
399#endif
400#if qStroika_Foundation_Common_Platform_Windows
401 Verify (::CombineRgn (fRgn, from, from, RGN_COPY) != ERROR);
402#endif
403 }
404 inline const Region& Region::operator= (const Region& rhs)
405 {
406#if qStroika_Foundation_Common_Platform_Windows
407 Verify (::CombineRgn (fRgn, rhs, rhs, RGN_COPY) != ERROR);
408#endif
409#if qStroika_Foundation_Common_Platform_Windows
410 Foundation::Execution::ThrowIfNull (fRgn);
411#endif
412 return *this;
413 }
414 inline Region::~Region ()
415 {
416#if qStroika_Foundation_Common_Platform_Windows
417 if (fRgn != nullptr) {
418 ::DeleteObject (fRgn);
419 }
420#endif
421 }
422 inline bool Region::IsEmpty () const
423 {
424#if qStroika_Foundation_Common_Platform_Windows
425 AssertNotNull (fRgn);
426#endif
427 Assert (false); //NYI - not used yet - so don't worry about this right now... LGP 2002-12-03
428 return false;
429 }
430 inline Led_Rect Region::GetBoundingRect () const
431 {
432#if qStroika_Foundation_Common_Platform_Windows
433 AssertNotNull (fRgn);
434 RECT r;
435 int tmp = ::GetRgnBox (fRgn, &r);
436 Verify (tmp != 0);
438 if (tmp == 0) {
439 Assert (AsLedRect (r) == Led_Rect (0, 0, 0, 0));
440 }
441 }
442 return AsLedRect (r);
443#else
444 Assert (false);
445 return Led_Rect (0, 0, 0, 0);
446#endif
447 }
448 inline Region operator* (const Region& lhs, const Region& rhs)
449 {
450 Region result;
451#if qStroika_Foundation_Common_Platform_Windows
452 Verify (::CombineRgn (result, lhs, rhs, RGN_AND) != ERROR);
453#endif
454 return result;
455 }
456 inline Region operator+ (const Region& lhs, const Region& rhs)
457 {
458 Region result;
459#if qStroika_Foundation_Common_Platform_Windows
460 Verify (::CombineRgn (result, lhs, rhs, RGN_OR) != ERROR);
461#endif
462 return result;
463 }
464 inline Led_Rect operator* (const Led_Rect& lhs, const Led_Rect& rhs)
465 {
466 Led_Rect tmp = lhs;
467 return tmp *= rhs;
468 }
469#if qStroika_Foundation_Common_Platform_Windows
470 inline Region::operator HRGN () const
471 {
472 return fRgn;
473 }
474 inline int Region::CombineRgn (Region* pRgn1, Region* pRgn2, int nCombineMode)
475 {
476 Require (pRgn1 != nullptr);
477 Require (pRgn2 != nullptr);
478 Require (fRgn != nullptr);
479 return ::CombineRgn (fRgn, pRgn1->fRgn, pRgn2->fRgn, nCombineMode);
480 }
481 inline BOOL Region::PtInRegion (int x, int y) const
482 {
483 Require (fRgn != nullptr);
484 return ::PtInRegion (fRgn, x, y);
485 }
486 inline BOOL Region::PtInRegion (POINT point) const
487 {
488 Require (fRgn != nullptr);
489 return ::PtInRegion (fRgn, point.x, point.y);
490 }
491
492 inline BOOL Region::DeleteObject ()
493 {
494 if (fRgn == nullptr)
495 return FALSE;
496 HRGN r = fRgn;
497 fRgn = nullptr;
498 return ::DeleteObject (r);
499 }
500#endif
501#endif
502
503 /*
504 ********************************************************************************
505 ************************************ TabStopList *******************************
506 ********************************************************************************
507 */
508#if qStroika_Frameworks_Led_SupportGDI
509 inline DistanceType TabStopList::ComputeTabStopAfterPosition (Tablet* tablet, DistanceType afterPos) const
510 {
511 RequireNotNull (tablet);
512 return tablet->CvtFromTWIPSH (ComputeTabStopAfterPosition (tablet->CvtToTWIPSH (afterPos)));
513 }
514#endif
515
516#if qStroika_Foundation_Common_Platform_Windows
517 /*
518 ********************************************************************************
519 **************************************** Bitmap ********************************
520 ********************************************************************************
521 */
522 inline Bitmap::~Bitmap ()
523 {
524 if (m_hObject != nullptr) {
525 ::DeleteObject (m_hObject);
526 }
527 }
528 inline void Bitmap::DeleteObject ()
529 {
530 if (m_hObject != nullptr) {
531 ::DeleteObject (m_hObject);
532 m_hObject = nullptr;
533 }
534 }
535 inline Bitmap::operator HBITMAP () const
536 {
537 return m_hObject;
538 }
539 inline Led_Size Bitmap::GetImageSize () const
540 {
541 // only valid if m_hObject != nullptr
542 RequireNotNull (m_hObject);
543 return fImageSize;
544 }
545#endif
546
547#if qStroika_Frameworks_Led_SupportGDI
548 /*
549 ********************************************************************************
550 **************************************** Tablet ********************************
551 ********************************************************************************
552 */
553#if qStroika_Foundation_Common_Platform_Windows
554 inline Tablet::operator HDC () const
555 {
556 return m_hDC;
557 }
558#endif
559 /*
560 @METHOD: Tablet::CvtFromTWIPSV
561 @DESCRIPTION:
562 <p>See also @'Tablet::CvtFromTWIPSH', @'Tablet::CvtToTWIPSV', @'Tablet::CvtToTWIPSH'.</p>
563 */
564 inline CoordinateType Tablet::CvtFromTWIPSV (TWIPS from) const
565 {
566#if qStroika_Foundation_Common_Platform_Windows
567 if (fLogPixelsV == 0) {
568 fLogPixelsV = GetDeviceCaps (LOGPIXELSY);
569 }
570 POINT vpOrg;
571 Verify (::GetViewportOrgEx (m_hAttribDC, &vpOrg));
572 POINT wOrg;
573 Verify (::GetWindowOrgEx (m_hAttribDC, &wOrg));
574 POINT x = vpOrg;
575 x.y += ::MulDiv (from, fLogPixelsV, 1440);
576 Verify (::DPtoLP (m_hAttribDC, &x, 1));
577 x.y -= wOrg.y;
578 Assert (x.x == wOrg.x);
579 return x.y;
580#else
581 //TMPHACK - look at tablet resolution?
582 return from * Globals::Get ().GetMainScreenLogPixelsV () / 1440;
583// return from / 20; // assume 72dpi on mac
584#endif
585 }
586 /*
587 @METHOD: Tablet::CvtFromTWIPSH
588 @DESCRIPTION:
589 <p>See also @'Tablet::CvtFromTWIPSV', @'Tablet::CvtToTWIPSV', @'Tablet::CvtToTWIPSH'.</p>
590 */
591 inline CoordinateType Tablet::CvtFromTWIPSH (TWIPS from) const
592 {
593#if qStroika_Foundation_Common_Platform_Windows
594 if (fLogPixelsH == 0) {
595 fLogPixelsH = GetDeviceCaps (LOGPIXELSX);
596 }
597 POINT vpOrg;
598 Verify (::GetViewportOrgEx (m_hAttribDC, &vpOrg));
599 POINT wOrg;
600 Verify (::GetWindowOrgEx (m_hAttribDC, &wOrg));
601 POINT x = vpOrg;
602 x.x += ::MulDiv (from, fLogPixelsH, 1440);
603 Verify (::DPtoLP (m_hAttribDC, &x, 1));
604 x.x -= wOrg.x;
605 Assert (x.y == wOrg.y);
606 return x.x;
607#else
608 //TMPHACK - look at tablet resolution?
609 return from * Globals::Get ().GetMainScreenLogPixelsH () / 1440;
610// return from / 20; // assume 72dpi on mac
611#endif
612 }
613 /*
614 @METHOD: Tablet::CvtToTWIPSV
615 @DESCRIPTION: <p>Utility routine to convert from logical coordinates (usually pixels) to TWIPS.</p>
616 <p>See also @'Tablet::CvtFromTWIPSV', @'Tablet::CvtFromTWIPSH', @'Tablet::CvtToTWIPSH'.</p>
617 */
618 inline TWIPS Tablet::CvtToTWIPSV (CoordinateType from) const
619 {
620#if qStroika_Foundation_Common_Platform_Windows
621 if (fLogPixelsV == 0) {
622 fLogPixelsV = GetDeviceCaps (LOGPIXELSY);
623 }
624 POINT vpOrg;
625 Verify (::GetViewportOrgEx (m_hAttribDC, &vpOrg));
626 POINT wOrg;
627 Verify (::GetWindowOrgEx (m_hAttribDC, &wOrg));
628 POINT x = wOrg;
629 x.y += from;
630 Verify (::LPtoDP (m_hAttribDC, &x, 1));
631 x.y -= vpOrg.y;
632 Assert (x.x == wOrg.x);
633 return TWIPS (::MulDiv (x.y, 1440, fLogPixelsV));
634#else
635 return TWIPS (from * 1440 / Globals::Get ().GetMainScreenLogPixelsV ());
636// return TWIPS (from * 20); // assume 72dpi on mac
637#endif
638 }
639 /*
640 @METHOD: Tablet::CvtToTWIPSH
641 @DESCRIPTION: <p>Utility routine to convert from logical coordinates (usually pixels) to TWIPS.</p>
642 <p>See also @'Tablet::CvtFromTWIPSV', @'Tablet::CvtFromTWIPSH', @'Tablet::CvtToTWIPSV'.</p>
643 */
644 inline TWIPS Tablet::CvtToTWIPSH (CoordinateType from) const
645 {
646#if qStroika_Foundation_Common_Platform_Windows
647 if (fLogPixelsH == 0) {
648 fLogPixelsH = GetDeviceCaps (LOGPIXELSX);
649 }
650 POINT vpOrg;
651 Verify (::GetViewportOrgEx (m_hAttribDC, &vpOrg));
652 POINT wOrg;
653 Verify (::GetWindowOrgEx (m_hAttribDC, &wOrg));
654 POINT x = wOrg;
655 x.x += from;
656 Verify (::LPtoDP (m_hAttribDC, &x, 1));
657 x.x -= vpOrg.x;
658 Assert (x.y == vpOrg.y);
659 return TWIPS (::MulDiv (x.x, 1440, fLogPixelsH));
660#else
661 return TWIPS (from * 1440 / Globals::Get ().GetMainScreenLogPixelsH ());
662// return TWIPS (from * 20); // assume 72dpi on mac
663#endif
664 }
665#if qStroika_Foundation_Common_Platform_Windows
666 inline BOOL Tablet::BitBlt (int x, int y, int nWidth, int nHeight, Tablet* pSrcDC, int xSrc, int ySrc, DWORD dwRop)
667 {
668 AssertNotNull (m_hDC);
669 return ::BitBlt (m_hDC, x, y, nWidth, nHeight, pSrcDC->m_hDC, xSrc, ySrc, dwRop);
670 }
671 inline BOOL Tablet::CreateCompatibleDC (Tablet* pDC)
672 {
673 Assert (m_hDC == nullptr); // only attach once, detach on destroy
674 Assert (m_hAttribDC == nullptr); // only attach to an empty DC
675
676 m_hDC = ::CreateCompatibleDC (pDC == nullptr ? nullptr : pDC->m_hDC);
677 if (m_hDC == nullptr)
678 return FALSE;
679
680 m_hAttribDC = m_hDC;
681 fOwnsDC = eOwnsDC;
682 return TRUE;
683 }
684 inline COLORREF Tablet::SetTextColor (COLORREF crColor)
685 {
686 Assert (m_hDC != nullptr);
687 COLORREF crRetVal = CLR_INVALID;
688
689 if (m_hDC != m_hAttribDC)
690 crRetVal = ::SetTextColor (m_hDC, crColor);
691 if (m_hAttribDC != nullptr)
692 crRetVal = ::SetTextColor (m_hAttribDC, crColor);
693 return crRetVal;
694 }
695 inline COLORREF Tablet::SetBkColor (COLORREF crColor)
696 {
697 Assert (m_hDC != nullptr);
698 COLORREF crRetVal = CLR_INVALID;
699
700 if (m_hDC != m_hAttribDC)
701 crRetVal = ::SetBkColor (m_hDC, crColor);
702 if (m_hAttribDC != nullptr)
703 crRetVal = ::SetBkColor (m_hAttribDC, crColor);
704 return crRetVal;
705 }
706 inline HWND Tablet::GetWindow () const
707 {
708 Assert (m_hDC != nullptr);
709 return ::WindowFromDC (m_hDC);
710 }
711 inline BOOL Tablet::IsPrinting () const
712 {
713 return m_bPrinting;
714 }
715 inline BOOL Tablet::RoundRect (int x1, int y1, int x2, int y2, int x3, int y3)
716 {
717 Assert (m_hDC != nullptr);
718 return ::RoundRect (m_hDC, x1, y1, x2, y2, x3, y3);
719 }
720 inline BOOL Tablet::TextOut (int x, int y, LPCTSTR lpszString, int nCount)
721 {
722 Assert (m_hDC != nullptr);
723 return ::TextOut (m_hDC, x, y, lpszString, nCount);
724 }
725 inline int Tablet::SetBkMode (int nBkMode)
726 {
727 Assert (m_hDC != nullptr);
728 int nRetVal = 0;
729
730 if (m_hDC != m_hAttribDC)
731 nRetVal = ::SetBkMode (m_hDC, nBkMode);
732 if (m_hAttribDC != nullptr)
733 nRetVal = ::SetBkMode (m_hAttribDC, nBkMode);
734 return nRetVal;
735 }
736 inline unsigned int Tablet::SetTextAlign (unsigned int nTextAlign)
737 {
738 Assert (m_hDC != nullptr);
739 unsigned int nRetVal = 0;
740
741 if (m_hDC != m_hAttribDC)
742 nRetVal = ::SetTextAlign (m_hDC, nTextAlign);
743 if (m_hAttribDC != nullptr)
744 nRetVal = ::SetTextAlign (m_hAttribDC, nTextAlign);
745 return nRetVal;
746 }
747 inline SIZE Tablet::GetWindowExt () const
748 {
749 Assert (m_hAttribDC != nullptr);
750 SIZE size;
751 Verify (::GetWindowExtEx (m_hAttribDC, &size));
752 return size;
753 }
754 inline SIZE Tablet::GetViewportExt () const
755 {
756 Assert (m_hAttribDC != nullptr);
757 SIZE size;
758 Verify (::GetViewportExtEx (m_hAttribDC, &size));
759 return size;
760 }
761 inline BOOL Tablet::Rectangle (int x1, int y1, int x2, int y2)
762 {
763 Assert (m_hDC != nullptr);
764 return ::Rectangle (m_hDC, x1, y1, x2, y2);
765 }
766 inline BOOL Tablet::Rectangle (const RECT& r)
767 {
768 Assert (m_hDC != nullptr);
769 return ::Rectangle (m_hDC, r.left, r.top, r.right, r.bottom);
770 }
771 inline BOOL Tablet::Rectangle (LPCRECT lpRect)
772 {
773 Assert (m_hDC != nullptr);
774 return ::Rectangle (m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
775 }
776 inline BOOL Tablet::GetTextMetrics (LPTEXTMETRIC lpMetrics) const
777 {
778 Assert (m_hAttribDC != nullptr);
779 return ::GetTextMetrics (m_hAttribDC, lpMetrics);
780 }
781 inline HBITMAP Tablet::SelectObject (HBITMAP hBitmap)
782 {
783 Assert (m_hDC != nullptr);
784 return (HBITMAP)::SelectObject (m_hDC, hBitmap);
785 }
786#if defined(STRICT)
787 inline HFONT Tablet::SelectObject (HFONT hFont)
788 {
789 Assert (m_hDC != nullptr);
790 return (HFONT)::SelectObject (m_hDC, hFont);
791 }
792#endif
793 inline POINT Tablet::SetWindowOrg (int x, int y)
794 {
795 Assert (m_hDC != nullptr);
796 POINT point;
797 memset (&point, 0, sizeof (point));
798 if (m_hDC != m_hAttribDC)
799 Verify (::SetWindowOrgEx (m_hDC, x, y, &point));
800 if (m_hAttribDC != nullptr)
801 Verify (::SetWindowOrgEx (m_hAttribDC, x, y, &point));
802 return point;
803 }
804 inline int Tablet::GetDeviceCaps (int nIndex) const
805 {
806 Assert (m_hAttribDC != nullptr);
807 return ::GetDeviceCaps (m_hAttribDC, nIndex);
808 }
809 inline BOOL Tablet::Attach (HDC hDC, Tablet::OwnDCControl ownsDC)
810 {
811 Assert (m_hDC == nullptr); // only attach once, detach on destroy
812 Assert (m_hAttribDC == nullptr); // only attach to an empty DC
813
814 if (hDC == nullptr)
815 return FALSE;
816
817 m_hDC = hDC;
818 m_hAttribDC = m_hDC; // Default to same as output
819 fOwnsDC = ownsDC;
820 return TRUE;
821 }
822 inline HDC Tablet::Detach ()
823 {
824 HDC hDC = m_hDC;
825 m_hAttribDC = nullptr;
826 m_hDC = nullptr;
827 return hDC;
828 }
829#endif
830 inline void Tablet::MoveTo (const Led_Point& to)
831 {
832#if qStroika_Foundation_Common_Platform_Windows
833 Assert (m_hDC != nullptr);
834 Verify (::MoveToEx (m_hDC, to.h, to.v, nullptr));
835#elif qStroika_FeatureSupported_XWindows
836 fCurDrawLineLoc = to;
837#endif
838 }
839 inline void Tablet::LineTo (const Led_Point& to)
840 {
841#if qStroika_Foundation_Common_Platform_Windows
842 Assert (m_hDC != nullptr);
843 Verify (::LineTo (m_hDC, to.h, to.v));
844#elif qStroika_FeatureSupported_XWindows
845 ::XDrawLine (fDisplay, fDrawable, fGC, fCurDrawLineLoc.h, fCurDrawLineLoc.v, to.h, to.v);
846 fCurDrawLineLoc = to;
847#endif
848 }
849 inline Region Tablet::GetClip () const
850 {
851 Region result;
852#if qStroika_Foundation_Common_Platform_Windows
853 int r = ::GetClipRgn (*this, result);
854 Assert (r == 0 or r == 1 or r == -1);
855 if (r == 0) {
856#if !qInternalErrorWithStaticRegionDeclaredInFunction
857 static
858#endif
859 Region kWideOpened = Region (Led_Rect (-10000, -10000, 20000, 20000));
860 result = kWideOpened;
861 }
862#else
863 Assert (false); // NYI
864#endif
865 return result;
866 }
867 inline bool Tablet::GetClip (Region* r) const
868 {
869 RequireNotNull (r);
870#if qStroika_Foundation_Common_Platform_Windows
871 int res = ::GetClipRgn (*this, *r);
872 Assert (res == 0 or res == 1 or res == -1);
873 if (res == 0) {
874 return false;
875 }
876 return true;
877#else
878 Assert (false); // NYI
879 return false;
880#endif
881 }
882 inline void Tablet::SetClip ()
883 {
884#if qStroika_Foundation_Common_Platform_Windows
885 Verify (::SelectClipRgn (*this, nullptr) != ERROR);
886#elif qStroika_FeatureSupported_XWindows
887 static Led_Rect kWideOpened = Led_Rect (-10000, -10000, 20000, 20000);
888 XRectangle xrectangle = AsXRect (kWideOpened);
889 ::XSetClipRectangles (fDisplay, fGC, 0, 0, &xrectangle, 1, Unsorted);
890#else
891 Assert (false); // NYI
892#endif
893 }
894 inline void Tablet::SetClip (const Led_Rect& clipTo)
895 {
896#if qStroika_Foundation_Common_Platform_Windows
897 Verify (::SelectClipRgn (*this, Region (clipTo)) != ERROR);
898 Ensure (GetClip ().GetBoundingRect () == clipTo);
899#elif qStroika_FeatureSupported_XWindows
900 XRectangle xrectangle = AsXRect (clipTo);
901 ::XSetClipRectangles (fDisplay, fGC, 0, 0, &xrectangle, 1, Unsorted);
902#else
903 Assert (false); // NYI
904#endif
905 }
906 inline void Tablet::SetClip (const Region& clipTo)
907 {
908#if qStroika_Foundation_Common_Platform_Windows
909 Verify (::SelectClipRgn (*this, clipTo) != ERROR);
910#else
911 Assert (false); // NYI
912#endif
913 }
914#endif
915
916#if qStroika_Frameworks_Led_SupportGDI
917 /*
918 ********************************************************************************
919 ****************************************** Globals *****************************
920 ********************************************************************************
921 */
922 inline Globals& Globals::Get ()
923 {
924 if (sThe == nullptr) {
925 sThe = new Globals ();
926 }
927 return *sThe;
928 }
929 inline DistanceType Globals::GetMainScreenLogPixelsH () const
930 {
931 return fLogPixelsH;
932 }
933 inline DistanceType Globals::GetMainScreenLogPixelsV () const
934 {
935 return fLogPixelsV;
936 }
937#endif
938
939 /*
940 ********************************************************************************
941 *********************************** Led_Rect ***********************************
942 ********************************************************************************
943 */
944 inline Led_Rect operator- (const Led_Rect& lhs, const Led_Point& rhs)
945 {
946 return Led_Rect (lhs.GetTop () - rhs.v, lhs.GetLeft () - rhs.h, lhs.GetHeight (), lhs.GetWidth ());
947 }
948 inline Led_Rect operator+ (Led_Point p, Led_Rect r)
949 {
950 return (Led_Rect (r.GetTop () + p.v, r.GetLeft () + p.h, r.GetHeight (), r.GetWidth ()));
951 }
952 inline Led_Rect operator+ (Led_Rect r, Led_Point p)
953 {
954 return (Led_Rect (r.GetTop () + p.v, r.GetLeft () + p.h, r.GetHeight (), r.GetWidth ()));
955 }
956
957 /*
958 ********************************************************************************
959 *********************************** Intersect **********************************
960 ********************************************************************************
961 */
962 inline bool Intersect (const Led_Rect& lhs, const Led_Rect& rhs)
963 {
964 if (rhs.GetTop () >= lhs.GetBottom ()) {
965 return false;
966 }
967 else if (rhs.GetBottom () <= lhs.GetTop ()) {
968 return false;
969 }
970 else if (rhs.GetLeft () >= lhs.GetRight ()) {
971 return false;
972 }
973 else if (rhs.GetRight () <= lhs.GetLeft ()) {
974 return false;
975 }
976
977 if (rhs.GetHeight () == 0 or rhs.GetWidth () == 0 or lhs.GetHeight () == 0 or lhs.GetWidth () == 0) {
978 return false;
979 }
980 return true;
981 }
982#if qStroika_Frameworks_Led_SupportGDI
983 inline bool Intersect (const Led_Rect& lhs, const Region& rhs)
984 {
985#if qStroika_Foundation_Common_Platform_Windows
986 Region lhsRgn = lhs;
987 Region result;
988 return result.CombineRgn (&lhsRgn, const_cast<Region*> (&rhs), RGN_AND) != NULLREGION;
989#endif
990 }
991 inline bool Intersect (const Region& lhs, const Led_Rect& rhs)
992 {
993#if qStroika_Foundation_Common_Platform_Windows
994 Region rhsRgn = rhs;
995 Region result;
996 return result.CombineRgn (const_cast<Region*> (&lhs), &rhsRgn, RGN_AND) != NULLREGION;
997#endif
998 }
999 inline bool Intersect (const Region& lhs, const Region& rhs)
1000 {
1001#if qStroika_Foundation_Common_Platform_Windows
1002 Region result;
1003 return result.CombineRgn (const_cast<Region*> (&lhs), const_cast<Region*> (&rhs), RGN_AND) != NULLREGION;
1004#endif
1005 }
1006#endif
1007
1008 /*
1009 ********************************************************************************
1010 ******************************** Intersection **********************************
1011 ********************************************************************************
1012 */
1013 inline Led_Rect Intersection (const Led_Rect& lhs, const Led_Rect& rhs)
1014 {
1015 Led_Rect tmp = lhs;
1016 return tmp *= rhs;
1017 }
1018
1019 /*
1020 ********************************************************************************
1021 ************************************ Led_Size **********************************
1022 ********************************************************************************
1023 */
1024 inline Led_Size operator+ (Led_Size lhs, Led_Size rhs)
1025 {
1026 return Led_Size (lhs.v + rhs.v, lhs.h + rhs.h);
1027 }
1028 inline Led_Size operator* (int lhs, Led_Size rhs)
1029 {
1030 return Led_Size (lhs * rhs.v, lhs * rhs.h);
1031 }
1032
1033 /*
1034 ********************************************************************************
1035 *********************************** InsetRect **********************************
1036 ********************************************************************************
1037 */
1038 /*
1039 @METHOD: InsetRect
1040 @DESCRIPTION: <p>Utility routine to convert shrink (if vBy/hBy posative), or expand (if negative) the given @'Led_Rect'.
1041 NB: This routine pins the minimum output rect size (in each dimention) to be zero.</p>
1042 */
1043 inline Led_Rect InsetRect (const Led_Rect& r, int vBy, int hBy)
1044 {
1045 return Led_Rect (r.GetTop () + vBy, r.GetLeft () + hBy, max (0L, CoordinateType (r.GetHeight ()) - 2 * vBy),
1046 max (0L, CoordinateType (r.GetWidth ()) - 2 * hBy));
1047 }
1048
1049 /*
1050 ********************************************************************************
1051 *********************************** EnsureRectInRect ***************************
1052 ********************************************************************************
1053 */
1054 /*
1055 @METHOD: EnsureRectInRect
1056 @DESCRIPTION: <p>Utility routine to ensure the first rect is entirely enclosed in the second (enclosing) rectangle.
1057 Pin the edges so it fits.</p>
1058 */
1059 inline Led_Rect EnsureRectInRect (const Led_Rect& r, Led_Rect enlosingR)
1060 {
1061 DistanceType winWidth = min (r.GetWidth (), enlosingR.GetWidth ());
1062 DistanceType winHeight = min (r.GetHeight (), enlosingR.GetHeight ());
1063 CoordinateType winLeft = max (r.GetLeft (), enlosingR.GetLeft ());
1064 CoordinateType winTop = max (r.GetTop (), enlosingR.GetTop ());
1065
1066 DISABLE_COMPILER_MSC_WARNING_START (4018) //signed/unsigned mismatch
1067 if ((winLeft + winWidth) > enlosingR.GetRight ()) {
1068 winLeft = enlosingR.GetRight () - winWidth;
1069 }
1070 if ((winTop + winHeight) > enlosingR.GetBottom ()) {
1071 winTop = enlosingR.GetBottom () - winHeight;
1072 }
1073 DISABLE_COMPILER_MSC_WARNING_END (4018)
1074 return Led_Rect (winTop, winLeft, winHeight, winWidth);
1075 }
1076
1077#if qStroika_Frameworks_Led_SupportGDI
1078 /*
1079 ********************************************************************************
1080 ********************************* EnsureRectOnScreen ***************************
1081 ********************************************************************************
1082 */
1083 /*
1084 @METHOD: EnsureRectOnScreen
1085 @DESCRIPTION: <p>Utility routine to ensure the first rect (typically used for a window) fits on the sceen.
1086 Pin the edges so it fits. See also @'EnsureRectInRect'.</p>
1087 */
1088 inline Led_Rect EnsureRectOnScreen ([[maybe_unused]] Led_Rect& r)
1089 {
1090#if qStroika_Foundation_Common_Platform_Windows
1091 // Get the limits of the 'workarea'
1092 RECT rWorkArea;
1093 memset (&rWorkArea, 0, sizeof (rWorkArea));
1094 BOOL bResult = SystemParametersInfo (SPI_GETWORKAREA, sizeof (RECT), &rWorkArea, 0);
1095 if (!bResult) {
1096 rWorkArea.left = rWorkArea.top = 0;
1097 rWorkArea.right = GetSystemMetrics (SM_CXSCREEN);
1098 rWorkArea.bottom = GetSystemMetrics (SM_CYSCREEN);
1099 }
1100 return EnsureRectInRect (r, AsLedRect (rWorkArea));
1101#else
1102 Assert (false); // NYI -
1103 return Led_Rect (0, 0, 0, 0);
1104#endif
1105 }
1106#endif
1107
1108 /*
1109 ********************************************************************************
1110 ************************************* Led_Point ********************************
1111 ********************************************************************************
1112 */
1113#if qStroika_Foundation_Common_Platform_Windows
1114 inline Led_Point AsLedPoint (POINT p)
1115 {
1116 return Led_Point (p.y, p.x);
1117 }
1118 inline POINT AsPOINT (Led_Point p)
1119 {
1120 POINT newP;
1121 newP.x = p.h;
1122 newP.y = p.v;
1123 return newP;
1124 }
1125 inline Led_Rect AsLedRect (RECT r)
1126 {
1127 return Led_Rect (r.top, r.left, r.bottom - r.top, r.right - r.left);
1128 }
1129 inline RECT AsRECT (Led_Rect r)
1130 {
1131 RECT newR;
1132 newR.top = r.GetTop ();
1133 newR.left = r.GetLeft ();
1134 newR.bottom = r.GetBottom ();
1135 newR.right = r.GetRight ();
1136 return newR;
1137 }
1138 inline SIZE AsSIZE (Led_Size s)
1139 {
1140 SIZE result;
1141 result.cx = s.h;
1142 result.cy = s.v;
1143 return result;
1144 }
1145 inline Led_Size AsLedSize (SIZE s)
1146 {
1147 Led_Size result;
1148 result.h = s.cx;
1149 result.v = s.cy;
1150 return result;
1151 }
1152#elif qStroika_FeatureSupported_XWindows
1153 inline Led_Rect AsLedRect (const XRectangle& r)
1154 {
1155 return Led_Rect (r.y, r.x, r.height, r.width);
1156 }
1157 inline XRectangle AsXRect (const Led_Rect& r)
1158 {
1159 XRectangle newR;
1160 newR.x = r.GetLeft ();
1161 newR.y = r.GetTop ();
1162 newR.height = r.GetHeight ();
1163 newR.width = r.GetWidth ();
1164 return newR;
1165 }
1166#endif
1167
1168#if qStroika_Frameworks_Led_SupportGDI
1169 /*
1170 @METHOD: Led_CvtScreenPixelsToTWIPSV
1171 @DESCRIPTION: <p>Utility routine to convert from logical coordinates (usually pixels) to TWIPS.
1172 <p>See also @'Led_CvtScreenPixelsToTWIPSH'.</p>
1173 */
1174 inline TWIPS Led_CvtScreenPixelsToTWIPSV (CoordinateType from)
1175 {
1176#if qStroika_Foundation_Common_Platform_Windows
1177 return TWIPS (::MulDiv (from, 1440, Globals::Get ().GetMainScreenLogPixelsV ()));
1178#else
1179 return TWIPS (from * 1440 / Globals::Get ().GetMainScreenLogPixelsV ());
1180#endif
1181 }
1182
1183 /*
1184 @METHOD: Led_CvtScreenPixelsToTWIPSH
1185 @DESCRIPTION: <p>Utility routine to convert from logical coordinates (usually pixels) to TWIPS.
1186 <p>See also @'Led_CvtScreenPixelsToTWIPSV'.</p>
1187 */
1188 inline TWIPS Led_CvtScreenPixelsToTWIPSH (CoordinateType from)
1189 {
1190#if qStroika_Foundation_Common_Platform_Windows
1191 return TWIPS (::MulDiv (from, 1440, Globals::Get ().GetMainScreenLogPixelsH ()));
1192#else
1193 return TWIPS (from * 1440 / Globals::Get ().GetMainScreenLogPixelsH ());
1194#endif
1195 }
1196 /*
1197 @METHOD: Led_CvtScreenPixelsFromTWIPSV
1198 @DESCRIPTION: <p>Utility routine to convert from TWIPS to logical coordinates (usually pixels).
1199 <p>See also @'Led_CvtScreenPixelsFromTWIPSH'.</p>
1200 */
1201 inline CoordinateType Led_CvtScreenPixelsFromTWIPSV (TWIPS from)
1202 {
1203#if qStroika_Foundation_Common_Platform_Windows
1204 return ::MulDiv (from, Globals::Get ().GetMainScreenLogPixelsV (), 1440);
1205#else
1206 return TWIPS{from * Globals::Get ().GetMainScreenLogPixelsV () / 1440};
1207#endif
1208 }
1209 /*
1210 @METHOD: Led_CvtScreenPixelsFromTWIPSH
1211 @DESCRIPTION: <p>Utility routine to convert from TWIPS to logical coordinates (usually pixels).
1212 <p>See also @'Led_CvtScreenPixelsFromTWIPSV'.</p>
1213 */
1214 inline CoordinateType Led_CvtScreenPixelsFromTWIPSH (TWIPS from)
1215 {
1216#if qStroika_Foundation_Common_Platform_Windows
1217 return ::MulDiv (from, Globals::Get ().GetMainScreenLogPixelsH (), 1440);
1218#else
1219 return TWIPS{from * Globals::Get ().GetMainScreenLogPixelsH () / 1440};
1220#endif
1221 }
1222#endif
1223
1224#if qStroika_Frameworks_Led_SupportGDI
1225 /*
1226 ********************************************************************************
1227 ******************************* FontMetrics ************************************
1228 ********************************************************************************
1229 */
1230#if qStroika_Foundation_Common_Platform_Windows
1231 inline FontMetrics::FontMetrics (const TEXTMETRIC& from)
1232 : fPlatformSpecific (from)
1233 {
1234 }
1235#elif qStroika_FeatureSupported_XWindows
1236 inline FontMetrics::FontMetrics (const FontMetrics::PlatformSpecific& from)
1237 : fPlatformSpecific (from)
1238 {
1239 }
1240#endif
1241 inline DistanceType FontMetrics::GetAscent () const
1242 {
1243#if qStroika_Foundation_Common_Platform_Windows
1244 return (fPlatformSpecific.tmAscent);
1245#elif qStroika_FeatureSupported_XWindows
1246 return fPlatformSpecific.fAscent;
1247#endif
1248 }
1249 inline DistanceType FontMetrics::GetDescent () const
1250 {
1251#if qStroika_Foundation_Common_Platform_Windows
1252 return (fPlatformSpecific.tmDescent);
1253#elif qStroika_FeatureSupported_XWindows
1254 return fPlatformSpecific.fDescent;
1255#endif
1256 }
1257 inline DistanceType FontMetrics::GetLeading () const
1258 {
1259#if qStroika_Foundation_Common_Platform_Windows
1260 return (fPlatformSpecific.tmExternalLeading);
1261#elif qStroika_FeatureSupported_XWindows
1262 return (fPlatformSpecific.fLeading);
1263#endif
1264 }
1265 inline DistanceType FontMetrics::GetHeight () const
1266 {
1267#if qStroika_Foundation_Common_Platform_Windows
1268 Assert (fPlatformSpecific.tmHeight >= 0);
1269 Assert (GetAscent () + GetDescent () == DistanceType (fPlatformSpecific.tmHeight));
1270#endif
1271 return (GetAscent () + GetDescent ());
1272 }
1273 inline DistanceType FontMetrics::GetLineHeight () const
1274 {
1275 return (GetAscent () + GetDescent () + GetLeading ());
1276 }
1277 inline nonvirtual DistanceType FontMetrics::GetMaxCharacterWidth () const
1278 {
1279#if qStroika_Foundation_Common_Platform_MacOS
1280 return fPlatformSpecific.widMax;
1281#elif qStroika_Foundation_Common_Platform_Windows
1282 return fPlatformSpecific.tmMaxCharWidth;
1283#elif qStroika_FeatureSupported_XWindows
1284 return fPlatformSpecific.fMaxCharWidth;
1285#endif
1286 }
1287#if qStroika_Foundation_Common_Platform_Windows
1288 inline nonvirtual DistanceType FontMetrics::GetAveCharacterWidth () const
1289 {
1290 return fPlatformSpecific.tmAveCharWidth;
1291 }
1292#endif
1293#if qStroika_Foundation_Common_Platform_MacOS
1294 inline FontMetrics::operator const FontInfo* () const
1295 {
1296 return &fPlatformSpecific;
1297 }
1298 inline FontMetrics::operator FontInfo* ()
1299 {
1300 return (&fPlatformSpecific);
1301 }
1302#elif qStroika_Foundation_Common_Platform_Windows
1303 inline FontMetrics::operator const TEXTMETRIC* () const
1304 {
1305 return &fPlatformSpecific;
1306 }
1307 inline FontMetrics::operator TEXTMETRIC* ()
1308 {
1309 return &fPlatformSpecific;
1310 }
1311#endif
1312#endif
1313
1314 /*
1315 ********************************************************************************
1316 ************************************* Color ************************************
1317 ********************************************************************************
1318 */
1319 constexpr inline Color::Color (ColorValue redValue, ColorValue greenValue, ColorValue blueValue)
1320 : fRed{redValue}
1321 , fGreen{greenValue}
1322 , fBlue{blueValue}
1323 {
1324 }
1325#if qStroika_Foundation_Common_Platform_Windows
1326 inline Color::Color (COLORREF colorRef)
1327 : fRed (static_cast<ColorValue> (GetRValue (colorRef)) << 8)
1328 , fGreen (static_cast<ColorValue> (GetGValue (colorRef)) << 8)
1329 , fBlue (static_cast<ColorValue> (GetBValue (colorRef)) << 8)
1330 {
1331 }
1332#endif
1333 inline Color::ColorValue Color::GetRed () const
1334 {
1335 return fRed;
1336 }
1337 inline Color::ColorValue Color::GetGreen () const
1338 {
1339 return fGreen;
1340 }
1341 inline Color::ColorValue Color::GetBlue () const
1342 {
1343 return fBlue;
1344 }
1345#if qStroika_Foundation_Common_Platform_Windows
1346 inline COLORREF Color::GetOSRep () const
1347 {
1348 return RGB (fRed >> 8, fGreen >> 8, fBlue >> 8);
1349 }
1350#endif
1351 inline Color operator* (Color lhs, float factor)
1352 {
1353 using CV = Color::ColorValue;
1354 return Color (static_cast<CV> (lhs.GetRed () * factor), static_cast<CV> (lhs.GetGreen () * factor), static_cast<CV> (lhs.GetBlue () * factor));
1355 }
1356 inline Color operator/ (Color lhs, float divBy)
1357 {
1358 return Color (static_cast<Color::ColorValue> (lhs.GetRed () / divBy), static_cast<Color::ColorValue> (lhs.GetGreen () / divBy),
1359 static_cast<Color::ColorValue> (lhs.GetBlue () / divBy));
1360 }
1361 inline Color operator+ (Color lhs, Color rhs)
1362 {
1363 return Color (lhs.GetRed () + rhs.GetRed (), lhs.GetGreen () + rhs.GetGreen (), lhs.GetBlue () + rhs.GetBlue ());
1364 }
1365 inline Color operator- (Color lhs, Color rhs)
1366 {
1367 return Color (lhs.GetRed () - rhs.GetRed (), lhs.GetGreen () - rhs.GetGreen (), lhs.GetBlue () - rhs.GetBlue ());
1368 }
1369 inline unsigned int Distance_Squared (Color lhs, Color rhs)
1370 {
1371 int rDiff = static_cast<int> (lhs.GetRed ()) - static_cast<int> (rhs.GetRed ());
1372 int gDiff = static_cast<int> (lhs.GetGreen ()) - static_cast<int> (rhs.GetGreen ());
1373 int bDiff = static_cast<int> (lhs.GetBlue ()) - static_cast<int> (rhs.GetBlue ());
1374 unsigned int sum = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
1375 return sum;
1376 }
1377 inline unsigned int Distance (Color lhs, Color rhs)
1378 {
1379 return static_cast<unsigned int> (::sqrt (static_cast<float> (Distance_Squared (lhs, rhs))));
1380 }
1381#if qStroika_Foundation_Common_Platform_Windows
1382 inline unsigned int Distance_Squared (COLORREF lhs, COLORREF rhs)
1383 {
1384 int rDiff = static_cast<int> (GetRValue (lhs)) - static_cast<int> (GetRValue (rhs));
1385 int gDiff = static_cast<int> (GetGValue (lhs)) - static_cast<int> (GetGValue (rhs));
1386 int bDiff = static_cast<int> (GetBValue (lhs)) - static_cast<int> (GetBValue (rhs));
1387 unsigned int sum = rDiff * rDiff + gDiff * gDiff + bDiff * bDiff;
1388 return sum;
1389 }
1390#endif
1391}
1392
1393namespace std {
1394 template <>
1395 struct less<Stroika::Frameworks::Led::Color> {
1396 bool operator() (const Stroika::Frameworks::Led::Color& _Left, const Stroika::Frameworks::Led::Color& _Right) const
1397 {
1398 if (_Left.GetRed () < _Right.GetRed ()) {
1399 return true;
1400 }
1401 else if (_Left.GetRed () == _Right.GetRed ()) {
1402 if (_Left.GetGreen () < _Right.GetGreen ()) {
1403 return true;
1404 }
1405 else if (_Left.GetGreen () == _Right.GetGreen ()) {
1406 return (_Left.GetBlue () < _Right.GetBlue ());
1407 }
1408 }
1409 return false;
1410 }
1411 };
1412}
1413
1414namespace Stroika::Frameworks::Led {
1415#if qStroika_Foundation_Common_Platform_Windows
1416 inline Pen::Pen (int nPenStyle, int nWidth, COLORREF crColor)
1417 : m_hObject{nullptr}
1418 {
1419 if (!Attach (::CreatePen (nPenStyle, nWidth, crColor)))
1420 Foundation::Execution::Throw (bad_alloc{});
1421 }
1422 inline Pen::~Pen ()
1423 {
1424 (void)DeleteObject ();
1425 }
1426 inline Pen::operator HPEN () const
1427 {
1428 return m_hObject;
1429 }
1430 inline BOOL Pen::Attach (HPEN hObject)
1431 {
1432 Assert (m_hObject == nullptr); // only attach once, detach on destroy
1433 if (hObject == nullptr)
1434 return FALSE;
1435 m_hObject = hObject;
1436 return TRUE;
1437 }
1438 inline BOOL Pen::DeleteObject ()
1439 {
1440 if (m_hObject == nullptr)
1441 return FALSE;
1442 HPEN h = m_hObject;
1443 m_hObject = nullptr;
1444 return ::DeleteObject (h);
1445 }
1446#endif
1447}
1448
1449namespace Stroika::Frameworks::Led {
1450 /*
1451 ********************************************************************************
1452 ************************************* LineSpacing ******************************
1453 ********************************************************************************
1454 */
1455 constexpr LineSpacing::LineSpacing (Rule rule)
1456 : fRule{rule}
1457 {
1458 Require (rule == eSingleSpace or rule == eOnePointFiveSpace or rule == eDoubleSpace);
1459 }
1460 constexpr LineSpacing::LineSpacing (Rule rule, TWIPS twips)
1461 : fRule{rule}
1462 , fArg{static_cast<unsigned> (twips)}
1463 {
1464 Require (rule == eAtLeastTWIPSSpacing or rule == eExactTWIPSSpacing);
1465 }
1466 constexpr LineSpacing::LineSpacing (Rule rule, unsigned lineCount)
1467 : fRule{rule}
1468 , fArg{lineCount}
1469 {
1470 Require (rule == eExactLinesSpacing);
1471 switch (lineCount) {
1472 case 20:
1473 fRule = eSingleSpace;
1474 break;
1475 case 30:
1476 fRule = eOnePointFiveSpace;
1477 break;
1478 case 40:
1479 fRule = eDoubleSpace;
1480 break;
1481 }
1482 }
1483 constexpr bool LineSpacing::operator== (const LineSpacing& rhs) const
1484 {
1485 if (fRule != rhs.fRule) {
1486 return false;
1487 }
1488 if (fRule == LineSpacing::eAtLeastTWIPSSpacing or fRule == LineSpacing::eExactTWIPSSpacing or fRule == LineSpacing::eExactLinesSpacing) {
1489 if (fArg != rhs.fArg) {
1490 return false;
1491 }
1492 }
1493 return true;
1494 }
1495
1496 /*
1497 ********************************************************************************
1498 ********************** FontSpecification::FontNameSpecifier ********************
1499 ********************************************************************************
1500 */
1501#if qStroika_Foundation_Common_Platform_Windows
1502 inline FontSpecification::FontNameSpecifier::FontNameSpecifier ()
1503 {
1504 fName[0] = '\0';
1505 }
1506#endif
1507
1508 /*
1509 ********************************************************************************
1510 ****************************** FontSpecification *******************************
1511 ********************************************************************************
1512 */
1513 inline FontSpecification::FontSpecification (const IncrementalFontSpecification& from)
1514#if qStroika_Foundation_Common_Platform_Windows
1515 : fFontInfo (((const FontSpecification&)from).fFontInfo)
1516#else
1517 : fFontFamily (from.fFontFamily)
1518 , fBold (from.fBold)
1519 , fItalics (from.fItalics)
1520 , fUnderline (from.fUnderline)
1521 , fFontSize (from.fFontSize)
1522#endif
1523 , fSubOrSuperScript (((const FontSpecification&)from).fSubOrSuperScript)
1524 , fTextColor (((const FontSpecification&)from).fTextColor)
1525 {
1526 }
1527 /*
1528 @METHOD: FontSpecification::GetFontName
1529 @DESCRIPTION: <p>Retrieve the 'FontName' attribute of the given font specification. This name is a string, and corresponds to the font family name.</p>
1530 <p>See also @'FontSpecification::SetFontName'.</p>
1531 */
1532 inline SDKString FontSpecification::GetFontName () const
1533 {
1534#if qStroika_Foundation_Common_Platform_Windows
1535 return fFontInfo.lfFaceName;
1536#else
1537 return fFontFamily.AsSDKString ();
1538#endif
1539 }
1540 // FontName info
1541 inline FontSpecification::FontNameSpecifier FontSpecification::GetFontNameSpecifier () const
1542 {
1543#if qStroika_Foundation_Common_Platform_Windows
1544 return fFontInfo.lfFaceName;
1545#else
1546 return fFontFamily;
1547#endif
1548 }
1549 // Style info
1550 /*
1551 @METHOD: FontSpecification::GetStyle_Plain
1552 @DESCRIPTION: <p>Checks all the various font 'style' attributes, such as 'bold', or 'italic'. Returns true iff all
1553 of these styles are not set.</p>
1554 <p>See also @'FontSpecification::SetStyle_Plain'.</p>
1555 */
1556 inline bool FontSpecification::GetStyle_Plain () const
1557 {
1558 if (fSubOrSuperScript != eNoSubOrSuperscript) {
1559 return false;
1560 }
1561#if qStroika_Foundation_Common_Platform_Windows
1562 return (fFontInfo.lfItalic == false and fFontInfo.lfWeight <= FW_NORMAL and fFontInfo.lfUnderline == false and fFontInfo.lfStrikeOut == false);
1563#else
1564 return not fBold and not fItalics and not fUnderline;
1565#endif
1566 }
1567 /*
1568 @METHOD: FontSpecification::SetStyle_Plain
1569 @DESCRIPTION: <p>Clears all 'style' attributes, such as 'bold', or 'italic'.</p>
1570 <p>See also @'FontSpecification::GetStyle_Plain'.</p>
1571 */
1572 inline void FontSpecification::SetStyle_Plain ()
1573 {
1574 fSubOrSuperScript = eNoSubOrSuperscript;
1575#if qStroika_Foundation_Common_Platform_Windows
1576 fFontInfo.lfItalic = false;
1577 fFontInfo.lfWeight = FW_NORMAL;
1578 fFontInfo.lfUnderline = false;
1579 fFontInfo.lfStrikeOut = false;
1580#elif qStroika_FeatureSupported_XWindows
1581 fBold = false;
1582 fItalics = false;
1583 fUnderline = false;
1584#endif
1585 }
1586 inline bool FontSpecification::GetStyle_Bold () const
1587 {
1588#if qStroika_Foundation_Common_Platform_Windows
1589 return fFontInfo.lfWeight > FW_NORMAL;
1590#else
1591 return fBold;
1592#endif
1593 }
1594 inline void FontSpecification::SetStyle_Bold (bool isBold)
1595 {
1596#if qStroika_Foundation_Common_Platform_Windows
1597 fFontInfo.lfWeight = isBold ? FW_BOLD : FW_NORMAL;
1598#elif qStroika_FeatureSupported_XWindows
1599 fBold = isBold;
1600#endif
1601 }
1602 inline bool FontSpecification::GetStyle_Italic () const
1603 {
1604#if qStroika_Foundation_Common_Platform_Windows
1605 return !!fFontInfo.lfItalic;
1606#else
1607 return fItalics;
1608#endif
1609 }
1610 inline void FontSpecification::SetStyle_Italic (bool isItalic)
1611 {
1612#if qStroika_Foundation_Common_Platform_Windows
1613 fFontInfo.lfItalic = isItalic;
1614#else
1615 fItalics = isItalic;
1616#endif
1617 }
1618 inline bool FontSpecification::GetStyle_Underline () const
1619 {
1620#if qStroika_Foundation_Common_Platform_Windows
1621 return !!fFontInfo.lfUnderline;
1622#else
1623 return fUnderline;
1624#endif
1625 }
1626 inline void FontSpecification::SetStyle_Underline (bool isUnderline)
1627 {
1628#if qStroika_Foundation_Common_Platform_Windows
1629 fFontInfo.lfUnderline = isUnderline;
1630#elif qStroika_FeatureSupported_XWindows
1631 fUnderline = isUnderline;
1632#endif
1633 }
1634 inline FontSpecification::SubOrSuperScript FontSpecification::GetStyle_SubOrSuperScript () const
1635 {
1636 return fSubOrSuperScript;
1637 }
1638 inline void FontSpecification::SetStyle_SubOrSuperScript (SubOrSuperScript subOrSuperScript)
1639 {
1640 fSubOrSuperScript = subOrSuperScript;
1641 }
1642#if qStroika_Foundation_Common_Platform_Windows
1643 inline bool FontSpecification::GetStyle_Strikeout () const
1644 {
1645 return !!fFontInfo.lfStrikeOut;
1646 }
1647 inline void FontSpecification::SetStyle_Strikeout (bool isStrikeout)
1648 {
1649 fFontInfo.lfStrikeOut = isStrikeout;
1650 }
1651#endif
1652 // FontSize info
1653 inline FontSpecification::FontSize FontSpecification::GetPointSize () const
1654 {
1655#if qStroika_Foundation_Common_Platform_Windows
1656 if (fFontInfo.lfHeight >= 0) {
1657 // I probably should be doing some magic here with subtracing internal leading, or something like that from this value -
1658 // See GetStaticDefaultFont () and Win32 SDK docs for LOGFONT
1659 // LGP 960222
1660 WindowDC screenDC (nullptr);
1661 FontObject font;
1662 Verify (font.CreateFontIndirect (&fFontInfo));
1663 HFONT oldFont = screenDC.SelectObject (font);
1664 TEXTMETRIC tms;
1665 screenDC.GetTextMetrics (&tms);
1666 screenDC.SelectObject (oldFont);
1667 return (unsigned short)::MulDiv (tms.tmHeight, 72, Globals::Get ().GetMainScreenLogPixelsV ());
1668 }
1669 else {
1670 return static_cast<unsigned short> (::MulDiv (-fFontInfo.lfHeight, 72, Globals::Get ().GetMainScreenLogPixelsV ()));
1671 }
1672#else
1673 return fFontSize;
1674#endif
1675 }
1676 inline void FontSpecification::SetPointSize (FontSize pointSize)
1677 {
1678#if qStroika_Foundation_Common_Platform_Windows
1679 fFontInfo.lfHeight = ::MulDiv (-long (pointSize), Globals::Get ().GetMainScreenLogPixelsV (), 72);
1680#else
1681 fFontSize = pointSize;
1682#endif
1683 }
1684#if qStroika_Foundation_Common_Platform_Windows
1685 inline long FontSpecification::PeekAtTMHeight () const
1686 {
1687 return fFontInfo.lfHeight;
1688 }
1689 inline void FontSpecification::PokeAtTMHeight (long tmHeight)
1690 {
1691 fFontInfo.lfHeight = tmHeight;
1692 }
1693#endif
1694 inline Color FontSpecification::GetTextColor () const
1695 {
1696 return fTextColor;
1697 }
1698 inline void FontSpecification::SetTextColor (const Color& textColor)
1699 {
1700 fTextColor = textColor;
1701 }
1702#if qStroika_Foundation_Common_Platform_Windows
1703 inline LOGFONT FontSpecification::GetOSRep () const
1704 {
1705 return fFontInfo;
1706 }
1707 inline void FontSpecification::GetOSRep (LOGFONT* logFont) const
1708 {
1709 RequireNotNull (logFont);
1710 *logFont = fFontInfo;
1711 }
1712 inline void FontSpecification::SetOSRep (LOGFONT logFont)
1713 {
1714 fFontInfo = logFont;
1715 }
1716 inline void FontSpecification::LightSetOSRep (LOGFONT logFont)
1717 {
1718 fFontInfo = logFont;
1719 fFontInfo.lfWidth = 0;
1720 fFontInfo.lfEscapement = 0;
1721 fFontInfo.lfOrientation = 0;
1722 fFontInfo.lfCharSet = DEFAULT_CHARSET;
1723 fFontInfo.lfOutPrecision = 0;
1724 fFontInfo.lfClipPrecision = 0;
1725 fFontInfo.lfQuality = 0;
1726 fFontInfo.lfPitchAndFamily = 0;
1727 }
1728#endif
1729#if qStroika_Foundation_Common_Platform_Windows
1730 inline FontSpecification::FontSpecification (const LOGFONT& logFont)
1731 : fFontInfo ()
1732 , fSubOrSuperScript (eNoSubOrSuperscript)
1733 , fTextColor (Color::kBlack)
1734 {
1735 LightSetOSRep (logFont);
1736 }
1737#endif
1738 inline bool FontSpecification::operator== (const FontSpecification& rhs) const
1739 {
1740 const FontSpecification& lhs = *this;
1741 // FontName Info
1742 if (lhs.GetFontNameSpecifier () != rhs.GetFontNameSpecifier ()) {
1743 return false;
1744 }
1745
1746// Style Info
1747#if qStroika_Foundation_Common_Platform_Windows
1748 if (lhs.GetStyle_Bold () != rhs.GetStyle_Bold ()) {
1749 return false;
1750 }
1751 if (lhs.GetStyle_Italic () != rhs.GetStyle_Italic ()) {
1752 return false;
1753 }
1754 if (lhs.GetStyle_Underline () != rhs.GetStyle_Underline ()) {
1755 return false;
1756 }
1757 if (lhs.GetStyle_Strikeout () != rhs.GetStyle_Strikeout ()) {
1758 return false;
1759 }
1760#elif qStroika_FeatureSupported_XWindows
1761 if (lhs.GetStyle_Bold () != rhs.GetStyle_Bold ()) {
1762 return false;
1763 }
1764 if (lhs.GetStyle_Italic () != rhs.GetStyle_Italic ()) {
1765 return false;
1766 }
1767 if (lhs.GetStyle_Underline () != rhs.GetStyle_Underline ()) {
1768 return false;
1769 }
1770#endif
1771 if (lhs.GetStyle_SubOrSuperScript () != rhs.GetStyle_SubOrSuperScript ()) {
1772 return false;
1773 }
1774
1775 // Color Info
1776 if (lhs.GetTextColor () != rhs.GetTextColor ()) {
1777 return false;
1778 }
1779
1780// Size Info
1781#if qStroika_Foundation_Common_Platform_Windows
1782 // Speed tweek to avoid divide and getdevicecaps crap...
1783 if (lhs.PeekAtTMHeight () == rhs.PeekAtTMHeight ()) {
1784 return true;
1785 }
1786 else if ((lhs.PeekAtTMHeight () > 0) == (rhs.PeekAtTMHeight () > 0)) {
1787 return false; // if same sign, we can just compare for equality, and since they
1788 // ABOVE didn't compare equal, they must be different point sizes
1789 // (or at least very close depending a little on resoution...)
1790 // If their signs DIFFER, we must fall through into the scaling crap (GetPointSize).
1791 }
1792#endif
1793 if (lhs.GetPointSize () != rhs.GetPointSize ()) {
1794 return false;
1795 }
1796
1797 return true;
1798 }
1799 inline void FontSpecification::MergeIn (const IncrementalFontSpecification& addInTheseAttributes)
1800 {
1801 // Font Name
1802 if (addInTheseAttributes.GetFontNameSpecifier_Valid ()) {
1803 SetFontNameSpecifier (addInTheseAttributes.GetFontNameSpecifier ());
1804 }
1805
1806 // Font Styles
1807 if (addInTheseAttributes.GetStyle_Bold_Valid ()) {
1808 SetStyle_Bold (addInTheseAttributes.GetStyle_Bold ());
1809 }
1810 if (addInTheseAttributes.GetStyle_Italic_Valid ()) {
1811 SetStyle_Italic (addInTheseAttributes.GetStyle_Italic ());
1812 }
1813 if (addInTheseAttributes.GetStyle_Underline_Valid ()) {
1814 SetStyle_Underline (addInTheseAttributes.GetStyle_Underline ());
1815 }
1816 if (addInTheseAttributes.GetStyle_SubOrSuperScript_Valid ()) {
1817 SetStyle_SubOrSuperScript (addInTheseAttributes.GetStyle_SubOrSuperScript ());
1818 }
1819#if qStroika_Foundation_Common_Platform_Windows
1820 if (addInTheseAttributes.GetStyle_Strikeout_Valid ()) {
1821 SetStyle_Strikeout (addInTheseAttributes.GetStyle_Strikeout ());
1822 }
1823#endif
1824
1825 // Font Size
1826 if (addInTheseAttributes.GetPointSize_Valid ()) {
1827#if qStroika_Foundation_Common_Platform_Windows
1828 // speed tweek - avoid costly conversion to 'points'. All we want todo is copy the tmHeight field!
1829 PokeAtTMHeight (addInTheseAttributes.PeekAtTMHeight ());
1830#else
1831 SetPointSize (addInTheseAttributes.GetPointSize ());
1832#endif
1833 }
1834 if (addInTheseAttributes.GetPointSizeIncrement_Valid ()) {
1835 short pointSize = GetPointSize ();
1836 pointSize += addInTheseAttributes.GetPointSizeIncrement ();
1837 if (pointSize <= 0) { // never let point size get any smaller...
1838 pointSize = 1;
1839 }
1840 SetPointSize (pointSize);
1841 }
1842
1843 // Text Color
1844 if (addInTheseAttributes.GetTextColor_Valid ()) {
1845 SetTextColor (addInTheseAttributes.GetTextColor ());
1846 }
1847
1848#if qStroika_Foundation_Common_Platform_Windows
1849 // could have done somewhat earlier, but if so, must be more careful about what else gets changed... (like textcolor not part of this guy)
1850 if (addInTheseAttributes.GetDidSetOSRepCallFlag ()) {
1851 LOGFONT lf;
1852 addInTheseAttributes.GetOSRep (&lf);
1853 SetOSRep (lf);
1854 }
1855#endif
1856 }
1857
1858 /*
1859 ********************************************************************************
1860 ************************** IncrementalFontSpecification ************************
1861 ********************************************************************************
1862 */
1863 inline IncrementalFontSpecification::IncrementalFontSpecification (const FontSpecification& fontSpec)
1864 : FontSpecification{fontSpec}
1865 , fFontSpecifierValid (true)
1866 , fStyleValid_Bold (true)
1867 , fStyleValid_Italic (true)
1868 , fStyleValid_Underline (true)
1869 , fStyleValid_SubOrSuperScript (true)
1870 ,
1871#if qStroika_Foundation_Common_Platform_Windows
1872 fStyleValid_Strikeout (true)
1873 , fDidSetOSRepCallFlag (true)
1874 ,
1875#endif
1876 fFontSizeValid (true)
1877 , fFontSizeIncrementValid (false)
1878 , fTextColorValid (true)
1879 {
1880 }
1881 inline FontSpecification::FontNameSpecifier IncrementalFontSpecification::GetFontNameSpecifier () const
1882 {
1883 Require (fFontSpecifierValid);
1884 return inherited::GetFontNameSpecifier ();
1885 }
1886 inline bool IncrementalFontSpecification::GetFontNameSpecifier_Valid () const
1887 {
1888 return (fFontSpecifierValid);
1889 }
1890 inline void IncrementalFontSpecification::InvalidateFontNameSpecifier ()
1891 {
1892 fFontSpecifierValid = false;
1893#if qStroika_Foundation_Common_Platform_Windows
1894 fDidSetOSRepCallFlag = false;
1895#endif
1896 }
1897 inline void IncrementalFontSpecification::SetFontNameSpecifier (FontNameSpecifier fontNameSpecifier)
1898 {
1899 fFontSpecifierValid = true;
1900#if qStroika_Foundation_Common_Platform_Windows
1901 fDidSetOSRepCallFlag = false;
1902#endif
1903 inherited::SetFontNameSpecifier (fontNameSpecifier);
1904 }
1905 inline void IncrementalFontSpecification::SetFontName (const SDKString& fontName)
1906 {
1907 fFontSpecifierValid = true;
1908#if qStroika_Foundation_Common_Platform_Windows
1909 fDidSetOSRepCallFlag = false;
1910#endif
1911 inherited::SetFontName (fontName);
1912 }
1913 inline bool IncrementalFontSpecification::GetStyle_Plain () const
1914 {
1915 Require (fStyleValid_Bold);
1916 Require (fStyleValid_Italic);
1917 Require (fStyleValid_Underline);
1918 Require (fStyleValid_SubOrSuperScript);
1919#if qStroika_Foundation_Common_Platform_Windows
1920 Require (fStyleValid_Strikeout);
1921#endif
1922 return inherited::GetStyle_Plain ();
1923 }
1924 inline bool IncrementalFontSpecification::GetStyle_Plain_Valid () const
1925 {
1926 bool isValid = fStyleValid_Bold and fStyleValid_Italic and fStyleValid_Underline and fStyleValid_SubOrSuperScript;
1927#if qStroika_Foundation_Common_Platform_Windows
1928 isValid = isValid and fStyleValid_Strikeout;
1929#endif
1930 return isValid;
1931 }
1932 inline void IncrementalFontSpecification::InvalidateStyles ()
1933 {
1934 fStyleValid_Bold = false;
1935 fStyleValid_Italic = false;
1936 fStyleValid_Underline = false;
1937 fStyleValid_SubOrSuperScript = false;
1938#if qStroika_Foundation_Common_Platform_Windows
1939 fStyleValid_Strikeout = false;
1940 fDidSetOSRepCallFlag = false;
1941#endif
1942 }
1943 inline void IncrementalFontSpecification::SetStyle_Plain ()
1944 {
1945 fStyleValid_Bold = true;
1946 fStyleValid_Italic = true;
1947 fStyleValid_Underline = true;
1948 fStyleValid_SubOrSuperScript = true;
1949#if qStroika_Foundation_Common_Platform_Windows
1950 fStyleValid_Strikeout = true;
1951 fDidSetOSRepCallFlag = false;
1952#endif
1953 inherited::SetStyle_Plain ();
1954 }
1955 inline bool IncrementalFontSpecification::GetStyle_Bold () const
1956 {
1957 Require (fStyleValid_Bold);
1958 return inherited::GetStyle_Bold ();
1959 }
1960 inline bool IncrementalFontSpecification::GetStyle_Bold_Valid () const
1961 {
1962 return (fStyleValid_Bold);
1963 }
1964 inline void IncrementalFontSpecification::InvalidateStyle_Bold ()
1965 {
1966 fStyleValid_Bold = false;
1967#if qStroika_Foundation_Common_Platform_Windows
1968 fDidSetOSRepCallFlag = false;
1969#endif
1970 }
1971 inline void IncrementalFontSpecification::SetStyle_Bold (bool isBold)
1972 {
1973 fStyleValid_Bold = true;
1974#if qStroika_Foundation_Common_Platform_Windows
1975 fDidSetOSRepCallFlag = false;
1976#endif
1977 inherited::SetStyle_Bold (isBold);
1978 }
1979 inline bool IncrementalFontSpecification::GetStyle_Italic () const
1980 {
1981 Require (fStyleValid_Italic);
1982 return inherited::GetStyle_Italic ();
1983 }
1984 inline bool IncrementalFontSpecification::GetStyle_Italic_Valid () const
1985 {
1986 return (fStyleValid_Italic);
1987 }
1988 inline void IncrementalFontSpecification::InvalidateStyle_Italic ()
1989 {
1990 fStyleValid_Italic = false;
1991#if qStroika_Foundation_Common_Platform_Windows
1992 fDidSetOSRepCallFlag = false;
1993#endif
1994 }
1995 inline void IncrementalFontSpecification::SetStyle_Italic (bool isItalic)
1996 {
1997 fStyleValid_Italic = true;
1998#if qStroika_Foundation_Common_Platform_Windows
1999 fDidSetOSRepCallFlag = false;
2000#endif
2001 inherited::SetStyle_Italic (isItalic);
2002 }
2003 inline bool IncrementalFontSpecification::GetStyle_Underline () const
2004 {
2005 Require (fStyleValid_Underline);
2006 return inherited::GetStyle_Underline ();
2007 }
2008 inline bool IncrementalFontSpecification::GetStyle_Underline_Valid () const
2009 {
2010 return (fStyleValid_Underline);
2011 }
2012 inline void IncrementalFontSpecification::InvalidateStyle_Underline ()
2013 {
2014 fStyleValid_Underline = false;
2015#if qStroika_Foundation_Common_Platform_Windows
2016 fDidSetOSRepCallFlag = false;
2017#endif
2018 }
2019 inline void IncrementalFontSpecification::SetStyle_Underline (bool isUnderline)
2020 {
2021 fStyleValid_Underline = true;
2022#if qStroika_Foundation_Common_Platform_Windows
2023 fDidSetOSRepCallFlag = false;
2024#endif
2025 inherited::SetStyle_Underline (isUnderline);
2026 }
2027 inline FontSpecification::SubOrSuperScript IncrementalFontSpecification::GetStyle_SubOrSuperScript () const
2028 {
2029 Require (fStyleValid_SubOrSuperScript);
2030 return inherited::GetStyle_SubOrSuperScript ();
2031 }
2032 inline bool IncrementalFontSpecification::GetStyle_SubOrSuperScript_Valid () const
2033 {
2034 return (fStyleValid_SubOrSuperScript);
2035 }
2036 inline void IncrementalFontSpecification::InvalidateStyle_SubOrSuperScript ()
2037 {
2038 fStyleValid_SubOrSuperScript = false;
2039#if qStroika_Foundation_Common_Platform_Windows
2040 fDidSetOSRepCallFlag = false;
2041#endif
2042 }
2043 inline void IncrementalFontSpecification::SetStyle_SubOrSuperScript (SubOrSuperScript subOrSuperScript)
2044 {
2045 fStyleValid_SubOrSuperScript = true;
2046#if qStroika_Foundation_Common_Platform_Windows
2047 fDidSetOSRepCallFlag = false;
2048#endif
2049 inherited::SetStyle_SubOrSuperScript (subOrSuperScript);
2050 }
2051#if qStroika_Foundation_Common_Platform_Windows
2052 inline bool IncrementalFontSpecification::GetStyle_Strikeout () const
2053 {
2054 Require (fStyleValid_Strikeout);
2055 return (inherited::GetStyle_Strikeout ());
2056 }
2057 inline bool IncrementalFontSpecification::GetStyle_Strikeout_Valid () const
2058 {
2059 return (fStyleValid_Strikeout);
2060 }
2061 inline void IncrementalFontSpecification::InvalidateStyle_Strikeout ()
2062 {
2063 fStyleValid_Strikeout = false;
2064#if qStroika_Foundation_Common_Platform_Windows
2065 fDidSetOSRepCallFlag = false;
2066#endif
2067 }
2068 inline void IncrementalFontSpecification::SetStyle_Strikeout (bool isStrikeout)
2069 {
2070 fStyleValid_Strikeout = true;
2071#if qStroika_Foundation_Common_Platform_Windows
2072 fDidSetOSRepCallFlag = false;
2073#endif
2074 inherited::SetStyle_Strikeout (isStrikeout);
2075 }
2076#endif
2077 // FontSize info
2078 inline unsigned short IncrementalFontSpecification::GetPointSize () const
2079 {
2080 Require (fFontSizeValid);
2081 Require (not fFontSizeIncrementValid);
2082 return inherited::GetPointSize ();
2083 }
2084 inline bool IncrementalFontSpecification::GetPointSize_Valid () const
2085 {
2086 return (fFontSizeValid);
2087 }
2088 inline void IncrementalFontSpecification::InvalidatePointSize ()
2089 {
2090 fFontSizeValid = false;
2091 fFontSizeIncrementValid = false;
2092#if qStroika_Foundation_Common_Platform_Windows
2093 fDidSetOSRepCallFlag = false;
2094#endif
2095 }
2096 inline void IncrementalFontSpecification::SetPointSize (FontSize pointSize)
2097 {
2098 fFontSizeValid = true;
2099#if qStroika_Foundation_Common_Platform_Windows
2100 fDidSetOSRepCallFlag = false;
2101#endif
2102 inherited::SetPointSize (pointSize);
2103 fFontSizeIncrementValid = false;
2104 }
2105#if qStroika_Foundation_Common_Platform_Windows
2106 inline void IncrementalFontSpecification::PokeAtTMHeight (long tmHeight)
2107 {
2108 fFontSizeValid = true;
2109 fDidSetOSRepCallFlag = false;
2110 fFontSizeIncrementValid = false;
2111 inherited::PokeAtTMHeight (tmHeight);
2112 }
2113#endif
2114 inline short IncrementalFontSpecification::GetPointSizeIncrement () const
2115 {
2116 Require (not fFontSizeValid);
2117 Require (fFontSizeIncrementValid);
2118 return (short)inherited::GetPointSize ();
2119 }
2120 inline bool IncrementalFontSpecification::GetPointSizeIncrement_Valid () const
2121 {
2122 return (fFontSizeIncrementValid);
2123 }
2124 inline void IncrementalFontSpecification::InvalidatePointSizeIncrement ()
2125 {
2126 fFontSizeValid = false;
2127 fFontSizeIncrementValid = false;
2128#if qStroika_Foundation_Common_Platform_Windows
2129 fDidSetOSRepCallFlag = false;
2130#endif
2131 }
2132 inline void IncrementalFontSpecification::SetPointSizeIncrement (short pointSizeIncrement)
2133 {
2134 fFontSizeValid = false;
2135#if qStroika_Foundation_Common_Platform_Windows
2136 fDidSetOSRepCallFlag = false;
2137#endif
2138 inherited::SetPointSize ((unsigned short)pointSizeIncrement);
2139 fFontSizeIncrementValid = true;
2140 }
2141 inline Color IncrementalFontSpecification::GetTextColor () const
2142 {
2143 Require (fTextColorValid);
2144 return inherited::GetTextColor ();
2145 }
2146 inline bool IncrementalFontSpecification::GetTextColor_Valid () const
2147 {
2148 return (fTextColorValid);
2149 }
2150 inline void IncrementalFontSpecification::InvalidateTextColor ()
2151 {
2152 fTextColorValid = false;
2153 }
2154 inline void IncrementalFontSpecification::SetTextColor (const Color& textColor)
2155 {
2156 fTextColorValid = true;
2157 inherited::SetTextColor (textColor);
2158 }
2159#if qStroika_Foundation_Common_Platform_Windows
2160 inline LOGFONT IncrementalFontSpecification::GetOSRep () const
2161 {
2162 Require (fFontSpecifierValid and fStyleValid_Bold and fStyleValid_Italic and fStyleValid_Underline and fFontSizeValid);
2163 Require (fStyleValid_Strikeout);
2164 return inherited::GetOSRep ();
2165 }
2166 inline void IncrementalFontSpecification::GetOSRep (LOGFONT* logFont) const
2167 {
2168 RequireNotNull (logFont);
2169 Require (fFontSpecifierValid and fStyleValid_Bold and fStyleValid_Italic and fStyleValid_Underline and fFontSizeValid);
2170 Require (fStyleValid_Strikeout);
2171 inherited::GetOSRep (logFont);
2172 }
2173 inline void IncrementalFontSpecification::SetOSRep (LOGFONT logFont)
2174 {
2175 fFontSpecifierValid = true;
2176 fStyleValid_Bold = true;
2177 fStyleValid_Italic = true;
2178 fStyleValid_Underline = true;
2179 fStyleValid_Strikeout = true;
2180 fFontSizeValid = true;
2181 fFontSizeIncrementValid = false;
2182 fDidSetOSRepCallFlag = true;
2183 inherited::SetOSRep (logFont);
2184 }
2185 inline void IncrementalFontSpecification::LightSetOSRep (LOGFONT logFont)
2186 {
2187 fFontSpecifierValid = true;
2188 fStyleValid_Bold = true;
2189 fStyleValid_Italic = true;
2190 fStyleValid_Underline = true;
2191 fStyleValid_Strikeout = true;
2192 fFontSizeValid = true;
2193 fFontSizeIncrementValid = false;
2194 fDidSetOSRepCallFlag = true;
2195 inherited::LightSetOSRep (logFont);
2196 }
2197 inline bool IncrementalFontSpecification::GetDidSetOSRepCallFlag () const
2198 {
2199 return fDidSetOSRepCallFlag;
2200 }
2201#endif
2202 inline void IncrementalFontSpecification::MergeIn (const IncrementalFontSpecification& addInTheseAttributes)
2203 {
2204 // Font Name
2205 if (addInTheseAttributes.GetFontNameSpecifier_Valid ()) {
2206 SetFontNameSpecifier (addInTheseAttributes.GetFontNameSpecifier ());
2207 }
2208
2209 // Font Styles
2210 if (addInTheseAttributes.GetStyle_Bold_Valid ()) {
2211 SetStyle_Bold (addInTheseAttributes.GetStyle_Bold ());
2212 }
2213 if (addInTheseAttributes.GetStyle_Italic_Valid ()) {
2214 SetStyle_Italic (addInTheseAttributes.GetStyle_Italic ());
2215 }
2216 if (addInTheseAttributes.GetStyle_Underline_Valid ()) {
2217 SetStyle_Underline (addInTheseAttributes.GetStyle_Underline ());
2218 }
2219#if qStroika_Foundation_Common_Platform_Windows
2220 if (addInTheseAttributes.GetStyle_Strikeout_Valid ()) {
2221 SetStyle_Strikeout (addInTheseAttributes.GetStyle_Strikeout ());
2222 }
2223#endif
2224
2225 // Font Size
2226 if (addInTheseAttributes.GetPointSize_Valid ()) {
2227#if qStroika_Foundation_Common_Platform_Windows
2228 // speed tweek - avoid costly conversion to 'points'. All we want todo is copy the tmHeight field!
2229 PokeAtTMHeight (addInTheseAttributes.PeekAtTMHeight ());
2230#else
2231 SetPointSize (addInTheseAttributes.GetPointSize ());
2232#endif
2233 }
2234 if (addInTheseAttributes.GetPointSizeIncrement_Valid ()) {
2235 short pointSize = GetPointSize ();
2236 pointSize += addInTheseAttributes.GetPointSizeIncrement ();
2237 if (pointSize <= 0) { // never let point size get any smaller...
2238 pointSize = 1;
2239 }
2240 SetPointSize (pointSize);
2241 }
2242
2243 // Text Color
2244 if (addInTheseAttributes.GetTextColor_Valid ()) {
2245 SetTextColor (addInTheseAttributes.GetTextColor ());
2246 }
2247
2248#if qStroika_Foundation_Common_Platform_Windows
2249 fDidSetOSRepCallFlag = addInTheseAttributes.GetDidSetOSRepCallFlag ();
2250#endif
2251 }
2252 inline bool IncrementalFontSpecification::operator== (const IncrementalFontSpecification& rhs) const
2253 {
2254 // Either make this non-portable, or somehow do some hack to make this test FASTER than it looks like
2255 // it may be currently - profile??? - LGP 960517
2256 //
2257 // FontName Info
2258 {
2259 if (GetFontNameSpecifier_Valid () != rhs.GetFontNameSpecifier_Valid ()) {
2260 return false;
2261 }
2262 if (GetFontNameSpecifier_Valid () and (GetFontNameSpecifier () != rhs.GetFontNameSpecifier ())) {
2263 return false;
2264 }
2265 }
2266
2267 // Style Info
2268 {
2269 if (GetStyle_Bold_Valid () != rhs.GetStyle_Bold_Valid ()) {
2270 return false;
2271 }
2272 if (GetStyle_Bold_Valid () and (GetStyle_Bold () != rhs.GetStyle_Bold ())) {
2273 return false;
2274 }
2275 }
2276 {
2277 if (GetStyle_Italic_Valid () != rhs.GetStyle_Italic_Valid ()) {
2278 return false;
2279 }
2280 if (GetStyle_Italic_Valid () and (GetStyle_Italic () != rhs.GetStyle_Italic ())) {
2281 return false;
2282 }
2283 }
2284 {
2285 if (GetStyle_Underline_Valid () != rhs.GetStyle_Underline_Valid ()) {
2286 return false;
2287 }
2288 if (GetStyle_Underline_Valid () and (GetStyle_Underline () != rhs.GetStyle_Underline ())) {
2289 return false;
2290 }
2291 }
2292 {
2293 if (GetStyle_SubOrSuperScript_Valid () != rhs.GetStyle_SubOrSuperScript_Valid ()) {
2294 return false;
2295 }
2296 if (GetStyle_SubOrSuperScript_Valid () and (GetStyle_SubOrSuperScript () != rhs.GetStyle_SubOrSuperScript ())) {
2297 return false;
2298 }
2299 }
2300#if qStroika_Foundation_Common_Platform_Windows
2301 {
2302 if (GetStyle_Strikeout_Valid () != rhs.GetStyle_Strikeout_Valid ()) {
2303 return false;
2304 }
2305 if (GetStyle_Strikeout_Valid () and (GetStyle_Strikeout () != rhs.GetStyle_Strikeout ())) {
2306 return false;
2307 }
2308 }
2309#endif
2310
2311 // Font Color Info
2312 {
2313 if (GetTextColor_Valid () != rhs.GetTextColor_Valid ()) {
2314 return false;
2315 }
2316 if (GetTextColor_Valid () and (GetTextColor () != rhs.GetTextColor ())) {
2317 return false;
2318 }
2319 }
2320
2321 // Size Info
2322 {
2323 if (GetPointSizeIncrement_Valid () != rhs.GetPointSizeIncrement_Valid ()) {
2324 return false;
2325 }
2326 if (GetPointSizeIncrement_Valid () and (GetPointSizeIncrement () != rhs.GetPointSizeIncrement ())) {
2327 return false;
2328 }
2329 }
2330 {
2331 if (GetPointSize_Valid () != rhs.GetPointSize_Valid ()) {
2332 return false;
2333 }
2334 if (GetPointSize_Valid ()) {
2335#if qStroika_Foundation_Common_Platform_Windows
2336 // Speed tweek to avoid divide and getdevicecaps crap...
2337 if (PeekAtTMHeight () == rhs.PeekAtTMHeight ()) {
2338 return true;
2339 }
2340 else if ((PeekAtTMHeight () > 0) == (rhs.PeekAtTMHeight () > 0)) {
2341 return false; // if same sign, we can just compare for equality, and since they
2342 // ABOVE didn't compare equal, they must be different point sizes
2343 // (or at least very close depending a little on resoution...)
2344 // If their signs DIFFER, we must fall through into the scaling crap (GetPointSize).
2345 }
2346#endif
2347 if (GetPointSize () != rhs.GetPointSize ()) {
2348 return false;
2349 }
2350 }
2351 }
2352
2353 return true;
2354 }
2355
2356 /*
2357 ********************************************************************************
2358 ********************************** InstalledFonts ******************************
2359 ********************************************************************************
2360 */
2361 inline const vector<SDKString>& InstalledFonts::GetUsableFontNames () const
2362 {
2363 return fFontNames;
2364 }
2365
2366#if qStroika_Frameworks_Led_SupportGDI
2367 /*
2368 ********************************************************************************
2369 ******************************** Led_GetTextColor ******************************
2370 ********************************************************************************
2371 */
2372 inline Color Led_GetTextColor ()
2373 {
2374#if qStroika_Foundation_Common_Platform_Windows
2375 return Color (::GetSysColor (COLOR_WINDOWTEXT));
2376#elif qStroika_FeatureSupported_XWindows
2377 return (Color::kBlack);
2378#endif
2379 }
2380
2381 /*
2382 ********************************************************************************
2383 ************************** Led_GetTextBackgroundColor **************************
2384 ********************************************************************************
2385 */
2386 inline Color Led_GetTextBackgroundColor ()
2387 {
2388#if qStroika_Foundation_Common_Platform_Windows
2389 return Color (::GetSysColor (COLOR_WINDOW));
2390#elif qStroika_FeatureSupported_XWindows
2391 return (Color::kWhite);
2392#endif
2393 }
2394#endif
2395
2396#if qStroika_Frameworks_Led_SupportGDI
2397 /*
2398 ********************************************************************************
2399 **************************** Led_GetSelectedTextColor **************************
2400 ********************************************************************************
2401 */
2402 inline Color Led_GetSelectedTextColor ()
2403 {
2404#if qStroika_Foundation_Common_Platform_MacOS
2405 RGBColor hiliteRGBValue;
2406 LMGetHiliteRGB (&hiliteRGBValue);
2407 /*
2408 * This is based on empirical testing with the behavior of the TE in the Color desk accessory
2409 * that comes with system 7.5. I REALLY should probably do something with color intensity
2410 * matching -- LGP 950531
2411 */
2412 if (Color (hiliteRGBValue) == Color::kBlack) {
2413 return (Color::kWhite);
2414 }
2415 else {
2416 return (Color::kBlack);
2417 }
2418#elif qStroika_Foundation_Common_Platform_Windows
2419 // return Color (::GetSysColor (COLOR_CAPTIONTEXT));
2420 return Color (::GetSysColor (COLOR_HIGHLIGHTTEXT));
2421#elif qStroika_FeatureSupported_XWindows
2422 return (Color::kWhite);
2423#endif
2424 }
2425 inline Color Led_GetSelectedTextBackgroundColor ()
2426 {
2427#if qStroika_Foundation_Common_Platform_MacOS
2428 RGBColor hiliteRGBValue;
2429 LMGetHiliteRGB (&hiliteRGBValue);
2430 return Color (hiliteRGBValue);
2431#elif qStroika_Foundation_Common_Platform_Windows
2432 //return Color (::GetSysColor (COLOR_ACTIVECAPTION));
2433 return Color (::GetSysColor (COLOR_HIGHLIGHT));
2434#elif qStroika_FeatureSupported_XWindows
2435 return (Color::kBlack);
2436#endif
2437 }
2438#endif
2439
2440#if qStroika_Frameworks_Led_SupportGDI
2441 /*
2442 ********************************************************************************
2443 ************************ Tablet::ClipNarrowAndRestore **************************
2444 ********************************************************************************
2445 */
2446 inline Tablet::ClipNarrowAndRestore::ClipNarrowAndRestore (Tablet* tablet)
2447 : fTablet (tablet)
2448 , fHasOldClip (false)
2449 , fOldClip ()
2450 {
2451 RequireNotNull (tablet);
2452#if qStroika_Foundation_Common_Platform_Windows
2453 if (::GetDeviceCaps (fTablet->m_hDC, TECHNOLOGY) == DT_METAFILE) {
2454 return;
2455 }
2456#endif
2457 fHasOldClip = tablet->GetClip (&fOldClip);
2458 }
2459 inline Tablet::ClipNarrowAndRestore::ClipNarrowAndRestore (Tablet* tablet, const Led_Rect& clipFurtherTo)
2460 : fTablet (tablet)
2461 , fHasOldClip (false)
2462 , fOldClip ()
2463 {
2464 RequireNotNull (tablet);
2465 fHasOldClip = tablet->GetClip (&fOldClip);
2466#if qStroika_Foundation_Common_Platform_MacOS
2467 Assert (fHasOldClip);
2468 tablet->SetClip (fOldClip * clipFurtherTo);
2469#elif qStroika_Foundation_Common_Platform_Windows
2470 /*
2471 * NB: We must use IntersectClipRect instead of the above SetClip () call because the CLIP on Win32 is in
2472 * device rather than logical coordinates.
2473 */
2474 if (::GetDeviceCaps (tablet->m_hDC, TECHNOLOGY) == DT_METAFILE) {
2475 return;
2476 }
2477 Verify (::IntersectClipRect (*tablet, clipFurtherTo.GetLeft (), clipFurtherTo.GetTop (), clipFurtherTo.GetRight (),
2478 clipFurtherTo.GetBottom ()) != ERROR);
2479#endif
2480 }
2481 inline Tablet::ClipNarrowAndRestore::ClipNarrowAndRestore (Tablet* tablet, [[maybe_unused]] const Region& clipFurtherTo)
2482 : fTablet (tablet)
2483 , fHasOldClip (false)
2484 , fOldClip ()
2485 {
2486 RequireNotNull (tablet);
2487 fHasOldClip = tablet->GetClip (&fOldClip);
2488#if qStroika_Foundation_Common_Platform_MacOS
2489 Assert (fHasOldClip);
2490 tablet->SetClip (fOldClip * clipFurtherTo);
2491#elif qStroika_Foundation_Common_Platform_Windows
2492 Assert (false); // NYI - see SPR#????
2493#else
2494 Assert (false); // NYI
2495#endif
2496 }
2497 inline Tablet::ClipNarrowAndRestore::~ClipNarrowAndRestore ()
2498 {
2499 AssertNotNull (fTablet);
2500#if qStroika_Foundation_Common_Platform_Windows
2501 if (::GetDeviceCaps (fTablet->m_hDC, TECHNOLOGY) == DT_METAFILE) {
2502 return;
2503 }
2504#endif
2505 if (fHasOldClip) {
2506 fTablet->SetClip (fOldClip);
2507 }
2508 else {
2509 fTablet->SetClip ();
2510 }
2511 }
2512#endif
2513
2514#if qStroika_Foundation_Common_Platform_Windows
2515 /*
2516 ********************************************************************************
2517 ********************************** WindowDC ************************************
2518 ********************************************************************************
2519 */
2520 inline WindowDC::WindowDC (HWND hWnd)
2521 : fHWnd_{hWnd}
2522 {
2523 Require (fHWnd_ == nullptr or ::IsWindow (fHWnd_));
2524 if (!Attach (::GetWindowDC (fHWnd_))) {
2525 Foundation::Execution::Throw (bad_alloc{});
2526 }
2527 }
2528 inline WindowDC::~WindowDC ()
2529 {
2530 AssertNotNull (m_hDC);
2531 ::ReleaseDC (fHWnd_, Detach ());
2532 }
2533
2534#endif
2535
2536#if qStroika_Frameworks_Led_SupportGDI
2537 /*
2538 ********************************************************************************
2539 *********************************** GDI_Obj_Selector ***************************
2540 ********************************************************************************
2541 */
2542#if qStroika_Foundation_Common_Platform_Windows
2543 inline GDI_Obj_Selector::GDI_Obj_Selector (Tablet* tablet, HGDIOBJ objToSelect)
2544 : fTablet (tablet)
2545 , fRestoreObject (nullptr)
2546 , fRestoreAttribObject (nullptr)
2547 {
2548 AssertNotNull (tablet);
2549 AssertNotNull (objToSelect);
2550 // See CDC::SelectObject for the logic..., but we do better than thiers and restore
2551 // right object to right DC!!!! - LGP 950525
2552 if (tablet->m_hDC != tablet->m_hAttribDC) {
2553 fRestoreObject = ::SelectObject (tablet->m_hDC, objToSelect);
2554 }
2555 if (tablet->m_hAttribDC != nullptr) {
2556 fRestoreAttribObject = ::SelectObject (tablet->m_hAttribDC, objToSelect);
2557 }
2558 }
2559#elif qStroika_Foundation_Common_Platform_MacOS
2560 inline GDI_Obj_Selector::GDI_Obj_Selector (Tablet* tablet, const Pen& pen)
2561 : fTablet (tablet)
2562 ,
2563#if TARGET_CARBON
2564 fRestorePen (Pen (::GetPortPenMode (Led_GetCurrentGDIPort ()), &Pen::kBlackPattern, Color (GDI_GetForeColor ())))
2565#else
2566 fRestorePen (Pen (Led_GetCurrentGDIPort ()->pnMode, &Led_GetCurrentGDIPort ()->pnPat, Color (GDI_GetForeColor ())))
2567#endif
2568 {
2569 Assert (Led_GetCurrentGDIPort () == *tablet);
2570 GDI_RGBForeColor (pen.fPenColor.GetOSRep ());
2571 ::PenMode (pen.fPenStyle);
2572 ::PenPat (&pen.fPenPat);
2573 }
2574#elif qStroika_FeatureSupported_XWindows
2575 inline GDI_Obj_Selector::GDI_Obj_Selector (Tablet* tablet, const Pen& pen)
2576 {
2577 }
2578#endif
2579 inline GDI_Obj_Selector::~GDI_Obj_Selector ()
2580 {
2581#if qStroika_Foundation_Common_Platform_Windows
2582 //NB: These restore objects CAN be nullptr, if no font (or whatever) selected into DC before we do... (aside from error cases)
2583 if (fRestoreObject != nullptr) {
2584 Verify (::SelectObject (fTablet->m_hDC, fRestoreObject));
2585 }
2586 if (fRestoreAttribObject != nullptr) {
2587 Verify (::SelectObject (fTablet->m_hAttribDC, fRestoreAttribObject));
2588 }
2589#elif qStroika_Foundation_Common_Platform_MacOS
2590 GDI_RGBForeColor (fRestorePen.fPenColor.GetOSRep ());
2591 ::PenMode (fRestorePen.fPenStyle);
2592 ::PenPat (&fRestorePen.fPenPat);
2593#endif
2594 }
2595#endif
2596
2597 /*
2598 ********************************************************************************
2599 *************************** Led_GetMacPict* ************************************
2600 ********************************************************************************
2601 */
2602 inline short Led_GetMacPictTop (const Led_Picture* picture)
2603 {
2604 RequireNotNull (picture);
2605 return Led_ByteSwapFromMac (picture->picFrameTop);
2606 }
2607 inline short Led_GetMacPictLeft (const Led_Picture* picture)
2608 {
2609 RequireNotNull (picture);
2610 return Led_ByteSwapFromMac (picture->picFrameLeft);
2611 }
2612 inline short Led_GetMacPictBottom (const Led_Picture* picture)
2613 {
2614 RequireNotNull (picture);
2615 return Led_ByteSwapFromMac (picture->picFrameBottom);
2616 }
2617 inline short Led_GetMacPictRight (const Led_Picture* picture)
2618 {
2619 RequireNotNull (picture);
2620 return Led_ByteSwapFromMac (picture->picFrameRight);
2621 }
2622 inline short Led_GetMacPictWidth (const Led_Picture* picture)
2623 {
2624 return Led_GetMacPictRight (picture) - Led_GetMacPictLeft (picture);
2625 }
2626 inline short Led_GetMacPictHeight (const Led_Picture* picture)
2627 {
2628 return Led_GetMacPictBottom (picture) - Led_GetMacPictTop (picture);
2629 }
2630 inline Led_Size Led_GetMacPictSize (const Led_Picture* picture)
2631 {
2632 return Led_Size (Led_GetMacPictHeight (picture), Led_GetMacPictWidth (picture));
2633 }
2634
2635#if qStroika_Frameworks_Led_ProvideIMESupport
2636 /*
2637 ********************************************************************************
2638 *************************************** IME ************************************
2639 ********************************************************************************
2640 */
2641 DISABLE_COMPILER_MSC_WARNING_START (6011)
2642 inline IME& IME::Get ()
2643 {
2644 if (sThe == nullptr) {
2645 new IME ();
2646 }
2647 AssertNotNull (sThe);
2648 return *sThe;
2649 }
2650 DISABLE_COMPILER_MSC_WARNING_END (6011)
2651 inline void IME::Enable ()
2652 {
2653 if (fIMEEnableProc != nullptr) {
2654 fIMEEnableProc (nullptr, true);
2655 }
2656 }
2657 inline void IME::Disable ()
2658 {
2659 if (fIMEEnableProc != nullptr) {
2660 fIMEEnableProc (nullptr, false);
2661 }
2662 }
2663 inline bool IME::Available () const
2664 {
2665 return fWinNlsAvailable;
2666 }
2667 inline void IME::ForgetPosition ()
2668 {
2669 fLastX = -1;
2670 fLastY = -1;
2671 }
2672#endif
2673
2674}
#define AssertNotNull(p)
Definition Assertions.h:333
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
Definition Assertions.h:48
#define RequireNotNull(p)
Definition Assertions.h:347
#define Verify(c)
Definition Assertions.h:419
set< T > Intersection(const set< T > &s1, const set< T > &s2)
basic_string< SDKChar > SDKString
Definition SDKString.h:38
STL namespace.