Skip to content

Commit 7fa3d11

Browse files
committed
feat: QuickDraw color-aware pattern fills and text, CopyBits safety
QuickDraw color improvements: - FillRect: use QDPlatform_SelectPatternColor() to respect port foreground/background colors instead of hardcoded black/white - FillOval: same fix - patterns now render in port colors - Text rendering: derive glyph foreground color from port->fgColor instead of pattern byte intensity (enables colored text) Security/safety: - CopyBits: validate source/destination offsets are non-negative before casting to UInt32 to prevent unsigned wraparound on misaligned bitmaps - EventDispatcher inContent: add NULL check on whichWindow before dereference (race condition protection) Cleanup: - Remove 7 debug serial_puts/MemoryManager_CheckSuspectBlock calls from DragWindow hot path in EventDispatcher
1 parent 2f37f89 commit 7fa3d11

File tree

3 files changed

+19
-30
lines changed

3 files changed

+19
-30
lines changed

src/EventManager/EventDispatcher.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ Boolean HandleMouseDown(EventRecord* event)
298298

299299
case inContent: {
300300
/* Click in window content */
301+
if (!whichWindow) return true; /* Safety: window may have been closed */
301302
EVT_LOG_DEBUG("HandleMouseDown: inContent case - whichWindow=%p\n", (void*)whichWindow);
302303

303304
WindowPtr frontWin = FrontWindow();
@@ -345,15 +346,7 @@ Boolean HandleMouseDown(EventRecord* event)
345346
(void*)whichWindow, dragBounds.top, dragBounds.left,
346347
dragBounds.bottom, dragBounds.right);
347348

348-
extern void serial_puts(const char *str);
349-
serial_puts("[EVT] ABOUT TO CALL DragWindow\n");
350-
serial_puts("[EVT] DragWindow function ptr logged\n");
351-
352-
serial_puts("[MEM] before DragWindow\n");
353-
MemoryManager_CheckSuspectBlock("before_DragWindow");
354349
DragWindow(whichWindow, event->where, &dragBounds);
355-
serial_puts("[MEM] after DragWindow\n");
356-
MemoryManager_CheckSuspectBlock("after_DragWindow");
357350
EVT_LOG_DEBUG("HandleMouseDown: DragWindow returned\n");
358351
} else {
359352
EVT_LOG_DEBUG("HandleMouseDown: inDrag but whichWindow is NULL!\n");

src/QuickDraw/Bitmaps.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,10 +642,16 @@ static void CopyBitsUnscaled(const BitMap *srcBits, const BitMap *dstBits,
642642
for (SInt16 line = 0; line < height; line++) {
643643
SInt16 srcOffsetY = (srcRect->top + line - srcBits->bounds.top);
644644
SInt16 dstOffsetY = (dstRect->top + line - dstBits->bounds.top);
645+
SInt16 srcOffsetX = srcRect->left - srcBits->bounds.left;
646+
SInt16 dstOffsetX = dstRect->left - dstBits->bounds.left;
647+
648+
/* Skip lines with negative offsets to prevent unsigned wraparound */
649+
if (srcOffsetY < 0 || dstOffsetY < 0 || srcOffsetX < 0 || dstOffsetX < 0) continue;
650+
645651
UInt32 srcStart = (UInt32)srcOffsetY * (UInt32)srcRowBytes +
646-
(UInt32)(srcRect->left - srcBits->bounds.left) * 4u;
652+
(UInt32)srcOffsetX * 4u;
647653
UInt32 dstStart = (UInt32)dstOffsetY * (UInt32)dstRowBytes +
648-
(UInt32)(dstRect->left - dstBits->bounds.left) * 4u;
654+
(UInt32)dstOffsetX * 4u;
649655
UInt32 copyBytes = (UInt32)width * 4u;
650656

651657
/* Bounds safety: if pmReserved holds buffer size, clamp copy */

src/QuickDraw/QuickDrawPlatform.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -498,18 +498,12 @@ void QDPlatform_DrawShape(GrafPtr port, GrafVerb verb, const Rect* rect,
498498
}
499499
}
500500
} else if (verb == fill) {
501-
/* Fill with pattern (used by FillRect) */
501+
/* Fill with pattern using port foreground/background colors */
502502
if (pat) {
503503
for (SInt32 y = rect->top; y < rect->bottom; y++) {
504504
for (SInt32 x = rect->left; x < rect->right; x++) {
505-
/* Get pattern bit (8x8 repeating) */
506-
SInt32 patY = y % 8; /* Use absolute position for desktop pattern */
507-
SInt32 patX = x % 8;
508-
UInt8 patByte = pat->pat[patY];
509-
Boolean bit = (patByte >> (7 - patX)) & 1;
510-
511-
/* Use black for 1 bits, white for 0 bits */
512-
UInt32 color = bit ? pack_color(0, 0, 0) : pack_color(255, 255, 255);
505+
UInt32 color = QDPlatform_SelectPatternColor(port, pat, x, y,
506+
pack_color(0, 0, 0));
513507
QDPlatform_SetPixel(x + offsetX, y + offsetY, color);
514508
}
515509
}
@@ -579,11 +573,7 @@ void QDPlatform_DrawShape(GrafPtr port, GrafVerb verb, const Rect* rect,
579573

580574
UInt32 color = fallbackColor;
581575
if (pat) {
582-
SInt32 patY = (verb == paint) ? ((y - rect->top) & 7) : (y & 7);
583-
SInt32 patX = (verb == paint) ? ((x - rect->left) & 7) : (x & 7);
584-
UInt8 patByte = pat->pat[patY];
585-
Boolean bit = (patByte >> (7 - patX)) & 1;
586-
color = bit ? pack_color(0, 0, 0) : pack_color(255, 255, 255);
576+
color = QDPlatform_SelectPatternColor(port, pat, x, y, fallbackColor);
587577
}
588578

589579
QDPlatform_SetPixel(x + offsetX, y + offsetY, color);
@@ -1324,12 +1314,12 @@ void QDPlatform_DrawGlyphBitmap(GrafPtr port, Point pen,
13241314
SInt16 destHeight = destBits->bounds.bottom - destBits->bounds.top;
13251315
SInt16 destRowBytes = destBits->rowBytes & 0x3FFF;
13261316

1327-
/* Determine foreground color from pattern */
1328-
uint32_t fgColor = 0xFF000000; /* Black default */
1329-
if (pattern) {
1330-
/* Use first byte of pattern to determine intensity */
1331-
uint8_t intensity = 255 - pattern->pat[0];
1332-
fgColor = pack_color(intensity, intensity, intensity);
1317+
/* Determine foreground color from port's foreground color setting */
1318+
uint32_t fgColor;
1319+
if (port) {
1320+
fgColor = QDPlatform_MapQDColor(port->fgColor);
1321+
} else {
1322+
fgColor = pack_color(0, 0, 0); /* Black default */
13331323
}
13341324

13351325
/* Get framebuffer pointer */

0 commit comments

Comments
 (0)