xoblite™ / Blackbox for Windows bb5 | RC6 preview | 0.25.2.14
http://xoblite.net/
BImage Class Reference

#include <BImage.h>

Public Member Functions

 BImage ()
 
 ~BImage ()
 
void DrawBorder (HDC hdc, RECT rect, COLORREF borderColour, int borderWidth)
 
void DrawGradient (HDC hdc, RECT rect, int type, COLORREF color1, COLORREF color2, COLORREF color3, COLORREF color4, COLORREF color5, COLORREF color6, COLORREF color7, COLORREF color8, bool bInterlaced, int bevelStyle, int bevelPosition, int bevelWidth)
 
void DrawGlyph (HDC hdc, RECT r, int glyph, COLORREF glyphColor)
 
void AlphaRect (HDC hdc, RECT rect, unsigned char alpha)
 
void AlphaBorder (HDC hdc, RECT rect, unsigned char alpha, int borderWidth)
 
void AlphaCorner (HDC hdc, RECT rect, int corner, int borderWidth, unsigned char minAlpha, unsigned char maxAlpha)
 
void AlphaFromRGB (HDC hdc, RECT rect, unsigned char minAlpha, unsigned char maxAlpha, bool recolor, COLORREF color)
 
void AlphaMask (HDC destHdc, RECT destRect, HDC srcHdc, RECT srcRect, bool useSrcRGBAsAlpha)
 
void AlphaApply (HDC hdc, RECT rect)
 
void PrepareCorner (HDC hdc, RECT rect, int corner, int bevelStyle, int bevelPosition, int bevelWidth, int borderWidth)
 

Private Member Functions

void CreateBuffer (HDC hdc, RECT rect, bool createTables)
 
void DestroyBuffer ()
 
bool CheckRemainder (int divider, int remainder, int i)
 
void PaintGradient (int type, COLORREF colorFrom, COLORREF colorTo, int bevelStyle)
 
void ApplyBevel (int bevelStyle, int bevelPosition, int bevelWidth)
 
void bevel1 (bool sunken)
 
void bevel2 (bool sunken)
 
void lightenpixel (unsigned int count)
 
void darkenpixel (unsigned int count)
 
void ApplyInterlace (bool bInterlaced)
 
void dgradient (void)
 
void hgradient (void)
 
void vgradient (void)
 
void pgradient (void)
 
void rgradient (void)
 
void egradient (void)
 
void pcgradient (void)
 
void cdgradient (void)
 

Private Attributes

unsigned int width
 
unsigned int height
 
unsigned int xoffset
 
unsigned int yoffset
 
unsigned int padding
 
HDC buf
 
HBITMAP bufbmp
 
HBITMAP oldbuf
 
HBRUSH solid_brush
 
RECT fillRect
 
PBYTE pixels
 
BYTE from_red
 
BYTE from_green
 
BYTE from_blue
 
BYTE to_red
 
BYTE to_green
 
BYTE to_blue
 
unsigned char * red
 
unsigned char * green
 
unsigned char * blue
 
unsigned int * xtable
 
unsigned int * ytable
 
bool sunken
 
BYTE r
 
BYTE g
 
BYTE b
 
BYTE rr
 
BYTE gg
 
BYTE bb
 
int sr
 
int sg
 
int sb
 

Constructor & Destructor Documentation

◆ BImage()

BImage::BImage ( )
45{
46}

◆ ~BImage()

BImage::~BImage ( )
49{
50 if (sqrt_table) delete sqrt_table;
51}
unsigned long * sqrt_table
Definition BImage.cpp:40

Member Function Documentation

◆ DrawBorder()

void BImage::DrawBorder ( HDC hdc,
RECT rect,
COLORREF borderColour,
int borderWidth )
456{
457 RECT borderRect;
458 CopyRect(&borderRect, &rect);
459
460 HBRUSH borderBrush = CreateSolidBrush(borderColour);
461
462 for (int i = 0; i < borderWidth; i++)
463 {
464 FrameRect(hdc, &borderRect, borderBrush); // Draw border...
465 InflateRect(&borderRect, -1, -1); // Shrink rectangle by 1 pixel...
466 }
467
468 DeleteObject(borderBrush);
469}

◆ DrawGradient()

void BImage::DrawGradient ( HDC hdc,
RECT rect,
int type,
COLORREF color1,
COLORREF color2,
COLORREF color3,
COLORREF color4,
COLORREF color5,
COLORREF color6,
COLORREF color7,
COLORREF color8,
bool bInterlaced,
int bevelStyle,
int bevelPosition,
int bevelWidth )
58{
59 CreateBuffer(hdc, rect, true);
60
61 //====================
62
63 switch (type)
64 {
65 case B_SPLITVERTICAL:
67 {
68 // NOTE: We're using a bottom-up DIB
69 // -> origin is the lower-left corner!
70
71 int upperHeight = height/2;
72 int lowerHeight = height - upperHeight;
73 xoffset = padding = 0;
74
75 // Draw the lower half of the gradient...
76 yoffset = 0;
77 height = lowerHeight;
78 if (type == B_SPLITVERTICAL) PaintGradient(B_VERTICAL, color3, color4, bevelStyle);
79 else PaintGradient(B_VERTICAL, color2, color1, bevelStyle);
80
81 // Draw the upper half of the gradient...
82 yoffset = lowerHeight;
83 height = upperHeight;
84 if (type == B_MIRRORVERTICAL)
85 {
86 // Overlap the gradients to get a single mirror center pixel...
87 yoffset--;
88 height++;
89 }
90 if (type == B_SPLITVERTICAL) PaintGradient(B_VERTICAL, color1, color2, bevelStyle);
91 else PaintGradient(B_VERTICAL, color1, color2, bevelStyle);
92
93 // ############################################
94 // PERSONAL NOTE:
95 // Maybe I should change the gradient engine
96 // to use e.g. xstart, xstop, ystart, ystop ???
97 // ############################################
98
99 // Do not forget to reset the height parameter or the functions
100 // below will only draw on a portion of the combined gradient...! =]
101 height = upperHeight + lowerHeight;
102 }
103 break;
104
105 //====================
106
109 {
110 // NOTE: We're using a bottom-up DIB
111 // -> origin is the lower-left corner!
112
113 int leftWidth = width/2;
114 int rightWidth = width - leftWidth;
115 yoffset = 0;
116
117 // Draw the left half of the gradient...
118 xoffset = 0;
119 width = leftWidth;
120 padding = rightWidth;
121 if (type == B_SPLITHORIZONTAL) PaintGradient(B_HORIZONTAL, color1, color2, bevelStyle);
122 else PaintGradient(B_HORIZONTAL, color1, color2, bevelStyle);
123
124 // Draw the right half of the gradient...
125 xoffset = padding = leftWidth;
126 width = rightWidth;
127 if (type == B_MIRRORHORIZONTAL)
128 {
129 // Overlap the gradients to get a single mirror center pixel...
130 xoffset--;
131 padding--;
132 width++;
133 }
134 if (type == B_SPLITHORIZONTAL) PaintGradient(B_HORIZONTAL, color3, color4, bevelStyle);
135 else PaintGradient(B_HORIZONTAL, color2, color1, bevelStyle);
136
137 // ############################################
138 // PERSONAL NOTE:
139 // Maybe I should change the gradient engine
140 // to use e.g. xstart, xstop, ystart, ystop ???
141 // ############################################
142
143 // Do not forget to reset the width parameter or the functions
144 // below will only draw on a portion of the combined gradient...! =]
145 width = leftWidth + rightWidth;
146 }
147 break;
148
149 //====================
150
152 {
153 int originalWidth = width;
154
155 if (width >= 14) // Is the available width OK? (nb. we always need 2 pixels per segment at a minimum!)
156 {
157 // -> The width *is* sufficient to accomodate a full 8-colour gradient, so we will
158 // render using all 8 colours (1-2-3-4-5-6-7-8), i.e. through 7 interconnected gradients...
159 int increment = width / 7;
160 int remainder = width % 7;
161 xoffset = 0, yoffset = 0;
162
163 for (int i=1; i<=7; i++)
164 {
165// width = increment;
166 if (i<7) width = increment+1; // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see below)
167 else width = increment;
168 if (CheckRemainder(7, remainder, i)) width++;
169 padding = originalWidth - width;
170
171 switch (i)
172 {
173 case 1: { PaintGradient(B_HORIZONTAL, color1, color2, BEVEL_FLAT); break; }
174 case 2: { PaintGradient(B_HORIZONTAL, color2, color3, BEVEL_FLAT); break; }
175 case 3: { PaintGradient(B_HORIZONTAL, color3, color4, BEVEL_FLAT); break; }
176 case 4: { PaintGradient(B_HORIZONTAL, color4, color5, BEVEL_FLAT); break; }
177 case 5: { PaintGradient(B_HORIZONTAL, color5, color6, BEVEL_FLAT); break; }
178 case 6: { PaintGradient(B_HORIZONTAL, color6, color7, BEVEL_FLAT); break; }
179 default: { PaintGradient(B_HORIZONTAL, color7, color8, BEVEL_FLAT); break; }
180 }
181
182// xoffset += width;
183 xoffset += (width-1); // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see above)
184 }
185 }
186 else
187 {
188 // -> The width is *not* sufficient to accomodate a full 8-colour gradient, so we will
189 // limit the render to use only 4 colours (1-3-6-8), i.e. through 3 interconnected gradients...
190 int increment = width / 3;
191 int remainder = width % 3;
192 xoffset = 0, yoffset = 0;
193
194 for (int i=1; i<=3; i++)
195 {
196// width = increment;
197 if (i<3) width = increment+1; // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see below)
198 else width = increment;
199 if (CheckRemainder(3, remainder, i)) width++;
200 padding = originalWidth - width;
201
202 switch (i)
203 {
204 case 1: { PaintGradient(B_HORIZONTAL, color1, color3, BEVEL_FLAT); break; }
205 case 2: { PaintGradient(B_HORIZONTAL, color3, color6, BEVEL_FLAT); break; }
206 default: { PaintGradient(B_HORIZONTAL, color6, color8, BEVEL_FLAT); break; }
207 }
208
209// xoffset += width;
210 xoffset += (width-1); // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see above)
211 }
212 }
213
214 // Finally, do not forget to reset the width parameter or the functions
215 // below will only draw on a portion of the combined gradient... ;)
216 width = originalWidth;
217 }
218 break;
219
220 //====================
221
222 case B_SUPERVERTICAL:
223 {
224 // NOTE: We're using a *bottom-up* DIB!!!
225 // -> Rendering origin is the *lower-left* corner,
226 // so we need to swap segment order and colours accordingly! (see below)
227
228 int originalHeight = height;
229
230 if (height >= 14) // Is the available height OK? (nb. we always need 2 pixels per segment at a minimum!)
231 {
232 // -> The height *is* sufficient to accomodate a full 8-colour gradient, so we will
233 // render using all 8 colours (1-2-3-4-5-6-7-8), i.e. through 7 interconnected gradients...
234 int increment = height / 7;
235 int remainder = height % 7;
236 xoffset = 0, yoffset = 0;
237
238 for (int i=1; i<=7; i++)
239 {
240// height = increment;
241 if (i<7) height = increment+1; // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see below)
242 else height = increment;
243 if (CheckRemainder(7, remainder, i)) height++;
244 padding = originalHeight - height;
245
246 switch (i)
247 {
248 case 1: { PaintGradient(B_VERTICAL, color7, color8, BEVEL_FLAT); break; }
249 case 2: { PaintGradient(B_VERTICAL, color6, color7, BEVEL_FLAT); break; }
250 case 3: { PaintGradient(B_VERTICAL, color5, color6, BEVEL_FLAT); break; }
251 case 4: { PaintGradient(B_VERTICAL, color4, color5, BEVEL_FLAT); break; }
252 case 5: { PaintGradient(B_VERTICAL, color3, color4, BEVEL_FLAT); break; }
253 case 6: { PaintGradient(B_VERTICAL, color2, color3, BEVEL_FLAT); break; }
254 default: { PaintGradient(B_VERTICAL, color1, color2, BEVEL_FLAT); break; }
255 }
256
257// yoffset += height;
258 yoffset += (height-1); // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see above)
259 }
260 }
261 else
262 {
263 // -> The height is *not* sufficient to accomodate a full 8-colour gradient, so we will
264 // limit the render to use only 4 colours (1-3-6-8), i.e. through 3 interconnected gradients...
265 int increment = height / 3;
266 int remainder = height % 3;
267 xoffset = 0, yoffset = 0;
268
269 for (int i=1; i<=3; i++)
270 {
271// height = increment;
272 if (i<3) height = increment+1; // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see below)
273 else height = increment;
274 if (CheckRemainder(3, remainder, i)) height++;
275 padding = originalHeight - height;
276
277 switch (i)
278 {
279 case 1: { PaintGradient(B_VERTICAL, color6, color8, BEVEL_FLAT); break; }
280 case 2: { PaintGradient(B_VERTICAL, color3, color6, BEVEL_FLAT); break; }
281 default: { PaintGradient(B_VERTICAL, color1, color3, BEVEL_FLAT); break; }
282 }
283
284// yoffset += height;
285 yoffset += (height-1); // -> Overlap the outer edges of adjacent gradients to avoid double lines of the same colour (see above)
286 }
287 }
288
289 // Finally, do not forget to reset the height parameter or the functions
290 // below will only draw on a portion of the combined gradient... ;)
291 height = originalHeight;
292 }
293 break;
294
295 //====================
296
297 default: // Regular gradients or SplitSolid (which does not use the gradient engine),
298 // or failsafe (e.g. if the appearance type specifies an image to be used instead of a *box gradient)
299 {
300 xoffset = yoffset = padding = 0;
301 PaintGradient(type, color1, color2, bevelStyle);
302 }
303 }
304
305 //====================
306
307 ApplyInterlace(bInterlaced);
308 ApplyBevel(bevelStyle, bevelPosition, bevelWidth);
309 BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
311}
#define B_VERTICAL
Definition BBApi.h:73
#define B_MIRRORHORIZONTAL
Definition BBApi.h:95
#define B_MIRRORVERTICAL
Definition BBApi.h:96
#define B_HORIZONTAL
Definition BBApi.h:72
#define BEVEL_FLAT
Definition BBApi.h:105
#define B_SPLITHORIZONTAL
Definition BBApi.h:86
#define B_SUPERVERTICAL
Definition BBApi.h:92
#define B_SPLITVERTICAL
Definition BBApi.h:87
#define B_SUPERHORIZONTAL
Definition BBApi.h:91
void ApplyBevel(int bevelStyle, int bevelPosition, int bevelWidth)
Definition BImage.cpp:528
void ApplyInterlace(bool bInterlaced)
Definition BImage.cpp:683
void PaintGradient(int type, COLORREF colorFrom, COLORREF colorTo, int bevelStyle)
Definition BImage.cpp:345
void CreateBuffer(HDC hdc, RECT rect, bool createTables)
Definition BImage.cpp:473
bool CheckRemainder(int divider, int remainder, int i)
Definition BImage.cpp:315
unsigned int width
Definition BImage.h:88
unsigned int xoffset
Definition BImage.h:90
HDC buf
Definition BImage.h:94
unsigned int height
Definition BImage.h:89
unsigned int padding
Definition BImage.h:92
unsigned int yoffset
Definition BImage.h:91
void DestroyBuffer()
Definition BImage.cpp:508

◆ DrawGlyph()

void BImage::DrawGlyph ( HDC hdc,
RECT r,
int glyph,
COLORREF glyphColor )
42{
43 HPEN hPen = CreatePen(PS_SOLID, 1, glyphColor);
44 HPEN hOldPen = (HPEN) SelectObject(hdc, hPen);
45 SelectObject(hdc, GetStockObject(NULL_BRUSH)); // -> Do not automatically fill any drawn shapes below...
46
47 int x = r.left, y = r.top;
48 RECT bulletRect;
49 if (pSettings->scalingFactorHiDPI == 4) SetRect(&bulletRect, x-10, y-10, x+10, y+10); // -> 20x20 pixel bullet
50 else if (pSettings->scalingFactorHiDPI == 3) SetRect(&bulletRect, x-7, y-7, x+8, y+8); // -> 15x15 pixel bullet
51 else if (pSettings->scalingFactorHiDPI == 2) SetRect(&bulletRect, x-5, y-5, x+5, y+5); // -> 10x10 pixel bullet
52 else SetRect(&bulletRect, x-2, y-2, x+3, y+3); // -> 5x5 pixel bullet
53
54 //====================
55
56 switch (glyph)
57 {
58 case GLYPH_MENU_SQUARE: // <-> MENU_BULLET_SQUARE
59 {
60 for (int n = 1; n <= pSettings->scalingFactorHiDPI; n++)
61 {
62 Rectangle(hdc, bulletRect.left, bulletRect.top, bulletRect.right, bulletRect.bottom);
63 InflateRect(&bulletRect, -1, -1);
64 }
65 break;
66 }
67 default: break;
68 }
69
70 //====================
71
72 SelectObject(hdc, hOldPen);
73 DeleteObject(hPen);
74 DeleteObject(hOldPen);
75}
Settings * pSettings
Definition Blackbox.cpp:46
#define GLYPH_MENU_SQUARE
Definition BBApi.h:113
BYTE r
Definition BImage.h:120
int scalingFactorHiDPI
Definition Settings.h:327

◆ AlphaRect()

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
64}
PBYTE pixels
Definition BImage.h:101

◆ AlphaBorder()

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
109}

◆ AlphaCorner()

void BImage::AlphaCorner ( HDC hdc,
RECT rect,
int corner,
int borderWidth,
unsigned char minAlpha,
unsigned char maxAlpha )
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 unsigned int x, y, offset;
144 unsigned int arraySizeXY;
145 unsigned int bytesPerRow = (width*4);
146 unsigned int topleft, topright, bottomleft, bottomright;
147 unsigned int topcount, bottomcount;
148
149 bool reversed;
150 if (outerAlpha > innerAlpha) reversed = true;
151 else reversed = false;
152
153 //====================
154
155 BYTE* alphaPtr;
156// if (pSettings->doubleScaleHiDPI)
158 {
159 alphaPtr = cornerAlphaArrayHiDPI;
160 arraySizeXY = 8;
161 }
162 else
163 {
164 alphaPtr = cornerAlphaArrayLoDPI;
165 arraySizeXY = 5;
166 }
167
168 BYTE pixelAlpha;
169
170 // Set per pixel alpha values for all four corners of the target rect...
171 for (y = 0; y < arraySizeXY; y++)
172 {
173 // NOTE: We're using a bottom-up DIB
174 // -> origin is the lower-left corner!
175 bottomcount = y * bytesPerRow;
176 topcount = (height-y-1) * bytesPerRow;
177
178 for (x = 0; x < arraySizeXY; x++)
179 {
180 pixelAlpha = *alphaPtr;
181
182 if (pixelAlpha == 0xff)
183 {
184 alphaPtr++;
185 continue;
186 }
187
188 if (reversed)
189 {
190 pixelAlpha = 255 - pixelAlpha;
191 if (pixelAlpha <= innerAlpha) pixelAlpha = innerAlpha;
192 if (pixelAlpha >= outerAlpha) pixelAlpha = outerAlpha;
193 }
194 else
195 {
196 if (pixelAlpha <= outerAlpha) pixelAlpha = outerAlpha;
197 if (pixelAlpha >= innerAlpha) pixelAlpha = innerAlpha;
198 }
199
200 offset = x * 4;
201
202 if (corner & CORNER_BOTTOMLEFT)
203 {
204 bottomleft = bottomcount+offset+3;
205 pixels[bottomleft] = pixelAlpha;
206 }
207 if (corner & CORNER_BOTTOMRIGHT)
208 {
209 bottomright = bottomcount+bytesPerRow-offset-1;
210 pixels[bottomright] = pixelAlpha;
211 }
212 if (corner & CORNER_TOPLEFT)
213 {
214 topleft = topcount+offset+3;
215 pixels[topleft] = pixelAlpha;
216 }
217 if (corner & CORNER_TOPRIGHT)
218 {
219 topright = topcount+bytesPerRow-offset-1;
220 pixels[topright] = pixelAlpha;
221 }
222
223 alphaPtr++;
224 }
225 }
226
227 // Copy the pixel data including alpha values back to the destination...
228 BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
229
231}
BYTE cornerAlphaArrayLoDPI[25]
Definition Alpha.cpp:128
BYTE cornerAlphaArrayHiDPI[64]
Definition Alpha.cpp:116
#define CORNER_BOTTOMRIGHT
Definition BBApi.h:128
#define CORNER_BOTTOMLEFT
Definition BBApi.h:127
#define CORNER_TOPLEFT
Definition BBApi.h:125
#define CORNER_TOPRIGHT
Definition BBApi.h:126

◆ AlphaFromRGB()

void BImage::AlphaFromRGB ( HDC hdc,
RECT rect,
unsigned char minAlpha,
unsigned char maxAlpha,
bool recolor,
COLORREF color )
239{
240 CreateBuffer(hdc, rect, false);
241
242 // Copy pixel data from the destination...
243 BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
244
245 BYTE red, green, blue;
246 if (recolor)
247 {
248 red = GetRValue(color);
249 green = GetGValue(color);
250 blue = GetBValue(color);
251 }
252
253 unsigned int alphaRange = maxAlpha - minAlpha;
254 unsigned int averageRGB, newAlpha;
255
256 unsigned int x, y, count = 0;
257 for (y = 0; y < height; y++)
258 {
259 for (x = 0; x < width; x++)
260 {
261 // Set the per pixel alpha values as an average of each pixel's RGB values, mapped to the allowed min<->max alpha range...
262 // (e.g. assuming the full alpha range 0-255 is allowed, 0xffffff pixels become fully opaque <-> 0x000000 pixels become fully transparent)
263 averageRGB = ((pixels[count+0] + pixels[count+1] + pixels[count+2]) / 3);
264 newAlpha = minAlpha + ((averageRGB * alphaRange) / 255);
265 pixels[count+3] = (BYTE)newAlpha;
266
267 // ...and optionally recolor the pixels themselves to the specified color...
268 // (nb. this is typically also used to avoid e.g. text anti-aliasing artifacts on otherwise
269 // transparent backgrounds by making the pixels all the same colour but with different alpha values)
270 if (recolor)
271 {
272 // Use case examples:
273 // Set the new pixel colour without alpha applied to fully white 0xffffff -> "Regular/Light mode"
274 // Set the new pixel colour without alpha applied to fully black 0x000000 -> "Dark mode"
275 // Set the new pixel colour without alpha applied to any colour 0xBBGGRR -> "Recolor mode"
276 pixels[count] = blue;
277 pixels[count+1] = green;
278 pixels[count+2] = red;
279 }
280
281 count += 4;
282 }
283 }
284
285 // Copy the pixel data including alpha values back to the destination...
286 BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
287
289}
unsigned char * red
Definition BImage.h:110
unsigned char * blue
Definition BImage.h:112
unsigned char * green
Definition BImage.h:111

◆ AlphaMask()

void BImage::AlphaMask ( HDC destHdc,
RECT destRect,
HDC srcHdc,
RECT srcRect,
bool useSrcRGBAsAlpha )
299{
300 // Safeguard: Make sure that the source and destination RECTs are of the same *size*...
301 // (the actual position of each RECT inside its parent HDC is irrelevant here)
302 int srcSize = (srcRect.right - srcRect.left) * (srcRect.bottom - srcRect.top);
303 int destSize = (destRect.right - destRect.left) * (destRect.bottom - destRect.top);
304 if (srcSize != destSize) return;
305
306 //====================
307
308 // Copy the requested input values from the source HDC into a buffer...
309 CreateBuffer(srcHdc, srcRect, false);
310 BitBlt(buf, 0, 0, width, height, srcHdc, srcRect.left, srcRect.top, SRCCOPY);
311
312 BYTE* alphaBuffer = (BYTE*)malloc(width*height);
313 if (alphaBuffer == NULL)
314 {
316 return;
317 }
318
319 unsigned int x, y, count;
320
321 // Should we use the source per pixel colors as the destination per pixel alpha values...
322 // (nb. greyscale source format assumed so we can use any of R/G/B; here using the B value)
323 if (useSrcRGBAsAlpha) count = 0; // Per pixel data offset 0 bytes -> B value
324 // ...or copy the per pixel alpha values straight over from the source to the destination?
325 else count = 3; // Per pixel data offset 3 bytes -> Alpha value
326
327 BYTE* alphaPtr = alphaBuffer;
328 for (y = 0; y < height; y++)
329 {
330 for (x = 0; x < width; x++)
331 {
332 *alphaPtr = pixels[count];
333 alphaPtr++;
334 count += 4;
335 }
336 }
337
338 BYTE* alphaBufferEnd = alphaPtr;
339
341
342// int alphaBufferSize = alphaBufferEnd - alphaBuffer;
343// char msg[255];
344// sprintf(msg, "Number of alpha bytes copied: %d", alphaBufferSize);
345// SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)msg);
346
347 //====================
348
349 // Copy the alpha values from the buffer to the destination HDC...
350 CreateBuffer(destHdc, destRect, false);
351 BitBlt(buf, 0, 0, width, height, destHdc, destRect.left, destRect.top, SRCCOPY);
352
353 alphaPtr = alphaBuffer;
354 count = 3; // Per pixel data offset 3 bytes -> Alpha value
355 for (y = 0; y < height; y++)
356 {
357 for (x = 0; x < width; x++)
358 {
359 pixels[count] = (BYTE)*alphaPtr;
360 count += 4;
361 alphaPtr++;
362 if (alphaPtr == alphaBufferEnd) break; // Safeguard
363 }
364 }
365
366 BitBlt(destHdc, destRect.left, destRect.top, width, height, buf, 0, 0, SRCCOPY);
368
369 //====================
370
371 free(alphaBuffer);
372}

◆ AlphaApply()

void BImage::AlphaApply ( HDC hdc,
RECT rect )
381{
382 CreateBuffer(hdc, rect, false);
383
384 // Copy pixel data from the destination...
385 BitBlt(buf, 0, 0, width, height, hdc, rect.left, rect.top, SRCCOPY);
386
387 // Apply per pixel alpha to the RGB values...
388 unsigned int x, y, count = 0, tempPixel;
389 BYTE alpha;
390 for (y = 0; y < height; y++)
391 {
392 for (x = 0; x < width; x++)
393 {
394 alpha = pixels[count + 3];
395
396 if (alpha < 255)
397 {
398 tempPixel = (pixels[count+2] * alpha) / 255;
399 pixels[count+2] = (BYTE)tempPixel;
400 tempPixel = (pixels[count+1] * alpha) / 255;
401 pixels[count+1] = (BYTE)tempPixel;
402 tempPixel = (pixels[count] * alpha) / 255;
403 pixels[count] = (BYTE)tempPixel;
404 }
405
406 count += 4;
407 }
408 }
409
410 // Copy the pixel data with newly applied alpha back to the destination...
411 BitBlt(hdc, rect.left, rect.top, width, height, buf, 0, 0, SRCCOPY);
412
414}

◆ PrepareCorner()

void BImage::PrepareCorner ( HDC hdc,
RECT rect,
int corner,
int bevelStyle,
int bevelPosition,
int bevelWidth,
int borderWidth )
422{
423// if (pSettings->doubleScaleHiDPI)
425 {
426 if (bevelStyle != BEVEL_FLAT)
427 {
428 if (bevelPosition == BEVEL1)
429 {
430 int offsetX, offsetY;
431
432 if (corner & CORNER_TOPLEFT)
433 {
434 // Round off the top left bevel...
435 offsetX = rect.left + borderWidth;
436 offsetY = rect.top + borderWidth;
437 SetPixel(hdc, offsetX+3, offsetY+1, GetPixel(hdc, offsetX+3, offsetY));
438 SetPixel(hdc, offsetX+2, offsetY+1, GetPixel(hdc, offsetX+2, offsetY));
439 SetPixel(hdc, offsetX+1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
440 SetPixel(hdc, offsetX+1, offsetY+3, GetPixel(hdc, offsetX, offsetY+3));
441 }
442
443 if (corner & CORNER_BOTTOMLEFT)
444 {
445 // Round off the bottom left bevel...
446 offsetX = rect.left + borderWidth;
447 offsetY = rect.bottom - borderWidth - 1;
448 SetPixel(hdc, offsetX+1, offsetY-3, GetPixel(hdc, offsetX, offsetY-3));
449 SetPixel(hdc, offsetX+1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
450 SetPixel(hdc, offsetX+2, offsetY-1, GetPixel(hdc, offsetX+2, offsetY));
451 SetPixel(hdc, offsetX+3, offsetY-1, GetPixel(hdc, offsetX+3, offsetY));
452 }
453
454 if (corner & CORNER_TOPRIGHT)
455 {
456 // Round off the top right bevel...
457 offsetX = rect.right - borderWidth - 1;
458 offsetY = rect.top + borderWidth;
459 SetPixel(hdc, offsetX-3, offsetY+1, GetPixel(hdc, offsetX-3, offsetY));
460 SetPixel(hdc, offsetX-2, offsetY+1, GetPixel(hdc, offsetX-2, offsetY));
461 SetPixel(hdc, offsetX-1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
462 SetPixel(hdc, offsetX-1, offsetY+3, GetPixel(hdc, offsetX, offsetY+3));
463 }
464
465 if (corner & CORNER_BOTTOMRIGHT)
466 {
467 // Round off the bottom right bevel...
468 offsetX = rect.right - borderWidth - 1;
469 offsetY = rect.bottom - borderWidth - 1;
470 SetPixel(hdc, offsetX-1, offsetY-3, GetPixel(hdc, offsetX, offsetY-3));
471 SetPixel(hdc, offsetX-1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
472 SetPixel(hdc, offsetX-2, offsetY-1, GetPixel(hdc, offsetX-2, offsetY));
473 SetPixel(hdc, offsetX-3, offsetY-1, GetPixel(hdc, offsetX-3, offsetY));
474 }
475 }
476 else if (bevelPosition == BEVEL2)
477 {
478 // No change necessary... [?] (as far as I can tell right now at least)
479 }
480 }
481
482 if (borderWidth > 0)
483 {
484 int offsetX, offsetY;
485
486 if (corner & CORNER_TOPLEFT)
487 {
488 // Round off the top left corner...
489 offsetX = rect.left + borderWidth;
490 offsetY = rect.top + borderWidth;
491 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY)));
492 SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY-1));
493 SetPixel(hdc, offsetX+2, offsetY, GetPixel(hdc, offsetX+2, offsetY-1));
494 SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX-1, offsetY+1));
495 SetPixel(hdc, offsetX, offsetY+2, GetPixel(hdc, offsetX-1, offsetY+2));
496 SetPixel(hdc, offsetX+1, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY+1), GetPixel(hdc, offsetX, offsetY)));
497 SetPixel(hdc, offsetX+3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+3, offsetY), GetPixel(hdc, offsetX+2, offsetY)));
498 SetPixel(hdc, offsetX, offsetY+3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+3), GetPixel(hdc, offsetX, offsetY+2)));
499 }
500
501 if (corner & CORNER_BOTTOMLEFT)
502 {
503 // Round off the bottom left corner...
504 offsetX = rect.left + borderWidth;
505 offsetY = rect.bottom - borderWidth - 1;
506 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY)));
507 SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY+1));
508 SetPixel(hdc, offsetX+2, offsetY, GetPixel(hdc, offsetX+2, offsetY+1));
509 SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX-1, offsetY-1));
510 SetPixel(hdc, offsetX, offsetY-2, GetPixel(hdc, offsetX-1, offsetY-2));
511 SetPixel(hdc, offsetX+1, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY-1), GetPixel(hdc, offsetX, offsetY)));
512 SetPixel(hdc, offsetX+3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+3, offsetY), GetPixel(hdc, offsetX+2, offsetY)));
513 SetPixel(hdc, offsetX, offsetY-3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-3), GetPixel(hdc, offsetX, offsetY-2)));
514 }
515
516 if (corner & CORNER_TOPRIGHT)
517 {
518 // Round off the top right corner...
519 offsetX = rect.right - borderWidth - 1;
520 offsetY = rect.top + borderWidth;
521 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY)));
522 SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY-1));
523 SetPixel(hdc, offsetX-2, offsetY, GetPixel(hdc, offsetX-2, offsetY-1));
524 SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX+1, offsetY+1));
525 SetPixel(hdc, offsetX, offsetY+2, GetPixel(hdc, offsetX+1, offsetY+2));
526 SetPixel(hdc, offsetX-1, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY+1), GetPixel(hdc, offsetX, offsetY)));
527 SetPixel(hdc, offsetX-3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-3, offsetY), GetPixel(hdc, offsetX-2, offsetY)));
528 SetPixel(hdc, offsetX, offsetY+3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+3), GetPixel(hdc, offsetX, offsetY+2)));
529 }
530
531 if (corner & CORNER_BOTTOMRIGHT)
532 {
533 // Round off the bottom right corner...
534 offsetX = rect.right - borderWidth - 1;
535 offsetY = rect.bottom - borderWidth - 1;
536 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY)));
537 SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY+1));
538 SetPixel(hdc, offsetX-2, offsetY, GetPixel(hdc, offsetX-2, offsetY+1));
539 SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX+1, offsetY-1));
540 SetPixel(hdc, offsetX, offsetY-2, GetPixel(hdc, offsetX+1, offsetY-2));
541 SetPixel(hdc, offsetX-1, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY-1), GetPixel(hdc, offsetX, offsetY)));
542 SetPixel(hdc, offsetX-3, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-3, offsetY), GetPixel(hdc, offsetX-2, offsetY)));
543 SetPixel(hdc, offsetX, offsetY-3, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-3), GetPixel(hdc, offsetX, offsetY-2)));
544 }
545 }
546 }
547
548 //====================
549
550 else // if (pSettings->scalingFactorHiDPI == 1)
551 {
552 if (bevelStyle != BEVEL_FLAT)
553 {
554 if (bevelPosition == BEVEL1)
555 {
556 int offsetX, offsetY;
557
558 if (corner & CORNER_TOPLEFT)
559 {
560 // Round off the top left bevel...
561 offsetX = rect.left + borderWidth;
562 offsetY = rect.top + borderWidth;
563 SetPixel(hdc, offsetX+1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
564 }
565
566 if (corner & CORNER_BOTTOMLEFT)
567 {
568 // Round off the bottom left bevel...
569 offsetX = rect.left + borderWidth;
570 offsetY = rect.bottom - borderWidth - 1;
571 SetPixel(hdc, offsetX+1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
572 }
573
574 if (corner & CORNER_TOPRIGHT)
575 {
576 // Round off the top right bevel...
577 offsetX = rect.right - borderWidth - 1;
578 offsetY = rect.top + borderWidth;
579 SetPixel(hdc, offsetX-1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
580 }
581
582 if (corner & CORNER_BOTTOMRIGHT)
583 {
584 // Round off the bottom right bevel...
585 offsetX = rect.right - borderWidth - 1;
586 offsetY = rect.bottom - borderWidth - 1;
587 SetPixel(hdc, offsetX-1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
588 }
589 }
590 else if (bevelPosition == BEVEL2)
591 {
592 // No change necessary... [?] (as far as I can tell right now at least)
593 }
594 }
595
596 if (borderWidth > 0)
597 {
598 int offsetX, offsetY;
599
600 if (corner & CORNER_TOPLEFT)
601 {
602 // Round off the top left corner...
603 offsetX = rect.left;
604 offsetY = rect.top;
605 SetPixel(hdc, offsetX+1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
606 SetPixel(hdc, offsetX+2, offsetY+1, GetPixel(hdc, offsetX+2, offsetY));
607 SetPixel(hdc, offsetX+1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
608 offsetX += borderWidth;
609 offsetY += borderWidth;
610 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY)));
611 SetPixel(hdc, offsetX+1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX+1, offsetY-1)));
612 SetPixel(hdc, offsetX, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY+1)));
613// SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX, offsetY-1)));
614// SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY-1));
615// SetPixel(hdc, offsetX+2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+2, offsetY), GetPixel(hdc, offsetX+2, offsetY-1)));
616// SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX-1, offsetY+1));
617// SetPixel(hdc, offsetX, offsetY+2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+2), GetPixel(hdc, offsetX-1, offsetY+2)));
618 }
619
620 if (corner & CORNER_BOTTOMLEFT)
621 {
622 // Round off the bottom left corner...
623 offsetX = rect.left;
624 offsetY = rect.bottom - 1;
625 SetPixel(hdc, offsetX+1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
626 SetPixel(hdc, offsetX+2, offsetY-1, GetPixel(hdc, offsetX+2, offsetY));
627 SetPixel(hdc, offsetX+1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
628 offsetX += borderWidth;
629 offsetY -= borderWidth;
630 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX-1, offsetY)));
631 SetPixel(hdc, offsetX+1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX+1, offsetY+1)));
632 SetPixel(hdc, offsetX, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX-1, offsetY-1)));
633// SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX, offsetY+1)));
634// SetPixel(hdc, offsetX+1, offsetY, GetPixel(hdc, offsetX+1, offsetY+1));
635// SetPixel(hdc, offsetX+2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+2, offsetY), GetPixel(hdc, offsetX+2, offsetY+1)));
636// SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX-1, offsetY-1));
637// SetPixel(hdc, offsetX, offsetY-2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-2), GetPixel(hdc, offsetX-1, offsetY-2)));
638 }
639
640 if (corner & CORNER_TOPRIGHT)
641 {
642 // Round off the top right corner...
643 offsetX = rect.right - 1;
644 offsetY = rect.top;
645 SetPixel(hdc, offsetX-1, offsetY+1, GetPixel(hdc, offsetX, offsetY));
646 SetPixel(hdc, offsetX-2, offsetY+1, GetPixel(hdc, offsetX-2, offsetY));
647 SetPixel(hdc, offsetX-1, offsetY+2, GetPixel(hdc, offsetX, offsetY+2));
648 offsetX -= borderWidth;
649 offsetY += borderWidth;
650 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY)));
651 SetPixel(hdc, offsetX-1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX-1, offsetY-1)));
652 SetPixel(hdc, offsetX, offsetY+1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY+1)));
653// SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX, offsetY-1)));
654// SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY-1));
655// SetPixel(hdc, offsetX-2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-2, offsetY), GetPixel(hdc, offsetX-2, offsetY-1)));
656// SetPixel(hdc, offsetX, offsetY+1, GetPixel(hdc, offsetX+1, offsetY+1));
657// SetPixel(hdc, offsetX, offsetY+2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+2), GetPixel(hdc, offsetX+1, offsetY+2)));
658 }
659
660 if (corner & CORNER_BOTTOMRIGHT)
661 {
662 // Round off the bottom right corner...
663 offsetX = rect.right - 1;
664 offsetY = rect.bottom - 1;
665 SetPixel(hdc, offsetX-1, offsetY-1, GetPixel(hdc, offsetX, offsetY));
666 SetPixel(hdc, offsetX-2, offsetY-1, GetPixel(hdc, offsetX-2, offsetY));
667 SetPixel(hdc, offsetX-1, offsetY-2, GetPixel(hdc, offsetX, offsetY-2));
668 offsetX -= borderWidth;
669 offsetY -= borderWidth;
670 SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY+1), GetPixel(hdc, offsetX+1, offsetY)));
671 SetPixel(hdc, offsetX-1, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-1, offsetY), GetPixel(hdc, offsetX-1, offsetY+1)));
672 SetPixel(hdc, offsetX, offsetY-1, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-1), GetPixel(hdc, offsetX+1, offsetY-1)));
673// SetPixel(hdc, offsetX, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX+1, offsetY), GetPixel(hdc, offsetX, offsetY+1)));
674// SetPixel(hdc, offsetX-1, offsetY, GetPixel(hdc, offsetX-1, offsetY+1));
675// SetPixel(hdc, offsetX-2, offsetY, pSettings->MixColors(GetPixel(hdc, offsetX-2, offsetY), GetPixel(hdc, offsetX-2, offsetY+1)));
676// SetPixel(hdc, offsetX, offsetY-1, GetPixel(hdc, offsetX+1, offsetY-1));
677// SetPixel(hdc, offsetX, offsetY-2, pSettings->MixColors(GetPixel(hdc, offsetX, offsetY-2), GetPixel(hdc, offsetX+1, offsetY-2)));
678 }
679 }
680 }
681}
#define BEVEL1
Definition BBApi.h:108
#define BEVEL2
Definition BBApi.h:109
COLORREF MixColors(COLORREF colorA, COLORREF colorB)
Definition Settings.cpp:2231

◆ CreateBuffer()

void BImage::CreateBuffer ( HDC hdc,
RECT rect,
bool createTables )
private
474{
475 width = rect.right - rect.left;
476 height = rect.bottom - rect.top;
477
478 buf = CreateCompatibleDC(NULL);
479
480 BITMAPINFOHEADER bv4info;
481 ZeroMemory(&bv4info, sizeof(BITMAPINFOHEADER));
482 bv4info.biSize = sizeof(BITMAPINFOHEADER);
483 bv4info.biWidth = width;
484 bv4info.biHeight = height;
485 bv4info.biPlanes = 1;
486 bv4info.biBitCount = 32;
487 bv4info.biCompression = BI_RGB;
488
489 BITMAPINFO bminfo;
490// ZeroMemory(&bminfo, sizeof(BITMAPINFO));
491 bminfo.bmiHeader = bv4info;
492
493 bufbmp = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS,(PVOID *) &pixels, NULL, 0);
494 oldbuf = (HBITMAP)SelectObject(buf, bufbmp);
495
496 // The x/y tables are only used when rendering gradients,
497 // not needed when setting or applying per pixel alpha...
498 if (createTables)
499 {
500 xtable = new unsigned int[width * 3];
501 ytable = new unsigned int[height * 3];
502 }
503 else xtable = ytable = NULL;
504}
unsigned int * xtable
Definition BImage.h:113
HBITMAP bufbmp
Definition BImage.h:95
unsigned int * ytable
Definition BImage.h:114
HBITMAP oldbuf
Definition BImage.h:96

◆ DestroyBuffer()

void BImage::DestroyBuffer ( )
private
509{
510 SelectObject(buf, oldbuf);
511 DeleteDC(buf);
512 DeleteObject(bufbmp);
513 DeleteObject(oldbuf);
514
515 if (xtable) delete [] xtable;
516 if (ytable) delete [] ytable;
517 xtable = ytable = NULL;
518}

◆ CheckRemainder()

bool BImage::CheckRemainder ( int divider,
int remainder,
int i )
private
316{
317 if (divider == 7)
318 {
319 switch (i)
320 {
321 case 1: { if (remainder >= 6) return true; break; }
322 case 2: { if (remainder >= 4) return true; break; }
323 case 3: { if (remainder >= 2) return true; break; }
324 case 4: { if (remainder >= 1) return true; break; }
325 case 5: { if (remainder >= 3) return true; break; }
326 case 6: { if (remainder >= 5) return true; break; }
327 default: { return false; }
328 }
329 }
330 else if (divider == 3)
331 {
332 switch (i)
333 {
334 case 1: { if (remainder >= 2) return true; break; }
335 case 2: { if (remainder >= 1) return true; break; }
336 default: { return false; }
337 }
338 }
339
340 return false;
341}

◆ PaintGradient()

void BImage::PaintGradient ( int type,
COLORREF colorFrom,
COLORREF colorTo,
int bevelStyle )
private
346{
347 from_red = GetRValue(colorFrom);
348 from_green = GetGValue(colorFrom);
349 from_blue = GetBValue(colorFrom);
350 to_red = GetRValue(colorTo);
351 to_green = GetGValue(colorTo);
352 to_blue = GetBValue(colorTo);
353
354 sunken = false;
355
356 //====================
357
358 if (bevelStyle == BEVEL_SUNKEN)
359 {
360 switch (type)
361 {
362 case B_PIPECROSS:
363 case B_ELLIPTIC:
364 case B_RECTANGLE:
365 case B_PYRAMID:
366 {
367 BYTE tempcolor;
368 // Swap red...
369 tempcolor = from_red;
371 to_red = tempcolor;
372 // Swap green...
373 tempcolor = from_green;
375 to_green = tempcolor;
376 // Swap blue...
377 tempcolor = from_blue;
379 to_blue = tempcolor;
380 }
381 }
382
383 sunken = true;
384 }
385
386 //====================
387
388 switch (type)
389 {
390 case B_VERTICAL:
391 vgradient();
392 break;
393
394 case B_DIAGONAL:
395 dgradient();
396 break;
397
398 case B_CROSSDIAGONAL:
399 cdgradient();
400 break;
401
402 case B_PIPECROSS:
403 pcgradient();
404 break;
405
406 case B_ELLIPTIC:
407 egradient();
408 break;
409
410 case B_RECTANGLE:
411 rgradient();
412 break;
413
414 case B_PYRAMID:
415 pgradient();
416 break;
417
418 case B_SOLID:
419 {
420 SetRect(&fillRect, 0, 0, width, height);
421 solid_brush = CreateSolidBrush(colorFrom);
422 FillRect(buf, &fillRect, solid_brush);
423 DeleteObject(solid_brush);
424 break;
425 }
426
427 case B_SPLITSOLID:
428 {
429 // Upper half...
430 SetRect(&fillRect, 0, 0, width, height/2);
431 solid_brush = CreateSolidBrush(colorFrom);
432 FillRect(buf, &fillRect, solid_brush);
433 DeleteObject(solid_brush);
434
435 // Lower half...
436 fillRect.top = fillRect.bottom;
437 fillRect.bottom = height;
438 solid_brush = CreateSolidBrush(colorTo);
439 FillRect(buf, &fillRect, solid_brush);
440 DeleteObject(solid_brush);
441
442 break;
443 }
444
445 //====================
446
447 default:
448 hgradient(); // B_HORIZONTAL is the default type...
449 }
450}
#define B_CROSSDIAGONAL
Definition BBApi.h:75
#define B_SOLID
Definition BBApi.h:80
#define B_ELLIPTIC
Definition BBApi.h:77
#define B_DIAGONAL
Definition BBApi.h:74
#define B_SPLITSOLID
Definition BBApi.h:88
#define B_PIPECROSS
Definition BBApi.h:76
#define BEVEL_SUNKEN
Definition BBApi.h:107
#define B_PYRAMID
Definition BBApi.h:79
#define B_RECTANGLE
Definition BBApi.h:78
BYTE to_blue
Definition BImage.h:108
void egradient(void)
Definition BImage.cpp:1062
BYTE from_red
Definition BImage.h:103
void hgradient(void)
Definition BImage.cpp:811
HBRUSH solid_brush
Definition BImage.h:97
bool sunken
Definition BImage.h:116
void dgradient(void)
Definition BImage.cpp:745
void rgradient(void)
Definition BImage.cpp:988
BYTE from_green
Definition BImage.h:104
void pgradient(void)
Definition BImage.cpp:916
void pcgradient(void)
Definition BImage.cpp:1142
BYTE from_blue
Definition BImage.h:105
void vgradient(void)
Definition BImage.cpp:867
RECT fillRect
Definition BImage.h:99
BYTE to_red
Definition BImage.h:106
void cdgradient(void)
Definition BImage.cpp:1216
BYTE to_green
Definition BImage.h:107

◆ ApplyBevel()

void BImage::ApplyBevel ( int bevelStyle,
int bevelPosition,
int bevelWidth )
private
529{
530 if (bevelStyle != BEVEL_FLAT)
531 {
532 switch (bevelPosition)
533 {
534 case BEVEL1:
535 bevel1(sunken);
536 break;
537
538 case BEVEL2:
539 bevel2(sunken);
540 break;
541 }
542 }
543}
void bevel1(bool sunken)
Definition BImage.cpp:547
void bevel2(bool sunken)
Definition BImage.cpp:598

◆ bevel1()

void BImage::bevel1 ( bool sunken)
private
548{
549 if (width > 2 && height > 2)
550 {
551 unsigned int count, x, y;
552 unsigned int w = ((width * 4) - 4), h = (width * (height-1) * 4);
553 unsigned int nextpixel = 4, nextline = (width * 4);
554
555 //====================
556
557 count = 0;
558 for (x = 0; x < width; x++)
559 {
560 // NOTE: We're using a bottom-up DIB -> origin is the lower-left corner!
561 if (!sunken)
562 {
563 lightenpixel(count+h); // Upper horizontal bevel for BEVEL_RAISED
564 if (x) darkenpixel(count); // Lower horizontal bevel for BEVEL_RAISED (do not bevelize the first pixel twice!)
565 }
566 else
567 {
568 darkenpixel(count+h); // Upper horizontal bevel for BEVEL_SUNKEN
569 if (x) lightenpixel(count); // Lower horizontal bevel for BEVEL_SUNKEN (do not bevelize the first pixel twice!)
570 }
571
572 count += nextpixel;
573 }
574
575 //====================
576
577 count = 0;
578 for (y = 0; y < (height-1); y++)
579 {
580 if (!sunken)
581 {
582 lightenpixel(count); // Left vertical bevel for BEVEL_RAISED
583 if (y) darkenpixel(count+w); // Right vertical bevel for BEVEL_RAISED (do not bevelize the first pixel twice!)
584 }
585 else
586 {
587 darkenpixel(count); // Left vertical bevel for BEVEL_SUNKEN
588 if (y) lightenpixel(count+w); // Right vertical bevel for BEVEL_SUNKEN (do not bevelize the first pixel twice!)
589 }
590
591 count += nextline;
592 }
593 }
594}
void darkenpixel(unsigned int count)
Definition BImage.cpp:664
void lightenpixel(unsigned int count)
Definition BImage.cpp:645

◆ bevel2()

void BImage::bevel2 ( bool sunken)
private
599{
600 if (width > 4 && height > 4)
601 {
602 unsigned int count, x, y, w = ((width * 4) - 12), h = (width * (height-3) * 4);
603 unsigned int nextpixel = 4, nextline = (width * 4);
604
605 count = nextline + nextpixel;
606 for (x = 0; x < (width-2); x++)
607 {
608 // NOTE: We're using a bottom-up DIB -> origin is the lower-left corner!
609
610 if (!sunken)
611 {
612 lightenpixel(count+h); // Upper horizontal bevel for BEVEL_RAISED
613 if (x) darkenpixel(count); // Lower horizontal bevel for BEVEL_RAISED (do not bevelize the first pixel twice!)
614 }
615 else
616 {
617 darkenpixel(count+h); // Upper horizontal bevel for BEVEL_SUNKEN
618 if (x) lightenpixel(count); // Lower horizontal bevel for BEVEL_SUNKEN (do not bevelize the first pixel twice!)
619 }
620
621 count += nextpixel;
622 }
623
624 count = nextline + nextpixel;
625 for (y = 0; y < (height-3); y++)
626 {
627 if (!sunken)
628 {
629 lightenpixel(count); // Left vertical bevel for BEVEL_RAISED
630 if (y) darkenpixel(count+w); // Right vertical bevel for BEVEL_RAISED (do not bevelize the first pixel twice!)
631 }
632 else
633 {
634 darkenpixel(count); // Left vertical bevel for BEVEL_SUNKEN
635 if (y) lightenpixel(count+w); // Right vertical bevel for BEVEL_SUNKEN (do not bevelize the first pixel twice!)
636 }
637
638 count += nextline;
639 }
640 }
641}

◆ lightenpixel()

void BImage::lightenpixel ( unsigned int count)
private
646{
647 r = pixels[count + 2];
648 rr = r + (r >> 1);
649 if (rr < r) rr = ~0;
650 g = pixels[count + 1];
651 gg = g + (g >> 1);
652 if (gg < g) gg = ~0;
653 b = pixels[count];
654 bb = b + (b >> 1);
655 if (bb < b) bb = ~0;
656
657 pixels[count + 2] = rr;
658 pixels[count + 1] = gg;
659 pixels[count] = bb;
660}
BYTE bb
Definition BImage.h:120
BYTE rr
Definition BImage.h:120
BYTE g
Definition BImage.h:120
BYTE gg
Definition BImage.h:120
BYTE b
Definition BImage.h:120

◆ darkenpixel()

void BImage::darkenpixel ( unsigned int count)
private
665{
666 r = pixels[count + 2];
667 rr = (r >> 2) + (r >> 1);
668 if (rr > r) rr = 0;
669 g = pixels[count + 1];
670 gg = (g >> 2) + (g >> 1);
671 if (gg > g) gg = 0;
672 b = pixels[count];
673 bb = (b >> 2) + (b >> 1);
674 if (bb > b) bb = 0;
675
676 pixels[count + 2] = rr;
677 pixels[count + 1] = gg;
678 pixels[count] = bb;
679}

◆ ApplyInterlace()

void BImage::ApplyInterlace ( bool bInterlaced)
private
684{
685 if (!bInterlaced) return;
686 if ((height <= 2) || (width <= 2)) return;
687
688 UINT x, y, count = 0;
689 unsigned char channel, channel2;
690
691 for (y = 0; y < height; y++)
692 {
693 for (x =0; x < width; x++)
694 {
695 if (y & 1)
696 {
697 channel = pixels[count + 2];
698 channel2 = (channel >> 1) + (channel >> 2);
699 if (channel2 > channel) channel2 = 0;
700 pixels[count + 2] = channel2;
701
702 channel = pixels[count + 1];
703 channel2 = (channel >> 1) + (channel >> 2);
704 if (channel2 > channel) channel2 = 0;
705 pixels[count + 1] = channel2;
706
707 channel = pixels[count];
708 channel2 = (channel >> 1) + (channel >> 2);
709 if (channel2 > channel) channel2 = 0;
710 pixels[count] = channel2;
711 }
712 else
713 {
714 channel = pixels[count + 2];
715 channel2 = channel + (channel >> 3);
716 if (channel2 < channel) channel2 = ~0;
717 pixels[count + 2] = channel2;
718
719 channel = pixels[count + 1];
720 channel2 = channel + (channel >> 3);
721 if (channel2 < channel) channel2 = ~0;
722 pixels[count + 1] = channel2;
723
724 channel = pixels[count];
725 channel2 = channel + (channel >> 3);
726 if (channel2 < channel) channel2 = ~0;
727 pixels[count] = channel2;
728 }
729
730 count += 4;
731 }
732 }
733}

◆ dgradient()

void BImage::dgradient ( void )
private
746{
747 if ((height <= 2) || (width <= 2)) return;
748
749 // diagonal gradient code was written by Mike Cole <mike@mydot.com>
750 // modified for interlacing by Brad Hughes
751
752 float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
753 xr = (float) from_red,
754 xg = (float) from_green,
755 xb = (float) from_blue;
756
757 UINT w = width * 2, h = height * 2, *xt = xtable, *yt = ytable, x, y, count = 0;
758
759 dry = drx = (float) (to_red - from_red);
760 dgy = dgx = (float) (to_green - from_green);
761 dby = dbx = (float) (to_blue - from_blue);
762
763 // Create X table
764 drx /= w;
765 dgx /= w;
766 dbx /= w;
767
768 for (x = 0; x < width; x++)
769 {
770 *(xt++) = (unsigned char) (xr);
771 *(xt++) = (unsigned char) (xg);
772 *(xt++) = (unsigned char) (xb);
773
774 xr += drx;
775 xg += dgx;
776 xb += dbx;
777 }
778
779 // Create Y table
780 dry /= h;
781 dgy /= h;
782 dby /= h;
783
784 for (yt = (ytable + (height * 3) - 1), y = 0; y < height; y++)
785 {
786 *(yt--) = ((unsigned char) yb);
787 *(yt--) = ((unsigned char) yg);
788 *(yt--) = ((unsigned char) yr);
789
790 yr += dry;
791 yg += dgy;
792 yb += dby;
793 }
794
795 // Combine tables to create gradient
796
797 for (yt = ytable, y = 0; y < height; y++, yt += 3)
798 {
799 for (xt = xtable, x = 0; x < width; x++)
800 {
801 pixels[count + 2] = *(xt++) + *(yt);
802 pixels[count + 1] = *(xt++) + *(yt + 1);
803 pixels[count] = *(xt++) + *(yt + 2);
804 count += 4;
805 }
806 }
807}

◆ hgradient()

void BImage::hgradient ( void )
private
812{
813// if ((height <= 2) || (width <= 2)) return;
814 if ((height < 1) || (width < 1)) return;
815
816 //====================
817
818 float xr = (float) from_red;
819 float xg = (float) from_green;
820 float xb = (float) from_blue;
821
822 float drx = (float) (to_red - from_red);
823 float dgx = (float) (to_green - from_green);
824 float dbx = (float) (to_blue - from_blue);
825
826 drx /= width;
827 dgx /= width;
828 dbx /= width;
829
830 //====================
831
832 unsigned int x, y, count, o = (xoffset*4), w = (width*4), p = (padding*4);
833
834 // Draw the first row of pixels...
835 count = o;
836 for (x = 0; x < (width-1); x++)
837 {
838 pixels[count+2] = (unsigned char) (xr);
839 pixels[count+1] = (unsigned char) (xg);
840 pixels[count] = (unsigned char) (xb);
841
842 xr += drx;
843 xg += dgx;
844 xb += dbx;
845
846 count += 4;
847 }
848 pixels[count+2] = to_red;
849 pixels[count+1] = to_green;
850 pixels[count] = to_blue;
851
852 // ...then memcpy this first row onto the remaining rows...
853 count = o+w+p;
854 for (y = 1; y < height; y++)
855 {
856 void* dest = &pixels[count];
857 void* src = &pixels[o];
858 memcpy(dest, src, w);
859
860 count += w;
861 count += p;
862 }
863}

◆ vgradient()

void BImage::vgradient ( void )
private
868{
869// if ((height <= 2) || (width <= 2)) return;
870 if ((height < 1) || (width < 1)) return;
871
872 //====================
873
874 float yr = (float) to_red;
875 float yg = (float) to_green;
876 float yb = (float) to_blue;
877
878 float dry = (float) (from_red - to_red);
879 float dgy = (float) (from_green - to_green);
880 float dby = (float) (from_blue - to_blue);
881
882 dry /= height;
883 dgy /= height;
884 dby /= height;
885
886 //====================
887
888 UINT x, y, count = yoffset*width*4, lastRow = (height-1);
889
890 for (y = 0; y < height; y++)
891 {
892 for (x = 0; x < width; x++)
893 {
894 if (y == lastRow)
895 {
896 pixels[count+2] = from_red;
897 pixels[count+1] = from_green;
898 pixels[count] = from_blue;
899 }
900 else
901 {
902 pixels[count+2] = (unsigned char) yr;
903 pixels[count+1] = (unsigned char) yg;
904 pixels[count] = (unsigned char) yb;
905 }
906 count += 4;
907 }
908 yr += dry;
909 yg += dgy;
910 yb += dby;
911 }
912}

◆ pgradient()

void BImage::pgradient ( void )
private
917{
918 if ((height <= 2) || (width <= 2)) return;
919
920 // pyramid gradient - based on original dgradient, written by
921 // Mosfet (mosfet@kde.org)
922 // adapted from kde sources for Blackbox by Brad Hughes
923
924 float yr, yg, yb, drx, dgx, dbx, dry, dgy, dby, xr, xg, xb;
925 int rsign, gsign, bsign;
926 UINT tr = to_red, tg = to_green, tb = to_blue, *xt = xtable, *yt = ytable, x, y, count = 0;
927
928 dry = drx = (float) (to_red - from_red);
929 dgy = dgx = (float) (to_green - from_green);
930 dby = dbx = (float) (to_blue - from_blue);
931
932 rsign = (drx < 0) ? -1 : 1;
933 gsign = (dgx < 0) ? -1 : 1;
934 bsign = (dbx < 0) ? -1 : 1;
935
936 xr = yr = (drx / 2);
937 xg = yg = (dgx / 2);
938 xb = yb = (dbx / 2);
939
940 // Create X table
941 drx /= width;
942 dgx /= width;
943 dbx /= width;
944
945 for (x = 0; x < width; x++)
946 {
947 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
948 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
949 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
950
951 xr -= drx;
952 xg -= dgx;
953 xb -= dbx;
954 }
955
956 // Create Y table
957 dry /= height;
958 dgy /= height;
959 dby /= height;
960
961 for (y = 0; y < height; y++)
962 {
963 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
964 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
965 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
966
967 yr -= dry;
968 yg -= dgy;
969 yb -= dby;
970 }
971
972 // Combine tables to create gradient
973
974 for (yt = ytable, y = 0; y < height; y++, yt += 3)
975 {
976 for (xt = xtable, x = 0; x < width; x++)
977 {
978 pixels[count + 2] = (unsigned char) (tr - (rsign * (*(xt++) + *(yt))));
979 pixels[count + 1] = (unsigned char) (tg - (gsign * (*(xt++) + *(yt + 1))));
980 pixels[count] = (unsigned char) (tb - (bsign * (*(xt++) + *(yt + 2))));
981 count += 4;
982 }
983 }
984}

◆ rgradient()

void BImage::rgradient ( void )
private
989{
990 if ((height <= 2) || (width <= 2)) return;
991
992 // rectangle gradient - based on original dgradient, written by
993 // Mosfet (mosfet@kde.org)
994 // adapted from kde sources for Blackbox by Brad Hughes
995
996 float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
997 int rsign, gsign, bsign;
998 unsigned int tr = to_red, tg = to_green, tb = to_blue, *xt = xtable, *yt = ytable;
999
1000 UINT x, y, count = 0;
1001
1002 dry = drx = (float) (to_red - from_red);
1003 dgy = dgx = (float) (to_green - from_green);
1004 dby = dbx = (float) (to_blue - from_blue);
1005
1006 rsign = (drx < 0) ? -2 : 2;
1007 gsign = (dgx < 0) ? -2 : 2;
1008 bsign = (dbx < 0) ? -2 : 2;
1009
1010 xr = yr = (drx / 2);
1011 xg = yg = (dgx / 2);
1012 xb = yb = (dbx / 2);
1013
1014 // Create X table
1015 drx /= width;
1016 dgx /= width;
1017 dbx /= width;
1018
1019 for (x = 0; x < width; x++)
1020 {
1021 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
1022 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
1023 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
1024
1025 xr -= drx;
1026 xg -= dgx;
1027 xb -= dbx;
1028 }
1029
1030 // Create Y table
1031 dry /= height;
1032 dgy /= height;
1033 dby /= height;
1034
1035 for (y = 0; y < height; y++)
1036 {
1037 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
1038 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
1039 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
1040
1041 yr -= dry;
1042 yg -= dgy;
1043 yb -= dby;
1044 }
1045
1046 // Combine tables to create gradient
1047
1048 for (yt = ytable, y = 0; y < height; y++, yt += 3)
1049 {
1050 for (xt = xtable, x = 0; x < width; x++)
1051 {
1052 pixels[count + 2] = (unsigned char) (tr - (rsign * lmax(*(xt++), *(yt))));
1053 pixels[count + 1] = (unsigned char) (tg - (gsign * lmax(*(xt++), *(yt + 1))));
1054 pixels[count] = (unsigned char) (tb - (bsign * lmax(*(xt++), *(yt + 2))));
1055 count += 4;
1056 }
1057 }
1058}
T lmax(T a, T b)
Definition BImage.cpp:523

◆ egradient()

void BImage::egradient ( void )
private
1063{
1064 if ((height <= 2) || (width <= 2)) return;
1065
1066 // elliptic gradient - based on original dgradient, written by
1067 // Mosfet (mosfet@kde.org)
1068 // adapted from kde sources for Blackbox by Brad Hughes
1069
1070 float drx, dgx, dbx, dry, dgy, dby, yr, yg, yb, xr, xg, xb;
1071 int rsign, gsign, bsign;
1072 unsigned int *xt = xtable, *yt = ytable,
1073 tr = (unsigned long) to_red,
1074 tg = (unsigned long) to_green,
1075 tb = (unsigned long) to_blue;
1076
1077 UINT x, y, count = 0;
1078
1079 dry = drx = (float) (to_red - from_red);
1080 dgy = dgx = (float) (to_green - from_green);
1081 dby = dbx = (float) (to_blue - from_blue);
1082
1083 rsign = (drx < 0) ? -1 : 1;
1084 gsign = (dgx < 0) ? -1 : 1;
1085 bsign = (dbx < 0) ? -1 : 1;
1086
1087 xr = yr = (drx / 2);
1088 xg = yg = (dgx / 2);
1089 xb = yb = (dbx / 2);
1090
1091 // Create X table
1092 drx /= width;
1093 dgx /= width;
1094 dbx /= width;
1095
1096 for (x = 0; x < width; x++)
1097 {
1098 *(xt++) = (unsigned long) (xr * xr);
1099 *(xt++) = (unsigned long) (xg * xg);
1100 *(xt++) = (unsigned long) (xb * xb);
1101
1102 xr -= drx;
1103 xg -= dgx;
1104 xb -= dbx;
1105 }
1106
1107 // Create Y table
1108 dry /= height;
1109 dgy /= height;
1110 dby /= height;
1111
1112 for (y = 0; y < height; y++)
1113 {
1114 *(yt++) = (unsigned long) (yr * yr);
1115 *(yt++) = (unsigned long) (yg * yg);
1116 *(yt++) = (unsigned long) (yb * yb);
1117
1118 yr -= dry;
1119 yg -= dgy;
1120 yb -= dby;
1121 }
1122
1123 // Combine tables to create gradient
1124
1125 for (yt = ytable, y = 0; y < height; y++, yt += 3)
1126 {
1127 for (xt = xtable, x = 0; x < width; x++)
1128 {
1129 pixels[count + 2] = (unsigned char)
1130 (tr - (rsign * getSqrt(*(xt++) + *(yt))));
1131 pixels[count + 1] = (unsigned char)
1132 (tg - (gsign * getSqrt(*(xt++) + *(yt + 1))));
1133 pixels[count] = (unsigned char)
1134 (tb - (bsign * getSqrt(*(xt++) + *(yt + 2))));
1135 count += 4;
1136 }
1137 }
1138}
unsigned long getSqrt(unsigned int x)
Definition BImage.cpp:1301

◆ pcgradient()

void BImage::pcgradient ( void )
private
1143{
1144 if ((height <= 4) || (width <= 4)) return;
1145
1146 // pipe cross gradient - based on original dgradient, written by
1147 // Mosfet (mosfet@kde.org)
1148 // adapted from kde sources for Blackbox by Brad Hughes
1149
1150 float drx, dgx, dbx, dry, dgy, dby, xr, xg, xb, yr, yg, yb;
1151 int rsign, gsign, bsign;
1152 unsigned int *xt = xtable, *yt = ytable, tr = to_red, tg = to_green, tb = to_blue;
1153
1154 UINT x, y, count = 0;
1155
1156 dry = drx = (float) (to_red - from_red);
1157 dgy = dgx = (float) (to_green - from_green);
1158 dby = dbx = (float) (to_blue - from_blue);
1159
1160 rsign = (drx < 0) ? -2 : 2;
1161 gsign = (dgx < 0) ? -2 : 2;
1162 bsign = (dbx < 0) ? -2 : 2;
1163
1164 xr = yr = (drx / 2);
1165 xg = yg = (dgx / 2);
1166 xb = yb = (dbx / 2);
1167
1168 // Create X table
1169 drx /= width;
1170 dgx /= width;
1171 dbx /= width;
1172
1173 for (x = 0; x < width; x++)
1174 {
1175 *(xt++) = (unsigned char) ((xr < 0) ? -xr : xr);
1176 *(xt++) = (unsigned char) ((xg < 0) ? -xg : xg);
1177 *(xt++) = (unsigned char) ((xb < 0) ? -xb : xb);
1178
1179 xr -= drx;
1180 xg -= dgx;
1181 xb -= dbx;
1182 }
1183
1184 // Create Y table
1185 dry /= height;
1186 dgy /= height;
1187 dby /= height;
1188
1189 for (y = 0; y < height; y++)
1190 {
1191 *(yt++) = ((unsigned char) ((yr < 0) ? -yr : yr));
1192 *(yt++) = ((unsigned char) ((yg < 0) ? -yg : yg));
1193 *(yt++) = ((unsigned char) ((yb < 0) ? -yb : yb));
1194
1195 yr -= dry;
1196 yg -= dgy;
1197 yb -= dby;
1198 }
1199
1200 // Combine tables to create gradient
1201
1202 for (yt = ytable, y = 0; y < height; y++, yt += 3)
1203 {
1204 for (xt = xtable, x = 0; x < width; x++)
1205 {
1206 pixels[count + 2] = (unsigned char) (tr - (rsign * lmin(*(xt++), *(yt))));
1207 pixels[count + 1] = (unsigned char) (tg - (gsign * lmin(*(xt++), *(yt + 1))));
1208 pixels[count] = (unsigned char) (tb - (bsign * lmin(*(xt++), *(yt + 2))));
1209 count += 4;
1210 }
1211 }
1212}
T lmin(T a, T b)
Definition BImage.cpp:524

◆ cdgradient()

void BImage::cdgradient ( void )
private
1217{
1218 if ((height <= 2) || (width <= 2)) return;
1219
1220 // cross diagonal gradient - based on original dgradient, written by
1221 // Mosfet (mosfet@kde.org)
1222 // adapted from kde sources for Blackbox by Brad Hughes
1223
1224 float drx, dgx, dbx, dry, dgy, dby, yr = 0.0, yg = 0.0, yb = 0.0,
1225 xr = (float) from_red,
1226 xg = (float) from_green,
1227 xb = (float) from_blue;
1228
1229 UINT w = width * 2, h = height * 2, *xt, *yt, x, y, count = 0;
1230
1231 dry = drx = (float) (to_red - from_red);
1232 dgy = dgx = (float) (to_green - from_green);
1233 dby = dbx = (float) (to_blue - from_blue);
1234
1235 // Create X table
1236 drx /= w;
1237 dgx /= w;
1238 dbx /= w;
1239
1240 for (xt = (xtable + (width * 3) - 1), x = 0; x < width; x++)
1241 {
1242 *(xt--) = (unsigned char) xb;
1243 *(xt--) = (unsigned char) xg;
1244 *(xt--) = (unsigned char) xr;
1245
1246 xr += drx;
1247 xg += dgx;
1248 xb += dbx;
1249 }
1250
1251 // Create Y table
1252 dry /= h;
1253 dgy /= h;
1254 dby /= h;
1255
1256 for (yt = (ytable + (height * 3) - 1), y = 0; y < height; y++)
1257 {
1258 *(yt--) = ((unsigned char) yb);
1259 *(yt--) = ((unsigned char) yg);
1260 *(yt--) = ((unsigned char) yr);
1261
1262 yr += dry;
1263 yg += dgy;
1264 yb += dby;
1265 }
1266
1267 // Combine tables to create gradient
1268
1269 for (yt = ytable, y = 0; y < height; y++, yt += 3)
1270 {
1271 for (xt = xtable, x = 0; x < width; x++)
1272 {
1273 pixels[count + 2] = *(xt++) + *(yt);
1274 pixels[count + 1] = *(xt++) + *(yt + 1);
1275 pixels[count] = *(xt++) + *(yt + 2);
1276 count += 4;
1277 }
1278 }
1279}

Member Data Documentation

◆ width

unsigned int BImage::width
private

◆ height

unsigned int BImage::height
private

◆ xoffset

unsigned int BImage::xoffset
private

◆ yoffset

unsigned int BImage::yoffset
private

◆ padding

unsigned int BImage::padding
private

◆ buf

HDC BImage::buf
private

◆ bufbmp

HBITMAP BImage::bufbmp
private

◆ oldbuf

HBITMAP BImage::oldbuf
private

◆ solid_brush

HBRUSH BImage::solid_brush
private

◆ fillRect

RECT BImage::fillRect
private

◆ pixels

PBYTE BImage::pixels
private

◆ from_red

BYTE BImage::from_red
private

◆ from_green

BYTE BImage::from_green
private

◆ from_blue

BYTE BImage::from_blue
private

◆ to_red

BYTE BImage::to_red
private

◆ to_green

BYTE BImage::to_green
private

◆ to_blue

BYTE BImage::to_blue
private

◆ red

unsigned char* BImage::red
private

◆ green

unsigned char* BImage::green
private

◆ blue

unsigned char* BImage::blue
private

◆ xtable

unsigned int* BImage::xtable
private

◆ ytable

unsigned int* BImage::ytable
private

◆ sunken

bool BImage::sunken
private

◆ r

BYTE BImage::r
private

◆ g

BYTE BImage::g
private

◆ b

BYTE BImage::b
private

◆ rr

BYTE BImage::rr
private

◆ gg

BYTE BImage::gg
private

◆ bb

BYTE BImage::bb
private

◆ sr

int BImage::sr
private

◆ sg

int BImage::sg
private

◆ sb

int BImage::sb
private