Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
GDI.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_GDI_h_
5#define _Stroika_Frameworks_Led_GDI_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9/*
10 * Graphix Library support. This code encapsulates access to underlying GDI for modularity sake.
11 * For historical reasons - as of Led 3.0 - there is still some direct access to underlying GDI in parts of Led
12 * but that will gradually (hopefully right after 3.0) be eliminated.</p>
13 * Also - no class library dependencies (ie no MFC dependencies). So we can build MFC-Free Win32 apps more
14 * easily.
15 */
16
17#include <algorithm>
18#include <cmath>
19#include <compare>
20#include <cstdlib>
21#include <map>
22#include <string>
23#include <vector>
24
25// WHY DON'T WE NEED TO INCLUDE <Windows.h> here??? - LGP 991213
26#if qStroika_FeatureSupported_XWindows
27#include <X11/Xlib.h>
28#include <X11/Xutil.h>
29#endif
30
32
33#include "Support.h"
34
35namespace Stroika::Frameworks::Led {
36
38 using Foundation::Characters::String;
39
40 /**
41 * <code>CoordinateType</code> is the <code>signed</code> analog of @'DistanceType'.
42 * @'Led_Point' is a tuple of <code>Coordinates</code>s
43 * (vertical and horizontal).</p>
44 */
45 using CoordinateType = long;
46
47 /*
48 @CLASS: DistanceType
49 @DESCRIPTION: <p><code>DistanceType</code> is an unsigned type, specifying the distance (always non-negative)
50 between two graphics locations. @'Led_Size' is a tuple of <code>DistanceType</code>s
51 (vertical and horizontal).</p>
52 */
53 using DistanceType = unsigned long;
54
55 /*
56 * Many distances are specified in Led in TWIPS - 1/20 of a printers point.
57 *
58 * This means - 1/1440 of an inch.</p>
59 *
60 * This size refers to the size when printed on a page. So it can be scaled - depnding on screen resolution.
61 * Led will often save this internally - and scale it at the last minute to the resolution of the @'Tablet*' being printed on.
62 *
63 * NB: This marks a change from Led 2.3 and earlier - where most distances were stored in pixels (still many are).
64 *
65 * NB: declard as a class instead of a typedef so we get better type checking. Shouldn't affect sizes or code
66 * generation - I would hope!
67 */
68 class TWIPS {
69 public:
70 constexpr explicit TWIPS (long v);
71 constexpr operator long () const;
72
73 private:
74 long fValue;
75
76 public:
77 nonvirtual TWIPS& operator+= (const TWIPS& rhs);
78 nonvirtual TWIPS& operator-= (const TWIPS& rhs);
79 nonvirtual TWIPS& operator*= (double rhs);
80
81 public:
82 constexpr bool operator== (const TWIPS&) const = default;
83
84 public:
85 static const TWIPS kPoint;
86 static const TWIPS kInch;
87 static const TWIPS kOneInch;
88 };
89 TWIPS operator+ (const TWIPS& lhs, const TWIPS& rhs);
90 TWIPS operator- (const TWIPS& lhs, const TWIPS& rhs);
91
92 class Tablet;
93
94 /*
95 * Even though WinSDK supports GetTabbedTextExtent/TabbedTextOut () - they do a bad job.
96 * In particular, they offer no (obvious) way to specify the tab origin for
97 * GetTabbedTextExtent(). This makes proper text display nearly impossible.
98 *
99 * Also, the Mac provides NO tab support at all. Because of the Mac - we NEED
100 * to implement our own tab support. Given we are doing that anyhow, may as
101 * well use our portable support on both platforms.
102 * For both calculating widths, and doing imaging, we follow essentially
103 * the same algorithm.
104 * o Walk the text looking for a tab or EOL.
105 * o Take the tab-free initial segment and image(calculate) it.
106 * o if now on a tab, image (calculate) that.
107 * o Advance indexes over what we've imaged (calculated) and repeat.
108 */
109 class TabStopList {
110 protected:
111 TabStopList () = default;
112
113 public:
114 virtual ~TabStopList () = default;
115
116 public:
117 /*
118 @DESCRIPTION: <p>Compute where the 'ith' tabstop lies (i >= 0, and can be arbitrarily high).
119 Note that though tabstop <code>i=0</code> is the first tabstop (which by convention is usually NOT
120 at the left margin - but is really the logically 'first' one).</p>
121 <p>Note - this used to return Distance - but in Led 3.0 - it changed to returning TWIPS (see SPR#0767);</p>
122 */
123 virtual TWIPS ComputeIthTab (size_t i) const = 0;
124 /*
125 @DESCRIPTION: <p>Given a distance from the left margin, find the immediately following tabstops position.
126 This is what is actually used in the imagers to compute where to draw text. It can logically
127 be implemented by walking the tabstoplist and calling @'TabStopList::ComputeIthTab', and
128 returning the next one after the one past(or equal to) <code>afterPos</code>.</p>
129 <p>Note - this used to take/return Distance - but in Led 3.0 - it changed to take/return TWIPS (see SPR#0767);</p>
130 <p>Now there is an overloaded version using Distance that takes a Tablet* as argument.</p>
131 */
132 virtual TWIPS ComputeTabStopAfterPosition (TWIPS afterPos) const = 0;
133 nonvirtual DistanceType ComputeTabStopAfterPosition (Tablet* tablet, DistanceType afterPos) const;
134 };
135
136#if qStroika_Foundation_Common_Platform_Windows
137 /**
138 */
139 class FontObject {
140 public:
141 FontObject () = default;
142 ~FontObject ();
143 nonvirtual operator HFONT () const;
144 nonvirtual int GetObject (int nCount, LPVOID lpObject) const;
145 nonvirtual BOOL DeleteObject ();
146 nonvirtual BOOL CreateFontIndirect (const LOGFONT* lpLogFont);
147 nonvirtual BOOL Attach (HFONT hObject);
148
149 public:
150 HFONT m_hObject{nullptr};
151 };
152#endif
153
154#if qStroika_Foundation_Common_Platform_Windows
155 /**
156 */
157 class Brush {
158 public:
159 Brush (COLORREF crColor);
160 ~Brush ();
161 nonvirtual operator HBRUSH () const;
162 nonvirtual BOOL Attach (HBRUSH hObject);
163 nonvirtual BOOL DeleteObject ();
164
165 private:
166 HBRUSH m_hObject{nullptr};
167 };
168#endif
169
170 /**
171 */
172 template <typename COORD_TYPE>
173 struct Point_Base {
174 public:
175 using CoordinateType = COORD_TYPE;
176
177 public:
178 constexpr Point_Base ();
179 constexpr Point_Base (COORD_TYPE newV, COORD_TYPE newH);
180 template <typename OTHER_POINT_BASE_TYPE>
181 constexpr explicit Point_Base (OTHER_POINT_BASE_TYPE o)
182 : v (COORD_TYPE (o.v))
183 , h (COORD_TYPE (o.h))
184 {
185 }
186
187 public:
188 COORD_TYPE v;
189 COORD_TYPE h;
190
191 public:
192 /**
193 */
194 constexpr strong_ordering operator<=> (const Point_Base& rhs) const = default;
195 };
196
197 /*
198 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
199 * o Standard Stroika Comparison support (operator<=>,operator==, etc);
200 */
201 template <typename POINT_TYPE, typename SIZE_TYPE>
202 struct Rect_Base {
203 public:
204 using CoordinateType = typename POINT_TYPE::CoordinateType;
205 using DistanceType = typename SIZE_TYPE::CoordinateType;
206 using THIS_TYPE = Rect_Base<POINT_TYPE, SIZE_TYPE>;
207
208 public:
209 constexpr Rect_Base ();
210 constexpr Rect_Base (CoordinateType newTop, CoordinateType newLeft, DistanceType newHeight, DistanceType newWidth);
211 constexpr Rect_Base (POINT_TYPE origin, SIZE_TYPE size);
212
213 public:
214 nonvirtual CoordinateType GetTop () const;
215 nonvirtual CoordinateType GetLeft () const;
216 nonvirtual CoordinateType GetBottom () const;
217 nonvirtual CoordinateType GetRight () const;
218 nonvirtual bool IsEmpty () const; /* contains no bits - ie one side <= zero length */
219 nonvirtual DistanceType GetHeight () const;
220 nonvirtual DistanceType GetWidth () const;
221 nonvirtual POINT_TYPE GetTopLeft () const;
222 nonvirtual POINT_TYPE GetTopRight () const;
223 nonvirtual POINT_TYPE GetBotRight () const;
224 nonvirtual POINT_TYPE GetOrigin () const;
225 nonvirtual SIZE_TYPE GetSize () const;
226 nonvirtual bool Contains (POINT_TYPE p) const;
227 nonvirtual bool Contains (THIS_TYPE r) const;
228
229 nonvirtual void SetOrigin (POINT_TYPE p);
230 nonvirtual void SetTop (CoordinateType top);
231 nonvirtual void SetLeft (CoordinateType left);
232 nonvirtual void SetBottom (CoordinateType bottom);
233 nonvirtual void SetRight (CoordinateType right);
234
235 public:
236 CoordinateType top;
237 CoordinateType left;
238 CoordinateType bottom;
239 CoordinateType right;
240
241 public:
242 nonvirtual const Rect_Base<POINT_TYPE, SIZE_TYPE>& operator+= (const POINT_TYPE& delta);
243 nonvirtual const Rect_Base<POINT_TYPE, SIZE_TYPE>& operator-= (const POINT_TYPE& delta);
244 nonvirtual const Rect_Base<POINT_TYPE, SIZE_TYPE>& operator*= (const THIS_TYPE& intersectWith);
245
246 public:
247 /**
248 */
249 constexpr strong_ordering operator<=> (const Rect_Base& rhs) const = default;
250 bool operator== (const Rect_Base& rhs) const;
251 };
252
253 /**
254 * Simple typedef of @'Point_Base<COORD_TYPE>' using @'Distance'.
255 */
256 using Led_Size = Point_Base<DistanceType>;
257
258 /**
259 * Simple typedef of @'Point_Base<COORD_TYPE>' using @'CoordinateType'.
260 */
261 using Led_Point = Point_Base<CoordinateType>;
262 Led_Point operator- (const Led_Point& lhs, const Led_Point& rhs);
263
264 /*
265 @DESCRIPTION: <p>Simple typedef of @'Point_Base<COORD_TYPE>' using @'TWIPS'.</p>
266 */
267 using TWIPS_Point = Point_Base<TWIPS>;
268
269 /*
270 @DESCRIPTION: <p>Simple typedef of @'Rect_Base<POINT_TYPE,SIZE_TYPE>' using @'Led_Point' and @'Led_Size'.</p>
271 */
272 using Led_Rect = Rect_Base<Led_Point, Led_Size>;
273
274 /*
275 @DESCRIPTION: <p>Simple typedef of @'Rect_Base<POINT_TYPE,SIZE_TYPE>' using @'TWIPS_Point'.</p>
276 */
277 using TWIPS_Rect = Rect_Base<TWIPS_Point, TWIPS_Point>;
278
279#if qStroika_Frameworks_Led_SupportGDI
280 /**
281 * \brief Portable GDI abstraction for 'Region' object.
282 */
283 class Region {
284 public:
285 Region ();
286 Region (const Led_Rect& r);
287 Region (const Region& from);
288 virtual ~Region ();
289 nonvirtual const Region& operator= (const Region& rhs);
290
291 public:
292 nonvirtual bool IsEmpty () const;
293 nonvirtual Led_Rect GetBoundingRect () const;
294
295 public:
296#if qStroika_Foundation_Common_Platform_MacOS
297 Region (RgnHandle rgn);
298 RgnHandle GetOSRep () const;
299 RgnHandle GetOSRep ();
300
301 private:
302 bool fOwned;
303#elif qStroika_Foundation_Common_Platform_Windows
304 operator HRGN () const;
305 int CombineRgn (Region* pRgn1, Region* pRgn2, int nCombineMode);
306 BOOL PtInRegion (int x, int y) const;
307 BOOL PtInRegion (POINT point) const;
308
309 private:
310 BOOL DeleteObject ();
311#endif
312 private:
313#if qStroika_Foundation_Common_Platform_MacOS
314 RgnHandle fRgn;
315#elif qStroika_Foundation_Common_Platform_Windows
316 HRGN fRgn;
317#endif
318 };
319 Region operator* (const Region& lhs, const Region& rhs);
320 Region operator+ (const Region& lhs, const Region& rhs);
321#endif
322
323 /**
324 * This class is a portable representation of a color. It can be constructed either
325 * from its basic RGB componets, or from the native color representations on a particular platform.
326 */
327 class Color {
328 public:
329 // regardless of Mac or Windows, we use the same size ColorValue so we can write
330 // portable code more easily...
331 using ColorValue = unsigned short;
332 enum {
333 kColorValueMin = 0,
334 kColorValueMax = USHRT_MAX
335 };
336
337 public:
338 constexpr Color (const Color&) = default;
339 constexpr Color (ColorValue redValue, ColorValue greenValue, ColorValue blueValue);
340#if qStroika_Foundation_Common_Platform_Windows
341 explicit Color (COLORREF colorRef);
342#endif
343
344 public:
345 nonvirtual ColorValue GetRed () const;
346 nonvirtual ColorValue GetGreen () const;
347 nonvirtual ColorValue GetBlue () const;
348
349 /*
350 * Some useful predefined values.
351 */
352 public:
353 static const Color kBlack;
354 static const Color kWhite;
355 static const Color kRed;
356 static const Color kGreen;
357 static const Color kBlue;
358 static const Color kCyan;
359 static const Color kMagenta;
360 static const Color kYellow;
361 static const Color kMaroon;
362 static const Color kOlive;
363 static const Color kNavyBlue;
364 static const Color kPurple;
365 static const Color kTeal;
366 static const Color kGray;
367 static const Color kSilver; // aka 'light gray'
368 static const Color kDarkGreen;
369 static const Color kLimeGreen;
370 static const Color kFuchsia;
371 static const Color kAqua;
372
373 public:
374#if qStroika_Foundation_Common_Platform_Windows
375 nonvirtual COLORREF GetOSRep () const;
376#endif
377
378 public:
379 /**
380 */
381 constexpr strong_ordering operator<=> (const Color& rhs) const = default;
382 constexpr bool operator== (const Color& rhs) const = default;
383
384 private:
385 ColorValue fRed;
386 ColorValue fGreen;
387 ColorValue fBlue;
388 };
389
390 Color operator* (Color lhs, float factor);
391 Color operator/ (Color lhs, float divBy);
392 Color operator+ (Color lhs, Color rhs);
393 Color operator- (Color lhs, Color rhs);
394
395 unsigned int Distance (Color lhs, Color rhs);
396 unsigned int Distance_Squared (Color lhs, Color rhs);
397#if qStroika_Foundation_Common_Platform_Windows
398 unsigned int Distance_Squared (COLORREF lhs, COLORREF rhs);
399#endif
400
401 /**
402 * Helper class to keep track of GDI information used for drawing.
403 * Very different implementations befween Mac and Windows.
404 *
405 * Note - this class is used in conjunction with @'GDI_Obj_Selector'.
406 */
407 class Pen {
408#if qStroika_Foundation_Common_Platform_Windows
409 public:
410 Pen (int nPenStyle, int nWidth, COLORREF crColor);
411 ~Pen ();
412 nonvirtual operator HPEN () const;
413 nonvirtual BOOL Attach (HPEN hObject);
414 nonvirtual BOOL DeleteObject ();
415
416 private:
417 HPEN m_hObject;
418#endif
419 };
420
421 /*
422 @DESCRIPTION: <p>Led defines several kinds of justification, but doesn't implement all of them.
423 <ul>
424 <li><em>eLeftJustify</em></li>
425 <li><em>eRightJustify</em></li>
426 <li><em>eCenterJustify</em></li>
427 <li><em>eFullyJustify</em>- not implemented in Led 3.0 - treated as eLeftJustify</li>
428 <li><em>eDefaultForScriptJustify</em>-not implemented in Led 3.0 - treated as eLeftJustify</li>
429 </ul>
430 </p>
431 <p>These extra unimplemented enums are provided so you can more easily write code and read/write files
432 etc which keep track of this information, and even show the styles in the UI. They just aren't reflected
433 in how the text is drawn yet. That should come in the next major Led release.</p>
434 */
435 enum Justification {
436 eLeftJustify,
437 eRightJustify,
438 eCenterJustify,
439 eFullyJustify,
440 eDefaultForScriptJustify
441 };
442
443 /**
444 * There are two defined text directions:
445 * <li><em>eLeftToRight</em></li>
446 * <li><em>eRightToLeft</em></li>
447 */
448 enum TextDirection {
449 eLeftToRight,
450 eRightToLeft
451 };
452
453 /**
454 * Different styles of bullet / list markers for list items in the WordProcessor.</p>
455 *
456 * Numeric values come from RTF 1.5 Spec \levelnfc (except for eListStyle_None which is special)</p>
457 */
458 enum ListStyle {
459 eListStyle_None = 9999,
460 eListStyle_Bullet = 23
461 };
462
463 /*
464 @DESCRIPTION: <p>Support at least all the crazy formats/options in the Win32 PARAFORMAT2 structure, and
465 the ill-documented RTF 1.5 SPEC \sl options.
466 <ul>
467 <li>eSingleSpace- fArg IGNORED
468 <li>eOnePointFiveSpace- fArg IGNORED
469 <li>eDoubleSpace- fArg IGNORED
470 <li>eAtLeastTWIPSSpacing-<br>
471 The fArg member specifies the spacing from one line to the next, in twips.
472 However, if fArg specifies a value that is less than single line spacing, Led displays single-spaced text.
473 <li>eExactTWIPSSpacing-<br>
474 The fArg member specifies the spacing from one row to the next, in twips.
475 Led uses the exact spacing specified, even if fArg specifies a value that is less than single spacing.
476 <li>eExactLinesSpacing-<br>
477 The value of fArg / 20 is the spacing, in lines, from one line to the next.
478 Thus, setting fArg to 20 produces single-spaced text, 40 is double spaced, 60 is triple spaced, and so on.
479 </ul>
480 </p>
481 */
482 class LineSpacing {
483 public:
484 enum Rule {
485 eSingleSpace,
486 eOnePointFiveSpace,
487 eDoubleSpace,
488 eAtLeastTWIPSSpacing,
489 eExactTWIPSSpacing,
490 eExactLinesSpacing
491 };
492 Rule fRule{eSingleSpace};
493 unsigned fArg{0};
494
495 public:
496 constexpr LineSpacing () = default;
497 constexpr LineSpacing (Rule rule);
498 constexpr LineSpacing (Rule rule, TWIPS twips);
499 constexpr LineSpacing (Rule rule, unsigned lineCount);
500
501 public:
502 constexpr bool operator== (const LineSpacing& rhs) const;
503 };
504
505 class IncrementalFontSpecification;
506
507 /**
508 * <code>FontSpecification</code> is a utility class which portably represents
509 * a user font choice. This largely corresponds to the MS-Windows <code>LOGFONT</code> structure
510 * or the Macintosh <code>txFace, txSize, txStyle</code>.</p>
511 * In addition to being a portable represenation of this information, it
512 * also contains handy wrapper accessors, and extra information like subscript,
513 * superscript, and font color.</p>
514 * See also, @'IncrementalFontSpecification'</p>
515 */
517 public:
518 FontSpecification (const FontSpecification&) = default;
519 FontSpecification () = default;
520#if qStroika_Foundation_Common_Platform_Windows
521 explicit FontSpecification (const LOGFONT& logFont);
522#endif
523 // Force users to be EXPLICIT about this object-slicing, since many of the fields
524 // maybe invalid... Will the compiler REALLY do this check???? We'll see - LGP 970314
525 explicit FontSpecification (const IncrementalFontSpecification& from);
526
527 public:
528#if qStroika_Foundation_Common_Platform_Windows
529 struct FontNameSpecifier { // So struct copies etc will work and so we can define op==
531 FontNameSpecifier (const SDKChar* from);
532 SDKChar fName[LF_FACESIZE];
533 bool operator== (const FontNameSpecifier& rhs) const
534 {
535 return ::_tcscmp (fName, rhs.fName) == 0;
536 }
537 };
538#elif qStroika_FeatureSupported_XWindows
539 using FontNameSpecifier = SDKString;
540#else
541 // even if no actual GDI, need FontNameSpecifer to get stuff compiling
543#endif
544
545 public:
546 // string/name wrapper. Trivial for PC, and for Mac - converts between name under NUMBER ID
547 nonvirtual SDKString GetFontName () const;
548 nonvirtual void SetFontName (const SDKString& fontName);
549
550 // FontName info
551 nonvirtual FontNameSpecifier GetFontNameSpecifier () const;
552 nonvirtual void SetFontNameSpecifier (FontNameSpecifier fontNameSpecifier);
553
554 // Style info
555 nonvirtual bool GetStyle_Plain () const; // special composite of all other styles...
556 nonvirtual void SetStyle_Plain ();
557
558 nonvirtual bool GetStyle_Bold () const;
559 nonvirtual void SetStyle_Bold (bool isBold);
560
561 nonvirtual bool GetStyle_Italic () const;
562 nonvirtual void SetStyle_Italic (bool isItalic);
563
564 nonvirtual bool GetStyle_Underline () const;
565 nonvirtual void SetStyle_Underline (bool isUnderline);
566
567 enum SubOrSuperScript {
568 eSubscript,
569 eSuperscript,
570 eNoSubOrSuperscript
571 };
572 nonvirtual SubOrSuperScript GetStyle_SubOrSuperScript () const;
573 nonvirtual void SetStyle_SubOrSuperScript (SubOrSuperScript subOrSuperScript);
574
575#if qStroika_Foundation_Common_Platform_Windows
576 nonvirtual bool GetStyle_Strikeout () const;
577 nonvirtual void SetStyle_Strikeout (bool isStrikeout);
578#endif
579
580 using FontSize = uint16_t;
581 nonvirtual FontSize GetPointSize () const;
582 nonvirtual void SetPointSize (FontSize pointSize);
583
584#if qStroika_Foundation_Common_Platform_Windows
585 nonvirtual long PeekAtTMHeight () const; // Speed tweek
586 nonvirtual void PokeAtTMHeight (long tmHeight); // ditto
587#endif
588
589 nonvirtual Color GetTextColor () const;
590 nonvirtual void SetTextColor (const Color& textColor);
591
592 public:
593#if qStroika_Foundation_Common_Platform_Windows
594 nonvirtual LOGFONT GetOSRep () const;
595 nonvirtual void GetOSRep (LOGFONT* logFont) const;
596 nonvirtual void SetOSRep (LOGFONT logFont);
597 nonvirtual void LightSetOSRep (LOGFONT logFont);
598#elif qStroika_FeatureSupported_XWindows
599 static string mkOSRep (const string& foundry, const string& family, const string& weight, const string& slant, const string& pointSize);
600 nonvirtual string GetOSRep () const;
601 nonvirtual void SetFromOSRep (const string& osRep);
602#endif
603
604 public:
605 /**
606 */
607 strong_ordering operator<=> (const FontSpecification& rhs) const;
608
609 public:
610 /**
611 */
612 bool operator== (const FontSpecification& rhs) const;
613
614 public:
615 nonvirtual void MergeIn (const IncrementalFontSpecification& addInTheseAttributes);
616
617 private:
618#if qStroika_Foundation_Common_Platform_Windows
619 LOGFONT fFontInfo{}; // Could make this MUCH smaller on windows - do for future release!
620#else
621 FontNameSpecifier fFontFamily{};
622 bool fBold : 1 {false};
623 bool fItalics : 1 {false};
624 bool fUnderline : 1 {false};
625 short fFontSize{0};
626#endif
627 SubOrSuperScript fSubOrSuperScript{SubOrSuperScript::eNoSubOrSuperscript};
628 Color fTextColor{Color::kBlack};
629 };
630
631 /*
632 * <code>IncrementalFontSpecification</code> is a simple subclass of
633 * @'FontSpecification' which adds a bool flag for each
634 * font attribute indicating whether or not it is really specified.
635 * With this, and the @'FontSpecification::MergeIn' method,
636 * you can specify just one or two changes to a font record, pass them around,
637 * and apply them to an existing font choice.</p>
638 * See also, @'FontSpecification'
639 */
640 class IncrementalFontSpecification : public FontSpecification {
641 private:
642 using inherited = FontSpecification;
643
644 public:
645 IncrementalFontSpecification () = default;
646
647 // I may end up regretting this, for all the confusion it
648 // can cause, but it sure makes a number of things simpler
649 // and clearer-- LGP 960520
650 IncrementalFontSpecification (const FontSpecification& fontSpec);
651
652 /*
653 * Basic form of this API. For a feature of a font, say its size, there is a
654 * GetFEATURE () -
655 * REQUIRES FEATURE VALID
656 * GetFEATURE (bool* valid, FEATUURE* feature)-
657 * Either valid or feature can be nullptr, but if NON-nullptr filled in with
658 * feature/valid (except feature NOT filled in if not valid.
659 * InvalidateFEATURE ()-
660 * Just sets valid-flag false.
661 * SetFEATURE(FEATURE)-
662 * Specifies this as the feature value, and sets the valid flag TRUE.
663 *
664 * (NOTE: MAYBE simplify this with member templates if/when that supported by compilers? - LGP 970314)
665 */
666 public:
667 nonvirtual FontNameSpecifier GetFontNameSpecifier () const;
668 nonvirtual bool GetFontNameSpecifier_Valid () const;
669 nonvirtual void InvalidateFontNameSpecifier ();
670 nonvirtual void SetFontNameSpecifier (FontNameSpecifier fontNameSpecifier);
671 nonvirtual void SetFontName (const SDKString& fontName);
672
673 // Style info
674 nonvirtual bool GetStyle_Plain () const; // special composite of all other styles...
675 nonvirtual bool GetStyle_Plain_Valid () const;
676 nonvirtual void InvalidateStyles ();
677 nonvirtual void SetStyle_Plain ();
678
679 nonvirtual bool GetStyle_Bold () const;
680 nonvirtual bool GetStyle_Bold_Valid () const;
681 nonvirtual void InvalidateStyle_Bold ();
682 nonvirtual void SetStyle_Bold (bool isBold);
683
684 nonvirtual bool GetStyle_Italic () const;
685 nonvirtual bool GetStyle_Italic_Valid () const;
686 nonvirtual void InvalidateStyle_Italic ();
687 nonvirtual void SetStyle_Italic (bool isItalic);
688
689 nonvirtual bool GetStyle_Underline () const;
690 nonvirtual bool GetStyle_Underline_Valid () const;
691 nonvirtual void InvalidateStyle_Underline ();
692 nonvirtual void SetStyle_Underline (bool isUnderline);
693
694 nonvirtual SubOrSuperScript GetStyle_SubOrSuperScript () const;
695 nonvirtual bool GetStyle_SubOrSuperScript_Valid () const;
696 nonvirtual void InvalidateStyle_SubOrSuperScript ();
697 nonvirtual void SetStyle_SubOrSuperScript (SubOrSuperScript subOrSuperScript);
698
699#if qStroika_Foundation_Common_Platform_Windows
700 nonvirtual bool GetStyle_Strikeout () const;
701 nonvirtual bool GetStyle_Strikeout_Valid () const;
702 nonvirtual void InvalidateStyle_Strikeout ();
703 nonvirtual void SetStyle_Strikeout (bool isStrikeout);
704#endif
705
706 /*
707 * Note the closely related nature of PointSize and PointSizeIncement.
708 * If one is set, that automatically unsets the other. You cannot set both
709 * at the same time. The former is used to specify the point size exactly.
710 * The latter is used to specify an ajdustment to the pointsize.
711 */
712 nonvirtual unsigned short GetPointSize () const;
713 nonvirtual bool GetPointSize_Valid () const;
714 nonvirtual void InvalidatePointSize ();
715 nonvirtual void SetPointSize (FontSize pointSize);
716#if qStroika_Foundation_Common_Platform_Windows
717 nonvirtual void PokeAtTMHeight (long tmHeight); // ditto
718#endif
719
720 nonvirtual short GetPointSizeIncrement () const;
721 nonvirtual bool GetPointSizeIncrement_Valid () const;
722 nonvirtual void InvalidatePointSizeIncrement ();
723 nonvirtual void SetPointSizeIncrement (short pointSizeIncrement);
724
725 nonvirtual Color GetTextColor () const;
726 nonvirtual bool GetTextColor_Valid () const;
727 nonvirtual void InvalidateTextColor ();
728 nonvirtual void SetTextColor (const Color& textColor);
729
730 public:
731#if qStroika_Foundation_Common_Platform_Windows
732 nonvirtual LOGFONT GetOSRep () const;
733 nonvirtual void GetOSRep (LOGFONT* logFont) const;
734 nonvirtual void SetOSRep (LOGFONT logFont); // marks all attribs as valid
735 nonvirtual void LightSetOSRep (LOGFONT logFont);
736 nonvirtual bool GetDidSetOSRepCallFlag () const; // special flag indicating user did SetOSRep() cuz that
737 // sets things valid that we don't have special 'valid' flags
738 // for. Makes MergeIn() just copy flat out!
739#endif
740
741 bool operator<=> (const IncrementalFontSpecification& rhs) = delete;
742 bool operator== (const IncrementalFontSpecification& rhs) const;
743
744 public:
745 nonvirtual void MergeIn (const IncrementalFontSpecification& addInTheseAttributes);
746
747 private:
748 bool fFontSpecifierValid : 1 {false};
749 bool fStyleValid_Bold : 1 {false};
750 bool fStyleValid_Italic : 1 {false};
751 bool fStyleValid_Underline : 1 {false};
752 bool fStyleValid_SubOrSuperScript : 1 {false};
753#if qStroika_Foundation_Common_Platform_Windows
754 bool fStyleValid_Strikeout : 1 {false};
755 bool fDidSetOSRepCallFlag : 1 {false};
756#endif
757 bool fFontSizeValid : 1 {false};
758 bool fFontSizeIncrementValid : 1 {false};
759 bool fTextColorValid : 1 {false};
760 };
761
762 IncrementalFontSpecification Intersection (const IncrementalFontSpecification& lhs, const IncrementalFontSpecification& rhs);
763
764 // Must support for other Platforms - but not done yet... Also - should have OPTIONS specified to this class (CTOR) picking various filter
765 // options...
766 class InstalledFonts {
767 public:
768 enum FilterOptions {
769#if qStroika_Foundation_Common_Platform_Windows
770 eSkipAtSignFonts = 0x1,
771 eSkipRasterFonts = 0x2,
772#endif
773
774#if qStroika_Foundation_Common_Platform_Windows
775 eDefaultFilterOptions = eSkipAtSignFonts | eSkipRasterFonts
776#else
777 eDefaultFilterOptions = 0
778#endif
779 };
780 InstalledFonts (
781#if qStroika_FeatureSupported_XWindows
782 Display* display,
783#endif
784 FilterOptions filterOptions = eDefaultFilterOptions);
785
786 public:
787 nonvirtual const vector<SDKString>& GetUsableFontNames () const;
788
789 private:
790 FilterOptions fFilterOptions;
791 vector<SDKString> fFontNames;
792
793#if qStroika_Foundation_Common_Platform_Windows
794 private:
795 static BOOL FAR PASCAL FontFamilyAdderProc (ENUMLOGFONTEX* pelf, NEWTEXTMETRICEX* /*lpntm*/, int fontType, LPVOID pThis);
796#endif
797 };
798
799 // Query the OS for the default font that should be used for new text windows
800 FontSpecification GetStaticDefaultFont ();
801#if qStroika_Foundation_Common_Platform_Windows
802 FontSpecification GetStaticDefaultFont (BYTE charSet);
803#endif
804
805#if qStroika_Frameworks_Led_SupportGDI
806 /**
807 * Something of a hack version of GDI global variables. We want to keep certain GDI global variables
808 * computed ONCE, for speed reasons. And yet - if we get a certain windows message, we must refresh our cached global
809 * variables. The compromise is that all these globals are associated with this class, so that there is one place to
810 * call to refresh those globals.
811 */
812 class Globals {
813 public:
814 Globals ();
815
816 public:
817 static Globals& Get ();
818
819 private:
820 static Globals* sThe;
821
822 public:
823 nonvirtual void InvalidateGlobals ();
824
825 public:
826 nonvirtual DistanceType GetMainScreenLogPixelsH () const;
827 nonvirtual DistanceType GetMainScreenLogPixelsV () const;
828
829 public:
830 DistanceType fLogPixelsH;
831 DistanceType fLogPixelsV;
832
833 private:
834 class _Global_DESTRUCTOR_;
835 friend class _Global_DESTRUCTOR_;
836 };
837#endif
838
839 Led_Rect operator- (const Led_Rect& lhs, const Led_Point& rhs);
840 Led_Rect operator+ (Led_Point p, Led_Rect r);
841 Led_Rect operator+ (Led_Rect r, Led_Point p);
842 bool Intersect (const Led_Rect& lhs, const Led_Rect& rhs);
843#if qStroika_Frameworks_Led_SupportGDI
844 bool Intersect (const Led_Rect& lhs, const Region& rhs);
845 bool Intersect (const Region& lhs, const Led_Rect& rhs);
846 bool Intersect (const Region& lhs, const Region& rhs);
847#endif
848
849 Led_Rect Intersection (const Led_Rect& lhs, const Led_Rect& rhs);
850 Led_Rect operator* (const Led_Rect& lhs, const Led_Rect& rhs);
851
852 Led_Size operator+ (Led_Size lhs, Led_Size rhs);
853 Led_Size operator* (int lhs, Led_Size rhs);
854
855 Led_Rect InsetRect (const Led_Rect& r, int vBy, int hBy);
856 Led_Rect EnsureRectInRect (const Led_Rect& r, Led_Rect enlosingR);
857#if qStroika_Frameworks_Led_SupportGDI
858 Led_Rect EnsureRectOnScreen (const Led_Rect& r);
859#endif
860
861#if qStroika_Foundation_Common_Platform_Windows
862 Led_Point AsLedPoint (POINT p);
863 POINT AsPOINT (Led_Point p);
864 Led_Rect AsLedRect (RECT r);
865 RECT AsRECT (Led_Rect p);
866 SIZE AsSIZE (Led_Size s);
867 Led_Size AsLedSize (SIZE s);
868#elif qStroika_FeatureSupported_XWindows
869 Led_Rect AsLedRect (const XRectangle& r);
870 XRectangle AsXRect (const Led_Rect& r);
871#endif
872
873#if qStroika_Frameworks_Led_SupportGDI
874 TWIPS Led_CvtScreenPixelsToTWIPSV (CoordinateType from);
875 TWIPS Led_CvtScreenPixelsToTWIPSH (CoordinateType from);
876 CoordinateType Led_CvtScreenPixelsFromTWIPSV (TWIPS from);
877 CoordinateType Led_CvtScreenPixelsFromTWIPSH (TWIPS from);
878#endif
879
880#if qStroika_Frameworks_Led_SupportGDI
881 /*
882 @CLASS: FontMetrics
883 @DESCRIPTION: <p><code>FontMetrics</code> is a portable wrapper class on the Macintosh
884 <em>FontInfo</em> structure, or the Windows <em>TEXTMETRIC</em> structure. It provides
885 portable access to things like GetLineHeight (), and GetAscent (), etc...</p>
886 */
887 class FontMetrics {
888#if qStroika_FeatureSupported_XWindows
889 public:
890 struct PlatformSpecific {
891 DistanceType fAscent;
892 DistanceType fDescent;
893 DistanceType fLeading;
894 DistanceType fMaxCharWidth;
895 };
896#endif
897 public:
898 FontMetrics () = default;
899#if qStroika_Foundation_Common_Platform_Windows
900 FontMetrics (const TEXTMETRIC& from);
901#elif qStroika_FeatureSupported_XWindows
902 FontMetrics (const PlatformSpecific& from);
903#endif
904 FontMetrics (const FontMetrics&) = default;
905 FontMetrics& operator= (const FontMetrics& rhs) = default;
906
907 public:
908 nonvirtual DistanceType GetAscent () const;
909 nonvirtual DistanceType GetDescent () const;
910 nonvirtual DistanceType GetLeading () const;
911 nonvirtual DistanceType GetHeight () const; // does NOT include leading
912 nonvirtual DistanceType GetLineHeight () const; // includes leading
913
914 public:
915 nonvirtual DistanceType GetMaxCharacterWidth () const;
916#if qStroika_Foundation_Common_Platform_Windows
917 nonvirtual DistanceType GetAveCharacterWidth () const;
918#endif
919
920 // Convertion operator to make it easier to make GDI calls with one of our guys on a
921 // with something expected a system specific one - like to fill in its value!
922 public:
923#if qStroika_Foundation_Common_Platform_Windows
924 operator const TEXTMETRIC* () const;
925 operator TEXTMETRIC* ();
926#endif
927
928 private:
929#if qStroika_Foundation_Common_Platform_Windows
930 TEXTMETRIC fPlatformSpecific{};
931#elif qStroika_FeatureSupported_XWindows
932 PlatformSpecific fPlatformSpecific{};
933#endif
934 };
935#endif
936
937#if qStroika_Frameworks_Led_SupportGDI
938 Color Led_GetTextColor ();
939 Color Led_GetTextBackgroundColor ();
940 Color Led_GetSelectedTextColor ();
941 Color Led_GetSelectedTextBackgroundColor ();
942
943 class OffscreenTablet;
944#endif
945
946#if qStroika_Frameworks_Led_SupportGDI
947 /**
948 * This class is used to wrap a low level graphics drawing device. On Windows - this is an HDC.
949 * On the Mac - a GrafPtr (also CGrafPtr and GWorldPtr). On X-Windows - a drawable and display, and GC.</p>
950 *
951 * This class right now is a very thin wrapper on those drawing prodedures (mostly for backward compatability reasons.
952 * Eventually - it may do a better job of wrapping those concepts/APIs genericly.</p>
953 */
954 class Tablet {
955 public:
956#if qStroika_Foundation_Common_Platform_MacOS
957 Tablet (GrafPtr gp);
958#elif qStroika_Foundation_Common_Platform_Windows
959 enum OwnDCControl {
960 eOwnsDC,
961 eDoesntOwnDC
962 };
963
964 Tablet (HDC hdc = nullptr, OwnDCControl ownsDC = eOwnsDC);
965#elif qStroika_FeatureSupported_XWindows
966 Tablet (Display* display, Drawable drawable);
967#endif
968
969 public:
970 virtual ~Tablet ();
971
972 public:
973#if qStroika_Foundation_Common_Platform_MacOS
974 nonvirtual operator GrafPtr () const;
975#elif qStroika_Foundation_Common_Platform_Windows
976 nonvirtual operator HDC () const;
977#endif
978
979 public:
980 nonvirtual CoordinateType CvtFromTWIPSV (TWIPS from) const;
981 nonvirtual CoordinateType CvtFromTWIPSH (TWIPS from) const;
982 nonvirtual TWIPS CvtToTWIPSV (CoordinateType from) const;
983 nonvirtual TWIPS CvtToTWIPSH (CoordinateType from) const;
984
985 public:
986 nonvirtual Led_Point CvtFromTWIPS (TWIPS_Point from) const;
987 nonvirtual TWIPS_Point CvtToTWIPS (Led_Point from) const;
988 nonvirtual Led_Rect CvtFromTWIPS (TWIPS_Rect from) const;
989 nonvirtual TWIPS_Rect CvtToTWIPS (Led_Rect from) const;
990
991 public:
992 nonvirtual void ScrollBitsAndInvalRevealed (const Led_Rect& windowRect, CoordinateType scrollBy);
993 nonvirtual void FrameRegion (const Region& r, const Color& c);
994
995 public:
996 nonvirtual void FrameRectangle (const Led_Rect& r, Color c, DistanceType borderWidth);
997
998 public:
999#if qStroika_Foundation_Common_Platform_MacOS
1000 nonvirtual void SetPort ();
1001#elif qStroika_Foundation_Common_Platform_Windows
1002 nonvirtual BOOL BitBlt (int x, int y, int nWidth, int nHeight, Tablet* pSrcDC, int xSrc, int ySrc, DWORD dwRop);
1003 nonvirtual BOOL CreateCompatibleDC (Tablet* pDC);
1004 nonvirtual COLORREF SetTextColor (COLORREF crColor);
1005 nonvirtual COLORREF SetBkColor (COLORREF crColor);
1006 nonvirtual BOOL IsPrinting () const;
1007 nonvirtual BOOL RoundRect (int x1, int y1, int x2, int y2, int x3, int y3);
1008 nonvirtual BOOL TextOut (int x, int y, LPCTSTR lpszString, int nCount);
1009 // nonvirtual SIZE GetTextExtent (LPCTSTR lpszString, int nCount) const;
1010 nonvirtual int SetBkMode (int nBkMode);
1011 nonvirtual SIZE GetWindowExt () const;
1012 nonvirtual SIZE GetViewportExt () const;
1013 nonvirtual BOOL Rectangle (int x1, int y1, int x2, int y2);
1014 nonvirtual BOOL Rectangle (const RECT& r);
1015 nonvirtual BOOL Rectangle (LPCRECT lpRect);
1016 nonvirtual BOOL GetTextMetrics (LPTEXTMETRIC lpMetrics) const;
1017 nonvirtual HBITMAP SelectObject (HBITMAP hBitmap);
1018#if defined(STRICT)
1019 nonvirtual HFONT SelectObject (HFONT hFont);
1020#endif
1021 nonvirtual POINT SetWindowOrg (int x, int y);
1022 nonvirtual int GetDeviceCaps (int nIndex) const;
1023 nonvirtual BOOL Attach (HDC hDC, OwnDCControl ownsDC = eOwnsDC);
1024 nonvirtual HDC Detach ();
1025#elif qStroika_FeatureSupported_XWindows
1026 public:
1027 nonvirtual void SetFont (const FontSpecification& fontSpec);
1028
1029 private:
1030 map<string, XFontStruct*> fFontCache;
1031 enum {
1032 kMaxFontCacheSize = 5
1033 };
1034
1035 public:
1036 nonvirtual void SetDrawableOrigin (const Led_Point& origin);
1037
1038 private:
1039 Led_Point fDrawableOrigin;
1040#endif
1041
1042#if qStroika_Foundation_Common_Platform_Windows
1043 private:
1044 nonvirtual HWND GetWindow () const;
1045 nonvirtual unsigned int SetTextAlign (unsigned int nTextAlign);
1046#endif
1047
1048#if qStroika_FeatureSupported_XWindows
1049 public:
1050 static int IgnoreXErrorHandler (Display* display, XErrorEvent* error);
1051#endif
1052
1053#if qStroika_FeatureSupported_XWindows
1054 private:
1055 nonvirtual SDKString BestMatchFont (const FontSpecification& fsp, const vector<SDKString>& fontsList);
1056
1057 public:
1058 static void ParseFontName (const SDKString& fontName, SDKString* familyName, SDKString* fontSize, SDKString* fontWeight, SDKString* fontSlant);
1059#endif
1060
1061 public:
1062 nonvirtual void MoveTo (const Led_Point& to);
1063 nonvirtual void LineTo (const Led_Point& to);
1064
1065#if qStroika_FeatureSupported_XWindows
1066 private:
1067 Led_Point fCurDrawLineLoc;
1068#endif
1069
1070 public:
1071 nonvirtual void MeasureText (const FontMetrics& precomputedFontMetrics, const Led_tChar* text, size_t nTChars, DistanceType* charLocations);
1072 nonvirtual void TabbedTextOut (const FontMetrics& precomputedFontMetrics, const Led_tChar* text, size_t nBytes,
1073 TextDirection direction, Led_Point outputAt, CoordinateType hTabOrigin,
1074 const TabStopList& tabStopList, DistanceType* amountDrawn, CoordinateType hScrollOffset);
1075
1076 public:
1077 nonvirtual void SetBackColor (const Color& backColor);
1078 nonvirtual void SetForeColor (const Color& foreColor);
1079
1080 public:
1081 nonvirtual void EraseBackground_SolidHelper (const Led_Rect& eraseRect, const Color& eraseColor);
1082 nonvirtual void HilightArea_SolidHelper (const Led_Rect& hilightArea, Color hilightBackColor, Color hilightForeColor,
1083 Color oldBackColor, Color oldForeColor);
1084 nonvirtual void HilightArea_SolidHelper (const Region& hilightArea, Color hilightBackColor, Color hilightForeColor,
1085 Color oldBackColor, Color oldForeColor);
1086
1087#if qStroika_Foundation_Common_Platform_Windows
1088 private:
1089 class RecolorHelper;
1090
1091 private:
1092 RecolorHelper* fRecolorHelper;
1093#endif
1094
1095 public:
1096 class ClipNarrowAndRestore;
1097
1098 public:
1099 nonvirtual Region GetClip () const;
1100 nonvirtual bool GetClip (Region* r) const;
1101 nonvirtual void SetClip ();
1102 nonvirtual void SetClip (const Led_Rect& clipTo);
1103 nonvirtual void SetClip (const Region& clipTo);
1104
1105 public:
1106 nonvirtual FontMetrics GetFontMetrics () const;
1107
1108#if qStroika_Foundation_Common_Platform_MacOS
1109 private:
1110 GrafPtr fGrafPort;
1111#elif qStroika_Foundation_Common_Platform_Windows
1112 public:
1113 HDC m_hDC; // The output DC (must be first data member)
1114 HDC m_hAttribDC; // The Attribute DC
1115 BOOL m_bPrinting;
1116 OwnDCControl fOwnsDC;
1117
1118 private:
1119 mutable DistanceType fLogPixelsV;
1120 mutable DistanceType fLogPixelsH;
1121#elif qStroika_FeatureSupported_XWindows
1122 private:
1123 Display* fDisplay;
1124 Drawable fDrawable;
1125 GC fGC;
1126 Colormap fColormap;
1127 mutable XFontStruct* fCachedFontInfo;
1128 map<string, string> fFontMappingCache;
1129#endif
1130
1131 public:
1132 friend class OffscreenTablet;
1133 };
1134
1135 /*
1136 @CLASS: Tablet::ClipNarrowAndRestore
1137 @DESCRIPTION: <p>Further narrow the existing clip region in the given tablet to the constructor. Then
1138 restore the clip region for the tablet to what it was when the contructor was called.</p>
1139 */
1140 class Tablet::ClipNarrowAndRestore {
1141 public:
1142 ClipNarrowAndRestore (Tablet* tablet);
1143 ClipNarrowAndRestore (Tablet* tablet, const Led_Rect& clipFurtherTo);
1144 ClipNarrowAndRestore (Tablet* tablet, const Region& clipFurtherTo);
1145 ~ClipNarrowAndRestore ();
1146
1147 private:
1148 Tablet* fTablet;
1149 bool fHasOldClip;
1150 Region fOldClip;
1151 };
1152
1153#if qStroika_Foundation_Common_Platform_MacOS
1154 /**
1155 */
1156 GrafPtr Led_GetCurrentGDIPort ();
1157#endif
1158
1159#if qStroika_Foundation_Common_Platform_Windows
1160 class WindowDC : public Tablet {
1161 public:
1162 WindowDC (HWND hWnd);
1163 ~WindowDC ();
1164
1165 private:
1166 HWND fHWnd_;
1167 };
1168#endif
1169
1170#if qStroika_Foundation_Common_Platform_MacOS
1171 class MacPortAndClipRegionEtcSaver {
1172 public:
1173 MacPortAndClipRegionEtcSaver ();
1174 ~MacPortAndClipRegionEtcSaver ();
1175
1176 private:
1177 GrafPtr fSavedPort;
1178 short fOldLeft;
1179 short fOldTop;
1180 RGBColor fRGBFgColor;
1181 RGBColor fRGBBkColor;
1182 RgnHandle fOldClip;
1183 };
1184#endif
1185
1186#if qStroika_Foundation_Common_Platform_Windows
1187 class Bitmap {
1188 public:
1189 Bitmap () = default;
1190 ~Bitmap ();
1191
1192 public:
1193 nonvirtual void DeleteObject ();
1194 nonvirtual operator HBITMAP () const;
1195
1196 public:
1197 nonvirtual Led_Size GetImageSize () const;
1198 nonvirtual BOOL CreateCompatibleBitmap (HDC hdc, DistanceType nWidth, DistanceType nHeight);
1199 nonvirtual BOOL CreateCompatibleDIBSection (HDC hdc, DistanceType nWidth, DistanceType nHeight);
1200 nonvirtual void LoadBitmap (HINSTANCE hInstance, LPCTSTR lpBitmapName);
1201
1202 private:
1203 HBITMAP m_hObject{nullptr};
1204 Led_Size fImageSize{};
1205 };
1206#endif
1207
1208 /*
1209 @DESCRIPTION: <p>An offscreen tablet is a helper object used to do offscreen imaging. This is useful in
1210 avoidance of flicker. Also, by encapsulating this procedure into a class, it becomes easier
1211 to add the functionality to several places in Led, yet with very different underlying implementations
1212 on each platform.</p>
1213 */
1214 class OffscreenTablet {
1215 public:
1216 OffscreenTablet ();
1217 ~OffscreenTablet ();
1218
1219 public:
1220 nonvirtual void Setup (Tablet* origTablet);
1221 nonvirtual Tablet* PrepareRect (const Led_Rect& currentRowRect, DistanceType extraToAddToBottomOfRect = 0);
1222 nonvirtual void BlastBitmapToOrigTablet ();
1223
1224 private:
1225 class OT : public Tablet {
1226 private:
1227 using inherited = Tablet;
1228
1229 public:
1230#if qStroika_Foundation_Common_Platform_MacOS
1231 OT (GrafPtr gp);
1232#elif qStroika_Foundation_Common_Platform_Windows
1233 OT (HDC hdc = nullptr, OwnDCControl ownsDC = eOwnsDC);
1234#elif qStroika_FeatureSupported_XWindows
1235 OT (Display* display, Drawable drawable);
1236#endif
1237 };
1238
1239 private:
1240 Tablet* fOrigTablet;
1241 Led_Rect fOffscreenRect;
1242 Tablet* fOffscreenTablet;
1243#if qStroika_Foundation_Common_Platform_MacOS
1244 GDHandle fOrigDevice;
1245 CGrafPtr fOrigPort;
1246 GWorldPtr fOffscreenGWorld;
1247#elif qStroika_Foundation_Common_Platform_Windows
1248 OT fMemDC;
1249 Bitmap fMemoryBitmap; // only can create / select inside loop cuz there is where we know the size.
1250 // but decare outside, so stays around for successive rows which are the same size.
1251 HBITMAP fOldBitmapInDC; // used for save/restore of bitmap associated with the DC.
1252#elif qStroika_FeatureSupported_XWindows
1253 Drawable fPixmap;
1254#endif
1255 };
1256
1257 /*
1258 @DESCRIPTION: <p><code>GDI_Obj_Selector</code> is a stack-based class designed to help
1259 out selecting objects into a Tablet* (windows DC, grafport, etc).
1260 <p>The constructor takes a tablet, and object to select into it (HGDIObject, etc),
1261 and selects it into the tablet. It saves gthe results of the SelectObject calls (old values).
1262 And on its destructor, it restores the old values.</p>
1263 <p>This is useful when you want to make sure that an object you've selected into a tablet (HDC)
1264 will be released, and restored to its original state through all paths through
1265 the code, including in the even of exceptions.</p>
1266 */
1267 class GDI_Obj_Selector {
1268 public:
1269#if qStroika_Foundation_Common_Platform_Windows
1270 GDI_Obj_Selector (Tablet* tablet, HGDIOBJ objToSelect);
1271#elif qStroika_Foundation_Common_Platform_MacOS || qStroika_FeatureSupported_XWindows
1272 GDI_Obj_Selector (Tablet* tablet, const Pen& pen);
1273#endif
1274 public:
1275 ~GDI_Obj_Selector ();
1276
1277 private:
1278 Tablet* fTablet;
1279#if qStroika_Foundation_Common_Platform_Windows
1280 HGDIOBJ fRestoreObject;
1281 HGDIOBJ fRestoreAttribObject;
1282#elif qStroika_Foundation_Common_Platform_MacOS
1283 Pen fRestorePen;
1284#endif
1285 };
1286#endif
1287
1288// Even for windows we have have this defined if we build including QuickTime support!
1289#ifndef qHaveMacPictureDefined
1290#define qHaveMacPictureDefined 0
1291#endif
1292
1293/*
1294 @CLASS: Led_Picture
1295 @DESCRIPTION: <p><code>Led_Picture</code> is a portable abstraction of a Macintosh Picture object.
1296 It can be displayed both on windows, and on the Mac (on Windows, it is only displayed if Apples
1297 QuickTime is installed). There are a bunch of routines (e.g Led_GetMacPictTop) which portable
1298 allow access to the size of the picture (even on windows if QT not available). And there are
1299 portable routines to draw the picture (again, with the windows QT caveat).</p>
1300 */
1301#if qHaveMacPictureDefined
1302 using Led_Picture = Picture;
1303#else
1304 struct Led_Picture {
1305 short picSize;
1306 short picFrameTop;
1307 short picFrameLeft;
1308 short picFrameBottom;
1309 short picFrameRight;
1310 // other data off end (specified by picSize) - note byte order for shorts is MAC
1311 };
1312#endif
1313
1314 short Led_GetMacPictTop (const Led_Picture* picture);
1315 short Led_GetMacPictLeft (const Led_Picture* picture);
1316 short Led_GetMacPictBottom (const Led_Picture* picture);
1317 short Led_GetMacPictRight (const Led_Picture* picture);
1318 short Led_GetMacPictWidth (const Led_Picture* picture);
1319 short Led_GetMacPictHeight (const Led_Picture* picture);
1320 Led_Size Led_GetMacPictSize (const Led_Picture* picture);
1321#if qStroika_Foundation_Common_Platform_MacOS
1322 short Led_GetMacPictTop (const Led_Picture* const* picture);
1323 short Led_GetMacPictLeft (const Led_Picture* const* picture);
1324 short Led_GetMacPictBottom (const Led_Picture* const* picture);
1325 short Led_GetMacPictRight (const Led_Picture* const* picture);
1326 short Led_GetMacPictWidth (const Led_Picture* const* picture);
1327 short Led_GetMacPictHeight (const Led_Picture* const* picture);
1328 Led_Size Led_GetMacPictSize (const Led_Picture* const* picture);
1329#endif
1330
1331// Windows DIB support
1332#ifndef qHaveWindowsDIBDefined
1333#define qHaveWindowsDIBDefined qStroika_Foundation_Common_Platform_Windows
1334#endif
1335
1336#if !qHaveWindowsDIBDefined
1337 // structs copied (paraphrased) from MSVC 4.1 includes (WinGDI.h)
1338 struct BITMAPINFOHEADER {
1339 unsigned long biSize;
1340 long biWidth;
1341 long biHeight;
1342 unsigned short biPlanes;
1343 unsigned short biBitCount;
1344 unsigned long biCompression;
1345 unsigned long biSizeImage;
1346 long biXPelsPerMeter;
1347 long biYPelsPerMeter;
1348 unsigned long biClrUsed;
1349 unsigned long biClrImportant;
1350 };
1351 struct BITMAPCOREHEADER {
1352 unsigned long bcSize;
1353 unsigned short bcWidth;
1354 unsigned short bcHeight;
1355 unsigned short bcPlanes;
1356 unsigned short bcBitCount;
1357 };
1358 struct RGBQUAD {
1359 unsigned char rgbBlue;
1360 unsigned char rgbGreen;
1361 unsigned char rgbRed;
1362 unsigned char rgbReserved;
1363 };
1364 struct RGBTRIPLE {
1365 unsigned char rgbtBlue;
1366 unsigned char rgbtGreen;
1367 unsigned char rgbtRed;
1368 };
1369 struct BITMAPINFO {
1370 BITMAPINFOHEADER bmiHeader;
1371 RGBQUAD bmiColors[1];
1372 };
1373#endif
1374 /*
1375 @CLASS: Led_DIB
1376 @DESCRIPTION: <p><em>Led_DIB</em> is a MS-Windows DIB (device independent bitmap) object. Much
1377 like @'Led_Picture', it has a host of accessor routines to get at its size, etc. But slightly
1378 better than Led_Picture, Led_DIB can be rendered on the Mac without assuming any special
1379 software (ie no analog to QT) is available. The downside is that I only support a few types
1380 of DIBs, but I appear to have most that windows currently generates. And it wouldn't be
1381 too hard to extend the code to support a few more types, if I knew what they were.</p>
1382 */
1383 using Led_DIB = BITMAPINFO;
1384
1385 Led_Size Led_GetDIBImageSize (const Led_DIB* dib);
1386 size_t Led_GetDIBPalletByteCount (const Led_DIB* dib);
1387 size_t Led_GetDIBImageRowByteCount (const Led_DIB* dib);
1388 size_t Led_GetDIBImageByteCount (const Led_DIB* dib);
1389 Led_DIB* Led_CloneDIB (const Led_DIB* dib);
1390 const void* Led_GetDIBBitsPointer (const Led_DIB* dib);
1391
1392#if qStroika_Foundation_Common_Platform_Windows
1393 Led_DIB* Led_DIBFromHBITMAP (HDC hDC, HBITMAP hbm);
1394#endif
1395
1396#if qStroika_Frameworks_Led_SupportGDI
1397
1398 void AddRectangleToRegion (Led_Rect addRect, Region* toRgn);
1399#endif
1400
1401#if qStroika_Frameworks_Led_ProvideIMESupport
1402 class IME {
1403 public:
1404 IME ();
1405
1406 public:
1407 static IME& Get ();
1408
1409 private:
1410 static IME* sThe;
1411
1412 private:
1413 nonvirtual bool Available () const; //tmphack - don't think this is ever used
1414 public:
1415 nonvirtual void ForgetPosition ();
1416 nonvirtual void NotifyPosition (HWND pWnd, const SHORT x, const SHORT y);
1417 nonvirtual void NotifyOfFontChange (HWND hWnd, const LOGFONT& lf);
1418 nonvirtual void IMEOn (HWND pWnd);
1419 nonvirtual void IMEOff (HWND pWnd);
1420 nonvirtual void Enable ();
1421 nonvirtual void Disable ();
1422 nonvirtual wstring GetCompositionResultStringW (HWND hWnd);
1423
1424 private:
1425 nonvirtual void UpdatePosition (const HWND hWnd, const SHORT x, const SHORT y);
1426 nonvirtual void SendSimpleMessage (HWND pWnd, UINT fnc, WPARAM wParam);
1427
1428 LRESULT (FAR PASCAL* fSendIMEMessageProc)
1429 (HWND, DWORD);
1430 BOOL (FAR PASCAL* fIMEEnableProc)
1431 (HWND, BOOL);
1432 HIMC (FAR PASCAL* fImmGetContext)
1433 (HWND);
1434 BOOL (FAR PASCAL* fImmSetCompositionFont)
1435 (HIMC, const LOGFONT*);
1436 BOOL (FAR PASCAL* fImmReleaseContext)
1437 (HWND, HIMC);
1438 LONG (FAR PASCAL* fImmGetCompositionStringW)
1439 (HIMC, DWORD, LPVOID, DWORD);
1440 BOOL (FAR PASCAL* fImmSetCompositionWindow)
1441 (HIMC, const void*);
1442 BOOL (FAR PASCAL* fImmSetOpenStatus)
1443 (HIMC, BOOL);
1444
1445 bool fWinNlsAvailable;
1446 SHORT fLastX;
1447 SHORT fLastY;
1448
1449 private:
1450 class _Global_DESTRUCTOR_;
1451 friend class _Global_DESTRUCTOR_;
1452 };
1453#endif
1454
1455 Led_Rect CenterRectInRect (const Led_Rect& r, const Led_Rect& centerIn);
1456#if qStroika_Foundation_Common_Platform_Windows
1457 void Led_CenterWindowInParent (HWND w);
1458#endif
1459
1460}
1461
1462/*
1463 ********************************************************************************
1464 ***************************** Implementation Details ***************************
1465 ********************************************************************************
1466 */
1467#include "GDI.inl"
1468
1469#endif /*_Stroika_Frameworks_Led_GDI_h_*/
set< T > Intersection(const set< T > &s1, const set< T > &s2)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
conditional_t< qTargetPlatformSDKUseswchar_t, wchar_t, char > SDKChar
Definition SDKChar.h:71
basic_string< SDKChar > SDKString
Definition SDKString.h:38