diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/nw/svcdlls/nwwks/client/drawpie.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/nw/svcdlls/nwwks/client/drawpie.c')
-rw-r--r-- | private/nw/svcdlls/nwwks/client/drawpie.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/private/nw/svcdlls/nwwks/client/drawpie.c b/private/nw/svcdlls/nwwks/client/drawpie.c new file mode 100644 index 000000000..2bb4f8e92 --- /dev/null +++ b/private/nw/svcdlls/nwwks/client/drawpie.c @@ -0,0 +1,240 @@ +#include <windows.h> +#include "drawpie.h" + +#ifdef WIN32 +#define MoveTo(_hdc,_x,_y) MoveToEx(_hdc, _x, _y, NULL) +#endif // WIN32 + + +int NEAR IntSqrt(unsigned long dwNum) +{ + // We will keep shifting dwNum left and look at the top two bits. + + // initialize sqrt and remainder to 0. + DWORD dwSqrt = 0, dwRemain = 0, dwTry; + int i; + + // We iterate 16 times, once for each pair of bits. + for (i=0; i<16; ++i) + { + // Mask off the top two bits of dwNum and rotate them into the + // bottom of the remainder + dwRemain = (dwRemain<<2) | (dwNum>>30); + + // Now we shift the sqrt left; next we'll determine whether the + // new bit is a 1 or a 0. + dwSqrt <<= 1; + + // This is where we double what we already have, and try a 1 in + // the lowest bit. + dwTry = dwSqrt*2 + 1; + + if (dwRemain >= dwTry) + { + // The remainder was big enough, so subtract dwTry from + // the remainder and tack a 1 onto the sqrt. + dwRemain -= dwTry; + dwSqrt |= 0x01; + } + + // Shift dwNum to the left by 2 so we can work on the next few + // bits. + dwNum <<= 2; + } + + return(dwSqrt); +} + + + +VOID NEAR DrawPie(HDC hDC, LPCRECT lprcItem, UINT uPctX10, BOOL TrueZr100, + UINT uOffset, const COLORREF FAR *lpColors) +{ + int cx, cy, rx, ry, x, y; + int uQPctX10; + RECT rcItem; + HRGN hEllRect, hEllipticRgn, hRectRgn; + HBRUSH hBrush, hOldBrush; + HPEN hPen, hOldPen; + + rcItem = *lprcItem; + rcItem.left = lprcItem->left; + rcItem.top = lprcItem->top; + rcItem.right = lprcItem->right - rcItem.left; + rcItem.bottom = lprcItem->bottom - rcItem.top - uOffset; + + rx = rcItem.right / 2; + cx = rcItem.left + rx; + ry = rcItem.bottom / 2; + cy = rcItem.top + ry; + if (rx<=10 || ry<=10) + { + return; + } + + rcItem.right = rcItem.left+2*rx; + rcItem.bottom = rcItem.top+2*ry; + + if (uPctX10 > 1000) + { + uPctX10 = 1000; + } + + /* Translate to first quadrant of a Cartesian system + */ + uQPctX10 = (uPctX10 % 500) - 250; + if (uQPctX10 < 0) + { + uQPctX10 = -uQPctX10; + } + + /* Calc x and y. I am trying to make the area be the right percentage. + ** I don't know how to calculate the area of a pie slice exactly, so I + ** approximate it by using the triangle area instead. + */ + if (uQPctX10 < 120) + { + x = IntSqrt(((DWORD)rx*(DWORD)rx*(DWORD)uQPctX10*(DWORD)uQPctX10) + /((DWORD)uQPctX10*(DWORD)uQPctX10+(250L-(DWORD)uQPctX10)*(250L-(DWORD)uQPctX10))); + + y = IntSqrt(((DWORD)rx*(DWORD)rx-(DWORD)x*(DWORD)x)*(DWORD)ry*(DWORD)ry/((DWORD)rx*(DWORD)rx)); + } + else + { + y = IntSqrt((DWORD)ry*(DWORD)ry*(250L-(DWORD)uQPctX10)*(250L-(DWORD)uQPctX10) + /((DWORD)uQPctX10*(DWORD)uQPctX10+(250L-(DWORD)uQPctX10)*(250L-(DWORD)uQPctX10))); + + x = IntSqrt(((DWORD)ry*(DWORD)ry-(DWORD)y*(DWORD)y)*(DWORD)rx*(DWORD)rx/((DWORD)ry*(DWORD)ry)); + } + + /* Switch on the actual quadrant + */ + switch (uPctX10 / 250) + { + case 1: + y = -y; + break; + + case 2: + break; + + case 3: + x = -x; + break; + + default: // case 0 and case 4 + x = -x; + y = -y; + break; + } + + /* Now adjust for the center. + */ + x += cx; + y += cy; + + /* Draw the shadows using regions (to reduce flicker). + */ + hEllipticRgn = CreateEllipticRgnIndirect(&rcItem); + OffsetRgn(hEllipticRgn, 0, uOffset); + hEllRect = CreateRectRgn(rcItem.left, cy, rcItem.right, cy+uOffset); + hRectRgn = CreateRectRgn(0, 0, 0, 0); + CombineRgn(hRectRgn, hEllipticRgn, hEllRect, RGN_OR); + OffsetRgn(hEllipticRgn, 0, -(int)uOffset); + CombineRgn(hEllRect, hRectRgn, hEllipticRgn, RGN_DIFF); + + /* Always draw the whole area in the free shadow/ + */ + hBrush = CreateSolidBrush(lpColors[DP_FREESHADOW]); + if (hBrush) + { + FillRgn(hDC, hEllRect, hBrush); + DeleteObject(hBrush); + } + + /* Draw the used shadow only if the disk is at least half used. + */ + if (uPctX10>500 && (hBrush=CreateSolidBrush(lpColors[DP_USEDSHADOW]))!=NULL) + { + DeleteObject(hRectRgn); + hRectRgn = CreateRectRgn(x, cy, rcItem.right, lprcItem->bottom); + CombineRgn(hEllipticRgn, hEllRect, hRectRgn, RGN_AND); + FillRgn(hDC, hEllipticRgn, hBrush); + DeleteObject(hBrush); + } + + DeleteObject(hRectRgn); + DeleteObject(hEllipticRgn); + DeleteObject(hEllRect); + + hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME)); + hOldPen = SelectObject(hDC, hPen); + + if((uPctX10 < 100) && (cy == y)) + { + hBrush = CreateSolidBrush(lpColors[DP_FREECOLOR]); + hOldBrush = SelectObject(hDC, hBrush); + if((TrueZr100 == FALSE) || (uPctX10 != 0)) + { + Pie(hDC, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, + rcItem.left, cy, x, y); + } + else + { + Ellipse(hDC, rcItem.left, rcItem.top, rcItem.right, + rcItem.bottom); + } + } + else if((uPctX10 > (1000 - 100)) && (cy == y)) + { + hBrush = CreateSolidBrush(lpColors[DP_USEDCOLOR]); + hOldBrush = SelectObject(hDC, hBrush); + if((TrueZr100 == FALSE) || (uPctX10 != 1000)) + { + Pie(hDC, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, + rcItem.left, cy, x, y); + } + else + { + Ellipse(hDC, rcItem.left, rcItem.top, rcItem.right, + rcItem.bottom); + } + } + else + { + hBrush = CreateSolidBrush(lpColors[DP_USEDCOLOR]); + hOldBrush = SelectObject(hDC, hBrush); + + Ellipse(hDC, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom); + SelectObject(hDC, hOldBrush); + DeleteObject(hBrush); + + hBrush = CreateSolidBrush(lpColors[DP_FREECOLOR]); + hOldBrush = SelectObject(hDC, hBrush); + Pie(hDC, rcItem.left, rcItem.top, rcItem.right, rcItem.bottom, + rcItem.left, cy, x, y); + } + SelectObject(hDC, hOldBrush); + DeleteObject(hBrush); + + /* Do not draw the lines if the %age is truely 0 or 100 (completely + ** empty disk or completly full disk) + */ + if((TrueZr100 == FALSE) || ((uPctX10 != 0) && (uPctX10 != 1000))) + { + Arc(hDC, rcItem.left, rcItem.top+uOffset, rcItem.right, rcItem.bottom+uOffset, + rcItem.left, cy+uOffset, rcItem.right, cy+uOffset-1); + MoveTo(hDC, rcItem.left, cy); + LineTo(hDC, rcItem.left, cy+uOffset); + MoveTo(hDC, rcItem.right-1, cy); + LineTo(hDC, rcItem.right-1, cy+uOffset); + + if (uPctX10 > 500) + { + MoveTo(hDC, x, y); + LineTo(hDC, x, y+uOffset); + } + } + SelectObject(hDC, hOldPen); + DeleteObject(hPen); +} |