1: /*
2: ============================================================================
3: xoblite™ -> an advanced "extended shell" for Microsoft® Windows® 11
4: Copyright © 2002-2026 Karl Henrik Henriksson [qwilk/@xoblite]
5: Copyright © 2001-2004 The Blackbox for Windows Development Team
6: http://xoblite.net/ + https://github.com/xoblite/
7: ============================================================================
8:
9: Blackbox for Windows is free software, released under the
10: GNU General Public License (GPL version 2 or later), with an extension
11: that allows linking of proprietary modules under a controlled interface.
12: What this means is that plugins etc. are allowed to be released
13: under any license the author wishes. Please note, however, that the
14: original Blackbox gradient math code used in Blackbox for Windows
15: is available under the BSD license.
16:
17: http://www.fsf.org/licenses/gpl.html
18: http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
19: http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5
20:
21: This program is distributed in the hope that it will be useful,
22: but WITHOUT ANY WARRANTY; without even the implied warranty of
23: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24: GNU General Public License for more details.
25:
26: For additional license information, please read the included license.html.
27:
28: ============================================================================
29: */
30:
31: #include "BImage.h"
32: #include "..\Settings\Settings.h"
33: #include <malloc.h>
34:
35: extern Settings* pSettings;
36:
37: //===========================================================================
38: // Function: AlphaRect
39: // Purpose: ...
40: //===========================================================================
41:
42: void BImage::AlphaRect(HDC hdc, RECT rect, unsigned char alpha)
43: {
44: CreateBuffer(hdc, rect, false);
45:
46: // Copy pixel data from the destination...
47: BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
48:
49: // Set per pixel alpha values...
50: unsigned int x, y, count = 0;
51: for (y = 0; y < height ; y++)
52: {
53: for (x = 0; x < width; x++)
54: {
55: pixels[count+3] = alpha;
56: count += 4;
57: }
58: }
59:
60: // Copy the pixel data including alpha values back to the destination...
61: BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
62:
63: DestroyBuffer();
64: }
65:
66: //===========================================================================
67: // Function: AlphaBorder
68: // Purpose: ...
69: //===========================================================================
70:
71: void BImage::AlphaBorder(HDC hdc, RECT rect, unsigned char alpha, int borderWidth)
72: {
73: // Copy pixel data from the destination...
74: CreateBuffer(hdc, rect, false);
75: BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
76:
77: int widthTimesFour = width * 4;
78: unsigned int x, y, count1, count2, nextValueOffset;
79:
80: for (int n = 1; n <= borderWidth; n++)
81: {
82: // Set per pixel alpha values along the top+bottom borders...
83: count1 = 3 + (widthTimesFour*(n-1)); // Top edge
84: count2 = 3 + (widthTimesFour*(height-n)); // Bottom edge
85: nextValueOffset = 4;
86: for (x = 0; x < width; x++)
87: {
88: pixels[count1] = pixels[count2] = alpha;
89: count1 += nextValueOffset;
90: count2 += nextValueOffset;
91: }
92:
93: // Set per pixel alpha values along the left+right borders...
94: count1 = 3 + ((n-1)*4); // Left edge
95: count2 = widthTimesFour - ((n-1)*4) - 1; // Right edge
96: nextValueOffset = widthTimesFour;
97: for (y = 0; y < height; y++)
98: {
99: pixels[count1] = pixels[count2] = alpha;
100: count1 += nextValueOffset;
101: count2 += nextValueOffset;
102: }
103: }
104:
105: // Copy the pixel data including alpha values back to the destination...
106: BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
107:
108: DestroyBuffer();
109: }
110:
111: //===========================================================================
112: // Function: AlphaCorner
113: // Purpose: ...
114: //===========================================================================
115:
116: BYTE cornerAlphaArrayHiDPI2x[64] =
117: {
118: 0x00, 0x00, 0x00, 0x10, 0x40, 0x80, 0xc0, 0xe0,
119: 0x00, 0x00, 0x40, 0xa0, 0xff, 0xff, 0xff, 0xff,
120: 0x00, 0x40, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff,
121: 0x10, 0xa0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122: 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
123: 0x80, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
124: 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
125: 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
126: };
127:
128: BYTE cornerAlphaArrayLoDPI[25] =
129: {
130: 0x00, 0x10, 0x40, 0x90, 0xc0,
131: 0x10, 0x60, 0xa0, 0xff, 0xff,
132: 0x40, 0xa0, 0xff, 0xff, 0xff,
133: 0x90, 0xff, 0xff, 0xff, 0xff,
134: 0xc0, 0xff, 0xff, 0xff, 0xff,
135: };
136:
137: void BImage::AlphaCorner(HDC hdc, RECT rect, int corner, int borderWidth, unsigned char outerAlpha, unsigned char innerAlpha)
138: {
139: // Copy pixel data from the destination...
140: CreateBuffer(hdc, rect, false);
141: BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
142:
143: BYTE* alphaPtr;
144: unsigned int arraySizeXY;
145: unsigned int x, y, offset;
146: unsigned int bytesPerRow = (width*4);
147: unsigned int topleft, topright, bottomleft, bottomright;
148: unsigned int topcount, bottomcount;
149:
150: bool reversed;
151: if (outerAlpha > innerAlpha) reversed = true;
152: else reversed = false;
153:
154: //====================
155:
156: switch (pSettings->scalingFactorHiDPI)
157: {
158: case 2:
159: case 3: // Placeholder pending addition of HiDPI 3x corner alpha array in AlphaCorner() and related PrepareCorner() support
160: case 4: // Placeholder pending addition of HiDPI 4x corner alpha array in AlphaCorner() and related PrepareCorner() support
161: {
162: alphaPtr = cornerAlphaArrayHiDPI2x;
163: arraySizeXY = 8;
164: break;
165: }
166:
167: case 1:
168: default:
169: {
170: alphaPtr = cornerAlphaArrayLoDPI;
171: arraySizeXY = 5;
172: break;
173: }
174: }
175:
176: //====================
177:
178: BYTE pixelAlpha;
179:
180: // Set per pixel alpha values for all four corners of the target rect...
181: for (y = 0; y < arraySizeXY; y++)
182: {
183: // NOTE: We're using a bottom-up DIB
184: // -> origin is the lower-left corner!
185: bottomcount = y * bytesPerRow;
186: topcount = (height-y-1) * bytesPerRow;
187:
188: for (x = 0; x < arraySizeXY; x++)
189: {
190: pixelAlpha = *alphaPtr;
191:
192: if (pixelAlpha == 0xff)
193: {
194: alphaPtr++;
195: continue;
196: }
197:
198: if (reversed)
199: {
200: pixelAlpha = 255 - pixelAlpha;
201: if (pixelAlpha <= innerAlpha) pixelAlpha = innerAlpha;
202: if (pixelAlpha >= outerAlpha) pixelAlpha = outerAlpha;
203: }
204: else
205: {
206: if (pixelAlpha <= outerAlpha) pixelAlpha = outerAlpha;
207: if (pixelAlpha >= innerAlpha) pixelAlpha = innerAlpha;
208: }
209:
210: offset = x * 4;
211:
212: if (corner & CORNER_BOTTOMLEFT)
213: {
214: bottomleft = bottomcount+offset+3;
215: pixels[bottomleft] = pixelAlpha;
216: }
217: if (corner & CORNER_BOTTOMRIGHT)
218: {
219: bottomright = bottomcount+bytesPerRow-offset-1;
220: pixels[bottomright] = pixelAlpha;
221: }
222: if (corner & CORNER_TOPLEFT)
223: {
224: topleft = topcount+offset+3;
225: pixels[topleft] = pixelAlpha;
226: }
227: if (corner & CORNER_TOPRIGHT)
228: {
229: topright = topcount+bytesPerRow-offset-1;
230: pixels[topright] = pixelAlpha;
231: }
232:
233: alphaPtr++;
234: }
235: }
236:
237: // Copy the pixel data including alpha values back to the destination...
238: BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
239:
240: DestroyBuffer();
241: }
242:
243: //===========================================================================
244: // Function: AlphaFromRGB
245: // Purpose: ...
246: //===========================================================================
247:
248: void BImage::AlphaFromRGB(HDC hdc, RECT rect, unsigned char minAlpha, unsigned char maxAlpha, bool recolor, COLORREF color)
249: {
250: CreateBuffer(hdc, rect, false);
251:
252: // Copy pixel data from the destination...
253: BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
254:
255: BYTE red, green, blue;
256: if (recolor)
257: {
258: red = GetRValue(color);
259: green = GetGValue(color);
260: blue = GetBValue(color);
261: }
262:
263: unsigned int alphaRange = maxAlpha - minAlpha;
264: unsigned int averageRGB, newAlpha;
265:
266: unsigned int x, y, count = 0;
267: for (y = 0; y < height; y++)
268: {
269: for (x = 0; x < width; x++)
270: {
271: // Set the per pixel alpha values as an average of each pixel's RGB values, mapped to the allowed min<->max alpha range...
272: // (e.g. assuming the full alpha range 0-255 is allowed, 0xffffff pixels become fully opaque <-> 0x000000 pixels become fully transparent)
273: averageRGB = ((pixels[count+0] + pixels[count+1] + pixels[count+2]) / 3);
274: newAlpha = minAlpha + ((averageRGB * alphaRange) / 255);
275: pixels[count+3] = (BYTE)newAlpha;
276:
277: // ...and optionally recolor the pixels themselves to the specified color...
278: // (nb. this is typically also used to avoid e.g. text anti-aliasing artifacts on otherwise
279: // transparent backgrounds by making the pixels all the same colour but with different alpha values)
280: if (recolor)
281: {
282: // Use case examples:
283: // Set the new pixel colour without alpha applied to fully white 0xffffff -> "Regular/Light mode"
284: // Set the new pixel colour without alpha applied to fully black 0x000000 -> "Dark mode"
285: // Set the new pixel colour without alpha applied to any colour 0xBBGGRR -> "Recolor mode"
286: pixels[count] = blue;
287: pixels[count+1] = green;
288: pixels[count+2] = red;
289: }
290:
291: count += 4;
292: }
293: }
294:
295: // Copy the pixel data including alpha values back to the destination...
296: BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
297:
298: DestroyBuffer();
299: }
300:
301: //===========================================================================
302: // Function: AlphaMask
303: // Purpose: ...
304: //===========================================================================
305:
306: // ########## NOTE: WORK STILL IN PROGRESS! ##########
307:
308: void BImage::AlphaMask(HDC destHdc, RECT destRect, HDC srcHdc, RECT srcRect, bool useSrcRGBAsAlpha)
309: {
310: // Safeguard: Make sure that the source and destination RECTs are of the same *size*...
311: // (the actual position of each RECT inside its parent HDC is irrelevant here)
312: int srcSize = (srcRect.right - srcRect.left) * (srcRect.bottom - srcRect.top);
313: int destSize = (destRect.right - destRect.left) * (destRect.bottom - destRect.top);
314: if (srcSize != destSize) return;
315:
316: //====================
317:
318: // Copy the requested input values from the source HDC into a buffer...
319: CreateBuffer(srcHdc, srcRect, false);
320: BitBlt(buf, 0, 0, width, height, srcHdc, srcRect.left, srcRect.top, SRCCOPY);
321:
322: BYTE* alphaBuffer = (BYTE*)malloc(width*height);
323: if (alphaBuffer == NULL)
324: {
325: DestroyBuffer();
326: return;
327: }
328:
329: unsigned int x, y, count;
330:
331: // Should we use the source per pixel colors as the destination per pixel alpha values...
332: // (nb. greyscale source format assumed so we can use any of R/G/B; here using the B value)
333: if (useSrcRGBAsAlpha) count = 0; // Per pixel data offset 0 bytes -> B value
334: // ...or copy the per pixel alpha values straight over from the source to the destination?
335: else count = 3; // Per pixel data offset 3 bytes -> Alpha value
336:
337: BYTE* alphaPtr = alphaBuffer;
338: for (y = 0; y < height; y++)
339: {
340: for (x = 0; x < width; x++)
341: {
342: *alphaPtr = pixels[count];
343: alphaPtr++;
344: count += 4;
345: }
346: }
347:
348: BYTE* alphaBufferEnd = alphaPtr;
349:
350: DestroyBuffer();
351:
352: // int alphaBufferSize = alphaBufferEnd - alphaBuffer;
353: // char msg[255];
354: // sprintf_s(msg, sizeofArray(msg), "Number of alpha bytes copied: %d", alphaBufferSize);
355: // SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
356:
357: //====================
358:
359: // Copy the alpha values from the buffer to the destination HDC...
360: CreateBuffer(destHdc, destRect, false);
361: BitBlt(buf, 0, 0, width, height, destHdc, destRect.left, destRect.top, SRCCOPY);
362:
363: alphaPtr = alphaBuffer;
364: count = 3; // Per pixel data offset 3 bytes -> Alpha value
365: for (y = 0; y < height; y++)
366: {
367: for (x = 0; x < width; x++)
368: {
369: pixels[count] = (BYTE)*alphaPtr;
370: count += 4;
371: alphaPtr++;
372: if (alphaPtr == alphaBufferEnd) break; // Safeguard
373: }
374: }
375:
376: BitBlt(destHdc, destRect.left, destRect.top, width, height, buf, 0, 0, SRCCOPY);
377: DestroyBuffer();
378:
379: //====================
380:
381: free(alphaBuffer);
382: alphaBuffer = NULL;
383: }
384:
385: //===========================================================================
386: // Function: AlphaApply
387: // Purpose: Pre-applies the per pixel alpha to the RGB values of each pixel
388: // (required by related Windows API functions before processing)
389: //===========================================================================
390:
391: void BImage::AlphaApply(HDC hdc, RECT rect)
392: {
393: CreateBuffer(hdc, rect, false);
394:
395: // Copy pixel data from the destination...
396: BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
397:
398: // Apply per pixel alpha to the RGB values...
399: unsigned int x, y, count = 0, tempPixel;
400: BYTE alpha;
401: for (y = 0; y < height; y++)
402: {
403: for (x = 0; x < width; x++)
404: {
405: alpha = pixels[count + 3];
406:
407: if (alpha < 255)
408: {
409: tempPixel = (pixels[count+2] * alpha) / 255;
410: pixels[count+2] = (BYTE)tempPixel;
411: tempPixel = (pixels[count+1] * alpha) / 255;
412: pixels[count+1] = (BYTE)tempPixel;
413: tempPixel = (pixels[count] * alpha) / 255;
414: pixels[count] = (BYTE)tempPixel;
415: }
416:
417: count += 4;
418: }
419: }
420:
421: // Copy the pixel data with newly applied alpha back to the destination...
422: BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
423:
424: DestroyBuffer();
425: }
426:
427: //===========================================================================
428: // Function: PrepareCorner
429: // Purpose: Round off corner pixel data prior to call to AlphaCorner
430: //===========================================================================
431:
432: void BImage::PrepareCorner(HDC hdc, RECT rect, int corner, int bevelStyle, int bevelPosition, int bevelWidth, int borderWidth)
433: {
434: switch (pSettings->scalingFactorHiDPI)
435: {
436: case 2:
437: case 3: // Placeholder pending addition of HiDPI 3x corner alpha array in AlphaCorner() and related PrepareCorner() support
438: case 4: // Placeholder pending addition of HiDPI 4x corner alpha array in AlphaCorner() and related PrepareCorner() support
439: {
440: if (bevelStyle != BEVEL_FLAT)
441: {
442: if (bevelPosition == BEVEL1)
443: {
444: int offsetX, offsetY;
445:
446: if (corner & CORNER_TOPLEFT)
447: {
448: // Round off the top left bevel...
449: offsetX = rect.left + borderWidth;
450: offsetY = rect.top + borderWidth;
451: SetPixel(hdc, offsetX+3, offsetY+1, GetPixel(hdc, offsetX+3, offsetY));
452: SetPixel(hdc, offsetX+2, offsetY+1, GetPixel(hdc, offsetX+2, offsetY));
453: SetPixel(hdc, offsetX+1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
454: SetPixel(hdc, offsetX+1, offsetY+3, GetPixel(hdc, offsetX, offsetY+3));
455: }
456:
457: if (corner & CORNER_BOTTOMLEFT)
458: {
459: // Round off the bottom left bevel...
460: offsetX = rect.left + borderWidth;
461: offsetY = rect.bottom - borderWidth - 1;
462: SetPixel(hdc, offsetX+1, offsetY-3, GetPixel(hdc, offsetX, offsetY-3));
463: SetPixel(hdc, offsetX+1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
464: SetPixel(hdc, offsetX+2, offsetY-1, GetPixel(hdc, offsetX+2, offsetY));
465: SetPixel(hdc, offsetX+3, offsetY-1, GetPixel(hdc, offsetX+3, offsetY));
466: }
467:
468: if (corner & CORNER_TOPRIGHT)
469: {
470: // Round off the top right bevel...
471: offsetX = rect.right - borderWidth - 1;
472: offsetY = rect.top + borderWidth;
473: SetPixel(hdc, offsetX-3, offsetY+1, GetPixel(hdc, offsetX-3, offsetY));
474: SetPixel(hdc, offsetX-2, offsetY+1, GetPixel(hdc, offsetX-2, offsetY));
475: SetPixel(hdc, offsetX-1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
476: SetPixel(hdc, offsetX-1, offsetY+3, GetPixel(hdc, offsetX, offsetY+3));
477: }
478:
479: if (corner & CORNER_BOTTOMRIGHT)
480: {
481: // Round off the bottom right bevel...
482: offsetX = rect.right - borderWidth - 1;
483: offsetY = rect.bottom - borderWidth - 1;
484: SetPixel(hdc, offsetX-1, offsetY-3, GetPixel(hdc, offsetX, offsetY-3));
485: SetPixel(hdc, offsetX-1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
486: SetPixel(hdc, offsetX-2, offsetY-1, GetPixel(hdc, offsetX-2, offsetY));
487: SetPixel(hdc, offsetX-3, offsetY-1, GetPixel(hdc, offsetX-3, offsetY));
488: }
489: }
490: else if (bevelPosition == BEVEL2)
491: {
492: // No change necessary... [?] (as far as I can tell right now at least)
493: }
494: }
495:
496: if (borderWidth > 0)
497: {
498: int offsetX, offsetY;
499:
500: if (corner & CORNER_TOPLEFT)
501: {
502: // Round off the top left corner...
503: offsetX = rect.left + borderWidth;
504: offsetY = rect.top + borderWidth;
505: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY)));
506: SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY-1));
507: SetPixel(hdc, offsetX+2, offsetY, GetPixel(hdc, offsetX+2, offsetY-1));
508: SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX-1, offsetY+1));
509: SetPixel(hdc, offsetX, offsetY+2, GetPixel(hdc, offsetX-1, offsetY+2));
510: SetPixel(hdc, offsetX+1, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY+1), GetPixel(hdc, offsetX, offsetY)));
511: SetPixel(hdc, offsetX+3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+3, offsetY), GetPixel(hdc, offsetX+2, offsetY)));
512: SetPixel(hdc, offsetX, offsetY+3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+3), GetPixel(hdc, offsetX, offsetY+2)));
513: }
514:
515: if (corner & CORNER_BOTTOMLEFT)
516: {
517: // Round off the bottom left corner...
518: offsetX = rect.left + borderWidth;
519: offsetY = rect.bottom - borderWidth - 1;
520: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY)));
521: SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY+1));
522: SetPixel(hdc, offsetX+2, offsetY, GetPixel(hdc, offsetX+2, offsetY+1));
523: SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX-1, offsetY-1));
524: SetPixel(hdc, offsetX, offsetY-2, GetPixel(hdc, offsetX-1, offsetY-2));
525: SetPixel(hdc, offsetX+1, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY-1), GetPixel(hdc, offsetX, offsetY)));
526: SetPixel(hdc, offsetX+3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+3, offsetY), GetPixel(hdc, offsetX+2, offsetY)));
527: SetPixel(hdc, offsetX, offsetY-3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-3), GetPixel(hdc, offsetX, offsetY-2)));
528: }
529:
530: if (corner & CORNER_TOPRIGHT)
531: {
532: // Round off the top right corner...
533: offsetX = rect.right - borderWidth - 1;
534: offsetY = rect.top + borderWidth;
535: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY)));
536: SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY-1));
537: SetPixel(hdc, offsetX-2, offsetY, GetPixel(hdc, offsetX-2, offsetY-1));
538: SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX+1, offsetY+1));
539: SetPixel(hdc, offsetX, offsetY+2, GetPixel(hdc, offsetX+1, offsetY+2));
540: SetPixel(hdc, offsetX-1, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY+1), GetPixel(hdc, offsetX, offsetY)));
541: SetPixel(hdc, offsetX-3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-3, offsetY), GetPixel(hdc, offsetX-2, offsetY)));
542: SetPixel(hdc, offsetX, offsetY+3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+3), GetPixel(hdc, offsetX, offsetY+2)));
543: }
544:
545: if (corner & CORNER_BOTTOMRIGHT)
546: {
547: // Round off the bottom right corner...
548: offsetX = rect.right - borderWidth - 1;
549: offsetY = rect.bottom - borderWidth - 1;
550: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY)));
551: SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY+1));
552: SetPixel(hdc, offsetX-2, offsetY, GetPixel(hdc, offsetX-2, offsetY+1));
553: SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX+1, offsetY-1));
554: SetPixel(hdc, offsetX, offsetY-2, GetPixel(hdc, offsetX+1, offsetY-2));
555: SetPixel(hdc, offsetX-1, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY-1), GetPixel(hdc, offsetX, offsetY)));
556: SetPixel(hdc, offsetX-3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-3, offsetY), GetPixel(hdc, offsetX-2, offsetY)));
557: SetPixel(hdc, offsetX, offsetY-3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-3), GetPixel(hdc, offsetX, offsetY-2)));
558: }
559: }
560:
561: break;
562: }
563:
564: //====================
565:
566: case 1:
567: default:
568: {
569: if (bevelStyle != BEVEL_FLAT)
570: {
571: if (bevelPosition == BEVEL1)
572: {
573: int offsetX, offsetY;
574:
575: if (corner & CORNER_TOPLEFT)
576: {
577: // Round off the top left bevel...
578: offsetX = rect.left + borderWidth;
579: offsetY = rect.top + borderWidth;
580: SetPixel(hdc, offsetX+1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
581: }
582:
583: if (corner & CORNER_BOTTOMLEFT)
584: {
585: // Round off the bottom left bevel...
586: offsetX = rect.left + borderWidth;
587: offsetY = rect.bottom - borderWidth - 1;
588: SetPixel(hdc, offsetX+1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
589: }
590:
591: if (corner & CORNER_TOPRIGHT)
592: {
593: // Round off the top right bevel...
594: offsetX = rect.right - borderWidth - 1;
595: offsetY = rect.top + borderWidth;
596: SetPixel(hdc, offsetX-1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
597: }
598:
599: if (corner & CORNER_BOTTOMRIGHT)
600: {
601: // Round off the bottom right bevel...
602: offsetX = rect.right - borderWidth - 1;
603: offsetY = rect.bottom - borderWidth - 1;
604: SetPixel(hdc, offsetX-1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
605: }
606: }
607: else if (bevelPosition == BEVEL2)
608: {
609: // No change necessary... [?] (as far as I can tell right now at least)
610: }
611: }
612:
613: if (borderWidth > 0)
614: {
615: int offsetX, offsetY;
616:
617: if (corner & CORNER_TOPLEFT)
618: {
619: // Round off the top left corner...
620: offsetX = rect.left;
621: offsetY = rect.top;
622: SetPixel(hdc, offsetX+1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
623: SetPixel(hdc, offsetX+2, offsetY+1, GetPixel(hdc, offsetX+2, offsetY));
624: SetPixel(hdc, offsetX+1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
625: offsetX += borderWidth;
626: offsetY += borderWidth;
627: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY)));
628: SetPixel(hdc, offsetX+1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX+1, offsetY-1)));
629: SetPixel(hdc, offsetX, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY+1)));
630: // SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX, offsetY-1)));
631: // SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY-1));
632: // SetPixel(hdc, offsetX+2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+2, offsetY), GetPixel(hdc, offsetX+2, offsetY-1)));
633: // SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX-1, offsetY+1));
634: // SetPixel(hdc, offsetX, offsetY+2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+2), GetPixel(hdc, offsetX-1, offsetY+2)));
635: }
636:
637: if (corner & CORNER_BOTTOMLEFT)
638: {
639: // Round off the bottom left corner...
640: offsetX = rect.left;
641: offsetY = rect.bottom - 1;
642: SetPixel(hdc, offsetX+1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
643: SetPixel(hdc, offsetX+2, offsetY-1, GetPixel(hdc, offsetX+2, offsetY));
644: SetPixel(hdc, offsetX+1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
645: offsetX += borderWidth;
646: offsetY -= borderWidth;
647: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY)));
648: SetPixel(hdc, offsetX+1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX+1, offsetY+1)));
649: SetPixel(hdc, offsetX, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY-1)));
650: // SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX, offsetY+1)));
651: // SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY+1));
652: // SetPixel(hdc, offsetX+2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+2, offsetY), GetPixel(hdc, offsetX+2, offsetY+1)));
653: // SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX-1, offsetY-1));
654: // SetPixel(hdc, offsetX, offsetY-2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-2), GetPixel(hdc, offsetX-1, offsetY-2)));
655: }
656:
657: if (corner & CORNER_TOPRIGHT)
658: {
659: // Round off the top right corner...
660: offsetX = rect.right - 1;
661: offsetY = rect.top;
662: SetPixel(hdc, offsetX-1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
663: SetPixel(hdc, offsetX-2, offsetY+1, GetPixel(hdc, offsetX-2, offsetY));
664: SetPixel(hdc, offsetX-1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
665: offsetX -= borderWidth;
666: offsetY += borderWidth;
667: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY)));
668: SetPixel(hdc, offsetX-1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX-1, offsetY-1)));
669: SetPixel(hdc, offsetX, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY+1)));
670: // SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX, offsetY-1)));
671: // SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY-1));
672: // SetPixel(hdc, offsetX-2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-2, offsetY), GetPixel(hdc, offsetX-2, offsetY-1)));
673: // SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX+1, offsetY+1));
674: // SetPixel(hdc, offsetX, offsetY+2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+2), GetPixel(hdc, offsetX+1, offsetY+2)));
675: }
676:
677: if (corner & CORNER_BOTTOMRIGHT)
678: {
679: // Round off the bottom right corner...
680: offsetX = rect.right - 1;
681: offsetY = rect.bottom - 1;
682: SetPixel(hdc, offsetX-1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
683: SetPixel(hdc, offsetX-2, offsetY-1, GetPixel(hdc, offsetX-2, offsetY));
684: SetPixel(hdc, offsetX-1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
685: offsetX -= borderWidth;
686: offsetY -= borderWidth;
687: SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY)));
688: SetPixel(hdc, offsetX-1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX-1, offsetY+1)));
689: SetPixel(hdc, offsetX, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY-1)));
690: // SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX, offsetY+1)));
691: // SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY+1));
692: // SetPixel(hdc, offsetX-2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-2, offsetY), GetPixel(hdc, offsetX-2, offsetY+1)));
693: // SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX+1, offsetY-1));
694: // SetPixel(hdc, offsetX, offsetY-2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-2), GetPixel(hdc, offsetX+1, offsetY-2)));
695: }
696: }
697: break;
698: }
699: }
700: }
701:
702: //===========================================================================
703: