1414#include " ckCanvas.h"
1515#include " ckWindow.h"
1616#include < Quickdraw.h>
17+ #include < Icons.h>
1718#include < Resources.h>
19+ #include < Memory.h>
20+
21+ static bool __CKPlotBWIcon (short resourceId, const Rect& destRect, const WindowPtr window) {
22+
23+ Handle iconHandle = GetResource (' ICN#' , resourceId);
24+ bool hasMask = true ;
25+ if (!iconHandle) {
26+ iconHandle = GetResource (' ICON' , resourceId);
27+ hasMask = false ;
28+ }
29+
30+ if (!iconHandle) {
31+ CKLog (" Resource %d not found." , resourceId);
32+ return false ;
33+ }
34+
35+ HLock (iconHandle);
36+ const UInt8* data = (const UInt8*)*iconHandle;
37+
38+ const UInt8* maskData = hasMask ? data : nullptr ;
39+ const UInt8* iconData = hasMask ? data + 128 : data;
40+
41+ BitMap srcBM;
42+ srcBM.baseAddr = (Ptr)iconData;
43+ srcBM.rowBytes = 4 ;
44+ SetRect (&srcBM.bounds , 0 , 0 , 32 , 32 );
45+
46+ const BitMap* dstBits = &(window->portBits );
47+
48+ Rect srcRect = srcBM.bounds ;
49+ Rect dstRectCopy = destRect;
50+
51+ if (hasMask) {
52+ BitMap maskBM;
53+ maskBM.baseAddr = (Ptr)maskData;
54+ maskBM.rowBytes = 4 ;
55+ SetRect (&maskBM.bounds , 0 , 0 , 32 , 32 );
56+ Rect maskRect = maskBM.bounds ;
57+ CopyMask (&srcBM, &maskBM, dstBits, &srcRect, &maskRect, &dstRectCopy);
58+ } else {
59+ CopyBits (&srcBM, dstBits, &srcRect, &dstRectCopy, srcCopy, NULL );
60+ }
61+
62+ HUnlock (iconHandle);
63+ ReleaseResource (iconHandle);
64+ return true ;
65+ }
1866
1967CKCanvas::CKCanvas (const CKControlInitParams& params)
2068 : CKControl(params, CKControlType::Canvas) {
@@ -24,7 +72,7 @@ CKCanvas::CKCanvas(const CKControlInitParams& params)
2472 this ->__gworldptr = NULL ;
2573
2674 if (!CKHasColorQuickDraw ()) {
27- CKLog (" CKCanvas requires Color QuickDraw; offscreen drawing disabled." );
75+ CKLog (" Color QuickDraw not available ; offscreen drawing disabled (drawing directly to window) ." );
2876 return ;
2977 }
3078
@@ -55,7 +103,47 @@ void CKCanvas::Redraw() {
55103 return ;
56104 }
57105
106+ // No offscreen buffer – draw directly into the window (mono fallback).
58107 if (!this ->__gworldptr ) {
108+ if (!this ->__hasQueuedIcon ) {
109+ return ;
110+ }
111+
112+ GrafPtr oldPort;
113+ GetPort (&oldPort);
114+ SetPort (this ->owner ->GetWindowPtr ());
115+
116+ short top = this ->rect ->origin ->y + this ->__queuedIconWhere .y ;
117+ short left = this ->rect ->origin ->x + this ->__queuedIconWhere .x ;
118+ Rect destRect = {(short )top, (short )left, (short )(top + 32 ), (short )(left + 32 )};
119+
120+ const bool hasIconUtils = CKHasIconUtilities ();
121+ const bool hasColorQD = CKHasColorQuickDraw ();
122+
123+ if (!hasColorQD || !hasIconUtils) {
124+ if (!__CKPlotBWIcon (this ->__queuedIconResourceId , destRect, this ->owner ->GetWindowPtr ())) {
125+ this ->__hasQueuedIcon = false ;
126+ }
127+ } else {
128+
129+ CIconHandle cIconHandle = GetCIcon (this ->__queuedIconResourceId );
130+ if (!cIconHandle) {
131+ Handle iconHandle = GetIcon (this ->__queuedIconResourceId );
132+ if (!iconHandle) {
133+ CKLog (" Resource %d not found." , this ->__queuedIconResourceId );
134+ this ->__hasQueuedIcon = false ;
135+ SetPort (oldPort);
136+ return ;
137+ }
138+ PlotIcon (&destRect, iconHandle);
139+ ReleaseResource (iconHandle);
140+ } else {
141+ PlotCIcon (&destRect, cIconHandle);
142+ DisposeCIcon (cIconHandle);
143+ }
144+ }
145+
146+ SetPort (oldPort);
59147 return ;
60148 }
61149
@@ -74,7 +162,7 @@ void CKCanvas::Redraw() {
74162 return ;
75163 }
76164
77- Rect destRect = {this ->rect ->origin ->x , this ->rect ->origin ->y , (short )(this ->rect ->size ->height + this ->rect ->origin ->y ), (short )(this ->rect ->size ->width + this ->rect ->origin ->x )};
165+ Rect destRect = {( short ) this ->rect ->origin ->x , ( short ) this ->rect ->origin ->y , (short )(this ->rect ->size ->height + this ->rect ->origin ->y ), (short )(this ->rect ->size ->width + this ->rect ->origin ->x )};
78166 Rect srcRect = {0 , 0 , (short )this ->rect ->size ->height , (short )this ->rect ->size ->width };
79167
80168 CopyBits ((BitMap*)&(**offscreenPixMap),
@@ -198,7 +286,20 @@ void CKCanvas::DrawLine(CKPoint start, CKPoint end, CKColor c) {
198286
199287bool CKCanvas::DrawResourceIcon (short resourceId, CKPoint where) {
200288
289+ this ->__hasQueuedIcon = true ;
290+ this ->__queuedIconResourceId = resourceId;
291+ this ->__queuedIconWhere = where;
292+
201293 if (!this ->__gworldptr ) {
294+ if (this ->owner ) {
295+ this ->MarkAsDirty ();
296+ }
297+ return true ;
298+ }
299+
300+ if (!CKHasIconUtilities ()) {
301+ CKLog (" Icon Utilities unavailable; cannot draw icons." );
302+ this ->__hasQueuedIcon = false ;
202303 return false ;
203304 }
204305
@@ -213,29 +314,35 @@ bool CKCanvas::DrawResourceIcon(short resourceId, CKPoint where) {
213314 GetGWorld (&oldPort, &oldGD); // Save the old port
214315 SetGWorld (this ->__gworldptr , NULL ); // Set the GWorld as the current port
215316
317+ const bool hasIconUtils = CKHasIconUtilities ();
318+ const bool hasColorQD = CKHasColorQuickDraw ();
319+
216320 CIconHandle cIconHandle = nullptr ;
217321 Handle iconHandle = nullptr ;
218322
219323 // Try color first.
220- cIconHandle = GetCIcon (resourceId);
221- bool isColor = true ;
324+ if (hasIconUtils && hasColorQD) {
325+ cIconHandle = GetCIcon (resourceId);
326+ }
222327 if (!cIconHandle) {
223328 // OK, try monochrome.
224329 iconHandle = GetIcon (resourceId);
225- isColor = false ;
226330 if (!iconHandle) {
227331 CKLog (" Resource %d not found." , resourceId);
332+ this ->__hasQueuedIcon = false ;
228333 SetGWorld (oldPort, oldGD);
229334 UnlockPixels (offscreenPixMap);
230335 return false ;
231336 }
232337 }
233- Rect destRect = {0 , 0 , 32 , 32 };
338+ Rect destRect = {( short )where. y , ( short )where. x , ( short )(where. y + 32 ), ( short )(where. x + 32 ) };
234339
235- if (isColor ) {
340+ if (cIconHandle ) {
236341 PlotCIcon (&destRect, cIconHandle);
237342 } else {
238- PlotIcon (&destRect, iconHandle);
343+ if (hasIconUtils) {
344+ PlotIcon (&destRect, iconHandle);
345+ }
239346 }
240347
241348 SetGWorld (oldPort, oldGD); // Restore the old port
@@ -247,5 +354,8 @@ bool CKCanvas::DrawResourceIcon(short resourceId, CKPoint where) {
247354 }
248355
249356 UnlockPixels (offscreenPixMap);
357+ if (this ->owner ) {
358+ this ->MarkAsDirty ();
359+ }
250360 return true ;
251361}
0 commit comments