Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/windirstat.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Schneider <oliver@assarbad.net>2015-11-15 22:55:05 +0300
committerOliver Schneider <oliver@assarbad.net>2015-11-15 22:55:05 +0300
commit5f42f5d3b026968fd79f2576d545ed899d89bee3 (patch)
tree5f01a520ed33de5c8ffc019c954ba75b873b089e /windirstat
parent88d4fcc77923037e5a9747bc24132983fa909d1d (diff)
parent57f06afdb61633745ed144a951ad8eb6de2e899c (diff)
Merging Finnbogi's WiX project
Diffstat (limited to 'windirstat')
-rw-r--r--windirstat/Controls/treemap.cpp256
-rw-r--r--windirstat/Controls/treemap.h25
-rw-r--r--windirstat/Controls/typeview.cpp4
-rw-r--r--windirstat/Dialogs/SelectDrivesDlg.cpp4
-rw-r--r--windirstat/dirstatdoc.cpp4
-rw-r--r--windirstat/item.cpp43
-rw-r--r--windirstat/item.h5
-rw-r--r--windirstat/stdafx.h3
8 files changed, 218 insertions, 126 deletions
diff --git a/windirstat/Controls/treemap.cpp b/windirstat/Controls/treemap.cpp
index 4df6958..9183e06 100644
--- a/windirstat/Controls/treemap.cpp
+++ b/windirstat/Controls/treemap.cpp
@@ -29,6 +29,8 @@
#define new DEBUG_NEW
#endif
+#define BGR(b,g,r) ((COLORREF)(((BYTE)(b)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(r))<<16)))
+
// I define the "brightness" of an rgb value as (r+b+g)/3/255.
// The EqualizeColors() method creates a palette with colors
// all having the same brightness of 0.6
@@ -47,8 +49,8 @@ double CColorSpace::GetColorBrightness(COLORREF color)
COLORREF CColorSpace::MakeBrightColor(COLORREF color, double brightness)
{
- ASSERT(brightness >= 0.0);
- ASSERT(brightness <= 1.0);
+ WEAK_ASSERT(brightness >= 0.0);
+ WEAK_ASSERT(brightness <= 1.0);
double dred = (RGB_GET_RVALUE(color) & 0xFF) / 255.0;
double dgreen = (RGB_GET_GVALUE(color) & 0xFF) / 255.0;
@@ -80,7 +82,7 @@ bool CColorSpace::Is256Colors()
void CColorSpace::NormalizeColor(int& red, int& green, int& blue)
{
- ASSERT(red + green + blue <= 3 * 255);
+ WEAK_ASSERT(red + green + blue <= 3 * 255);
if(red > 255)
{
@@ -108,14 +110,14 @@ void CColorSpace::DistributeFirst(int& first, int& second, int& third)
int h = second - 255;
second = 255;
third += h;
- ASSERT(third <= 255);
+ WEAK_ASSERT(third <= 255);
}
else if(third > 255)
{
int h = third - 255;
third = 255;
second += h;
- ASSERT(second <= 255);
+ WEAK_ASSERT(second <= 255);
}
}
@@ -222,7 +224,7 @@ CTreemap::CTreemap(Callback *callback)
void CTreemap::SetOptions(const Options *options)
{
- ASSERT(options != NULL);
+ WEAK_ASSERT(options != NULL);
m_options = *options;
// Derive normalized vector here for performance
@@ -256,7 +258,7 @@ void CTreemap::RecurseCheckTree(Item *item)
{
if(item->TmiIsLeaf())
{
- ASSERT(item->TmiGetChildrenCount() == 0);
+ WEAK_ASSERT(item->TmiGetChildrenCount() == 0);
}
else
{
@@ -268,7 +270,7 @@ void CTreemap::RecurseCheckTree(Item *item)
sum += child->TmiGetSize();
RecurseCheckTree(child);
}
- ASSERT(sum == item->TmiGetSize());
+ WEAK_ASSERT(sum == item->TmiGetSize());
}
}
#endif
@@ -314,6 +316,8 @@ void CTreemap::DrawTreemap(CDC *pdc, CRect rc, Item *root, const Options *option
return;
}
+ m_renderArea = rc;
+
if(root->TmiGetSize() > 0)
{
double surface[4];
@@ -322,7 +326,34 @@ void CTreemap::DrawTreemap(CDC *pdc, CRect rc, Item *root, const Options *option
surface[i]= 0;
}
- RecurseDrawGraph(pdc, root, rc, true, surface, m_options.height, 0);
+ // Create a temporary CDC that represents only the tree map
+ CDC dcTreeView;
+ dcTreeView.CreateCompatibleDC(pdc);
+
+ // This temporary CDC will be filled with this bitmap
+ CBitmap bmp;
+
+ // That bitmap in turn will be created from this array
+ CArray<COLORREF, COLORREF> *bitmap = new CArray<COLORREF, COLORREF>;
+ bitmap->SetSize(rc.Width() * rc.Height());
+
+ // Recursively draw the tree graph
+ RecurseDrawGraph(bitmap, root, rc, true, surface, m_options.height, 0);
+
+ // Fill the bitmap with the array
+ bmp.CreateBitmap(rc.Width(), rc.Height(), 1, 32, &(*bitmap)[0]);
+
+ // Render bitmap to the temporary CDC
+ dcTreeView.SelectObject(&bmp);
+
+ // And lastly, draw the temporary CDC to the real one
+ pdc->BitBlt(rc.TopLeft().x, rc.TopLeft().y, rc.Width(), rc.Height(), &dcTreeView, 0, 0, SRCCOPY);
+
+ // Free memory
+ bmp.DeleteObject();
+ dcTreeView.DeleteDC();
+ delete bitmap;
+
#ifdef STRONGDEBUG // slow, but finds bugs!
#ifdef _DEBUG
@@ -330,7 +361,7 @@ void CTreemap::DrawTreemap(CDC *pdc, CRect rc, Item *root, const Options *option
{
for(int y = rc.top; y < rc.bottom - m_options.grid; y++)
{
- ASSERT(FindItemByPoint(root, CPoint(x, y)) != NULL);
+ WEAK_ASSERT(FindItemByPoint(root, CPoint(x, y)) != NULL);
}
}
#endif
@@ -371,7 +402,7 @@ void CTreemap::DrawTreemapDoubleBuffered(CDC *pdc, const CRect& rc, Item *root,
CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
{
- ASSERT(item != NULL);
+ WEAK_ASSERT(item != NULL);
const CRect& rc = item->TmiGetRectangle();
if(!rc.PtInRect(point))
@@ -388,7 +419,7 @@ CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
return NULL;
}
- ASSERT(rc.PtInRect(point));
+ WEAK_ASSERT(rc.PtInRect(point));
Item *ret = NULL;
@@ -404,14 +435,14 @@ CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
}
else
{
- ASSERT(item->TmiGetSize() > 0);
- ASSERT(item->TmiGetChildrenCount() > 0);
+ WEAK_ASSERT(item->TmiGetSize() > 0);
+ WEAK_ASSERT(item->TmiGetChildrenCount() > 0);
for(int i = 0; i < item->TmiGetChildrenCount(); i++)
{
Item *child = item->TmiGetChild(i);
- ASSERT(child->TmiGetSize() > 0);
+ WEAK_ASSERT(child->TmiGetSize() > 0);
#ifdef _DEBUG
CRect rcChild(child->TmiGetRectangle());
@@ -425,7 +456,7 @@ CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
if(child->TmiGetRectangle().PtInRect(point))
{
ret = FindItemByPoint(child, point);
- ASSERT(ret != NULL);
+ WEAK_ASSERT(ret != NULL);
#ifdef STRONGDEBUG
#ifdef _DEBUG
for(i++; i < item->TmiGetChildrenCount(); i++)
@@ -440,18 +471,18 @@ CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
rcChild = child->TmiGetRectangle();
if(rcChild.left == -1)
{
- ASSERT(rcChild.top == -1);
- ASSERT(rcChild.right == -1);
- ASSERT(rcChild.bottom == -1);
+ WEAK_ASSERT(rcChild.top == -1);
+ WEAK_ASSERT(rcChild.right == -1);
+ WEAK_ASSERT(rcChild.bottom == -1);
break;
}
- ASSERT(rcChild.right >= rcChild.left);
- ASSERT(rcChild.bottom >= rcChild.top);
- ASSERT(rcChild.left >= rc.left);
- ASSERT(rcChild.right <= rc.right);
- ASSERT(rcChild.top >= rc.top);
- ASSERT(rcChild.bottom <= rc.bottom);
+ WEAK_ASSERT(rcChild.right >= rcChild.left);
+ WEAK_ASSERT(rcChild.bottom >= rcChild.top);
+ WEAK_ASSERT(rcChild.left >= rc.left);
+ WEAK_ASSERT(rcChild.right <= rc.right);
+ WEAK_ASSERT(rcChild.top >= rc.top);
+ WEAK_ASSERT(rcChild.bottom <= rc.bottom);
}
#endif
#endif
@@ -461,7 +492,7 @@ CTreemap::Item *CTreemap::FindItemByPoint(Item *item, CPoint point)
}
}
- ASSERT(ret != NULL);
+ WEAK_ASSERT(ret != NULL);
if(ret == NULL)
{
@@ -486,7 +517,31 @@ void CTreemap::DrawColorPreview(CDC *pdc, const CRect& rc, COLORREF color, const
AddRidge(rc, surface, m_options.height * m_options.scaleFactor);
- RenderRectangle(pdc, rc, surface, color);
+ m_renderArea = rc;
+
+ // Create a temporary CDC that represents only the tree map
+ CDC dcTreeView;
+ dcTreeView.CreateCompatibleDC(pdc);
+
+ // This temporary CDC will be filled with this bitmap
+ CBitmap bmp;
+
+ // That bitmap in turn will be created from this array
+ CArray<COLORREF, COLORREF> *bitmap = new CArray<COLORREF, COLORREF>;
+ bitmap->SetSize(rc.Width() * rc.Height());
+
+ // Recursively draw the tree graph
+ RenderRectangle(bitmap, CRect(0, 0, rc.Width(), rc.Height()), surface, color);
+
+ // Fill the bitmap with the array
+ bmp.CreateBitmap(rc.Width(), rc.Height(), 1, 32, &(*bitmap)[0]);
+
+ // Render bitmap to the temporary CDC
+ dcTreeView.SelectObject(&bmp);
+
+ // And lastly, draw the temporary CDC to the real one
+ pdc->BitBlt(rc.TopLeft().x, rc.TopLeft().y, rc.Width(), rc.Height(), &dcTreeView, 0, 0, SRCCOPY);
+
if(m_options.grid)
{
CPen pen(PS_SOLID, 1, m_options.gridColor);
@@ -494,10 +549,15 @@ void CTreemap::DrawColorPreview(CDC *pdc, const CRect& rc, COLORREF color, const
CSelectStockObject sobrush(pdc, NULL_BRUSH);
pdc->Rectangle(rc);
}
+
+ // Free memory
+ bmp.DeleteObject();
+ dcTreeView.DeleteDC();
+ delete bitmap;
}
void CTreemap::RecurseDrawGraph(
- CDC *pdc,
+ CArray<COLORREF, COLORREF> *bitmap,
Item *item,
const CRect& rc,
bool asroot,
@@ -506,8 +566,8 @@ void CTreemap::RecurseDrawGraph(
DWORD flags
)
{
- ASSERT(rc.Width() >= 0);
- ASSERT(rc.Height() >= 0);
+ WEAK_ASSERT(rc.Width() >= 0);
+ WEAK_ASSERT(rc.Height() >= 0);
WEAK_ASSERT(item->TmiGetSize() > 0);
@@ -542,14 +602,14 @@ void CTreemap::RecurseDrawGraph(
if(item->TmiIsLeaf())
{
- RenderLeaf(pdc, item, surface);
+ RenderLeaf(bitmap, item, surface);
}
else
{
- ASSERT(item->TmiGetChildrenCount() > 0);
- ASSERT(item->TmiGetSize() > 0);
+ WEAK_ASSERT(item->TmiGetChildrenCount() > 0);
+ WEAK_ASSERT(item->TmiGetSize() > 0);
- DrawChildren(pdc, item, surface, h, flags);
+ DrawChildren(bitmap, item, surface, h, flags);
}
}
@@ -559,7 +619,7 @@ void CTreemap::RecurseDrawGraph(
// pointers, factory methods and explicit destruction. It's not worth.
void CTreemap::DrawChildren(
- CDC *pdc,
+ CArray<COLORREF, COLORREF> *bitmap,
Item *parent,
const double *surface,
double h,
@@ -570,19 +630,19 @@ void CTreemap::DrawChildren(
{
case KDirStatStyle:
{
- KDirStat_DrawChildren(pdc, parent, surface, h, flags);
+ KDirStat_DrawChildren(bitmap, parent, surface, h, flags);
}
break;
case SequoiaViewStyle:
{
- SequoiaView_DrawChildren(pdc, parent, surface, h, flags);
+ SequoiaView_DrawChildren(bitmap, parent, surface, h, flags);
}
break;
case SimpleStyle:
{
- Simple_DrawChildren(pdc, parent, surface, h, flags);
+ Simple_DrawChildren(bitmap, parent, surface, h, flags);
}
break;
}
@@ -592,9 +652,9 @@ void CTreemap::DrawChildren(
// I learned this squarification style from the KDirStat executable.
// It's the most complex one here but also the clearest, imho.
//
-void CTreemap::KDirStat_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD /*flags*/)
+void CTreemap::KDirStat_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD /*flags*/)
{
- ASSERT(parent->TmiGetChildrenCount() > 0);
+ WEAK_ASSERT(parent->TmiGetChildrenCount() > 0);
const CRect& rc = parent->TmiGetRectangle();
@@ -608,8 +668,8 @@ void CTreemap::KDirStat_DrawChildren(CDC *pdc, Item *parent, const double *surfa
const int width = horizontalRows ? rc.Width() : rc.Height();
const int height = horizontalRows ? rc.Height() : rc.Width();
- ASSERT(width >= 0);
- ASSERT(height >= 0);
+ WEAK_ASSERT(width >= 0);
+ WEAK_ASSERT(height >= 0);
int c = 0;
double top = horizontalRows ? rc.top : rc.left;
@@ -657,11 +717,11 @@ void CTreemap::KDirStat_DrawChildren(CDC *pdc, Item *parent, const double *surfa
{
CRect test;
test.IntersectRect(parent->TmiGetRectangle(), rcChild);
- ASSERT(test == rcChild);
+ WEAK_ASSERT(test == rcChild);
}
#endif
- RecurseDrawGraph(pdc, child, rcChild, false, surface, h * m_options.scaleFactor, 0);
+ RecurseDrawGraph(bitmap, child, rcChild, false, surface, h * m_options.scaleFactor, 0);
if(lastChild)
{
@@ -678,10 +738,10 @@ void CTreemap::KDirStat_DrawChildren(CDC *pdc, Item *parent, const double *surfa
left = fRight;
}
- // This asserts due to rounding error: ASSERT(left == (horizontalRows ? rc.right : rc.bottom));
+ // This asserts due to rounding error: WEAK_ASSERT(left == (horizontalRows ? rc.right : rc.bottom));
top = fBottom;
}
- // This asserts due to rounding error: ASSERT(top == (horizontalRows ? rc.bottom : rc.right));
+ // This asserts due to rounding error: WEAK_ASSERT(top == (horizontalRows ? rc.bottom : rc.right));
}
@@ -694,8 +754,8 @@ bool CTreemap::KDirStat_ArrangeChildren(
CArray<int, int>& childrenPerRow
)
{
- ASSERT(!parent->TmiIsLeaf());
- ASSERT(parent->TmiGetChildrenCount() > 0);
+ WEAK_ASSERT(!parent->TmiIsLeaf());
+ WEAK_ASSERT(parent->TmiGetChildrenCount() > 0);
if(parent->TmiGetSize() == 0)
{
@@ -742,13 +802,13 @@ double CTreemap::KDirStat_CalcutateNextRow(Item *parent, const int nextChild, do
{
int i = 0;
static const double _minProportion = 0.4;
- ASSERT(_minProportion < 1);
+ WEAK_ASSERT(_minProportion < 1);
- ASSERT(nextChild < parent->TmiGetChildrenCount());
- ASSERT(width >= 1.0);
+ WEAK_ASSERT(nextChild < parent->TmiGetChildrenCount());
+ WEAK_ASSERT(width >= 1.0);
const double mySize = (double)parent->TmiGetSize();
- ASSERT(mySize > 0);
+ WEAK_ASSERT(mySize > 0);
ULONGLONG sizeUsed = 0;
double rowHeight = 0;
@@ -763,8 +823,8 @@ double CTreemap::KDirStat_CalcutateNextRow(Item *parent, const int nextChild, do
sizeUsed += childSize;
double virtualRowHeight = sizeUsed / mySize;
- ASSERT(virtualRowHeight > 0);
- ASSERT(virtualRowHeight <= 1);
+ WEAK_ASSERT(virtualRowHeight > 0);
+ WEAK_ASSERT(virtualRowHeight <= 1);
// Rectangle(mySize) = width * 1.0
// Rectangle(childSize) = childWidth * virtualRowHeight
@@ -774,7 +834,7 @@ double CTreemap::KDirStat_CalcutateNextRow(Item *parent, const int nextChild, do
if(childWidth / virtualRowHeight < _minProportion)
{
- ASSERT(i > nextChild); // because width >= 1 and _minProportion < 1.
+ WEAK_ASSERT(i > nextChild); // because width >= 1 and _minProportion < 1.
// For the first child we have:
// childWidth / rowHeight
// = childSize / mySize * width / rowHeight / rowHeight
@@ -816,17 +876,17 @@ double CTreemap::KDirStat_CalcutateNextRow(Item *parent, const int nextChild, do
// The classical squarification method.
//
-void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD /*flags*/)
+void CTreemap::SequoiaView_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD /*flags*/)
{
// Rest rectangle to fill
CRect remaining(parent->TmiGetRectangle());
- ASSERT(remaining.Width() > 0);
- ASSERT(remaining.Height() > 0);
+ WEAK_ASSERT(remaining.Width() > 0);
+ WEAK_ASSERT(remaining.Height() > 0);
// Size of rest rectangle
ULONGLONG remainingSize = parent->TmiGetSize();
- ASSERT(remainingSize > 0);
+ WEAK_ASSERT(remainingSize > 0);
// Scale factor
const double sizePerSquarePixel = (double)parent->TmiGetSize() / remaining.Width() / remaining.Height();
@@ -837,8 +897,8 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
// At least one child left
while(head < parent->TmiGetChildrenCount())
{
- ASSERT(remaining.Width() > 0);
- ASSERT(remaining.Height() > 0);
+ WEAK_ASSERT(remaining.Width() > 0);
+ WEAK_ASSERT(remaining.Height() > 0);
// How we divide the remaining rectangle
bool horizontal = (remaining.Width() >= remaining.Height());
@@ -848,7 +908,7 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
// Square of height in size scale for ratio formula
const double hh = (height * height) * sizePerSquarePixel;
- ASSERT(hh > 0);
+ WEAK_ASSERT(hh > 0);
// Row will be made up of child(rowBegin)...child(rowEnd - 1)
int rowBegin = head;
@@ -909,11 +969,11 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
// As the size of parent is greater than zero, the size of
// the first child must have been greater than zero, too.
- ASSERT(sum > 0);
+ WEAK_ASSERT(sum > 0);
// Width of row
int width = (horizontal ? remaining.Width() : remaining.Height());
- ASSERT(width > 0);
+ WEAK_ASSERT(width > 0);
if(sum < remainingSize)
width = (int)((double)sum / remainingSize * width);
@@ -963,15 +1023,15 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
rc.right = end;
}
- ASSERT(rc.left <= rc.right);
- ASSERT(rc.top <= rc.bottom);
+ WEAK_ASSERT(rc.left <= rc.right);
+ WEAK_ASSERT(rc.top <= rc.bottom);
- ASSERT(rc.left >= remaining.left);
- ASSERT(rc.right <= remaining.right);
- ASSERT(rc.top >= remaining.top);
- ASSERT(rc.bottom <= remaining.bottom);
+ WEAK_ASSERT(rc.left >= remaining.left);
+ WEAK_ASSERT(rc.right <= remaining.right);
+ WEAK_ASSERT(rc.top >= remaining.top);
+ WEAK_ASSERT(rc.bottom <= remaining.bottom);
- RecurseDrawGraph(pdc, parent->TmiGetChild(i), rc, false, surface, h * m_options.scaleFactor, 0);
+ RecurseDrawGraph(bitmap, parent->TmiGetChild(i), rc, false, surface, h * m_options.scaleFactor, 0);
if(lastChild)
break;
@@ -991,10 +1051,10 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
remainingSize -= sum;
- ASSERT(remaining.left <= remaining.right);
- ASSERT(remaining.top <= remaining.bottom);
+ WEAK_ASSERT(remaining.left <= remaining.right);
+ WEAK_ASSERT(remaining.top <= remaining.bottom);
- ASSERT(remainingSize >= 0);
+ WEAK_ASSERT(remainingSize >= 0);
head += (rowEnd - rowBegin);
@@ -1008,30 +1068,30 @@ void CTreemap::SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *su
break;
}
}
- ASSERT(remainingSize == 0);
- ASSERT(remaining.left == remaining.right || remaining.top == remaining.bottom);
+ WEAK_ASSERT(remainingSize == 0);
+ WEAK_ASSERT(remaining.left == remaining.right || remaining.top == remaining.bottom);
}
// No squarification. Children are arranged alternately horizontally and vertically.
//
-void CTreemap::Simple_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD flags)
+void CTreemap::Simple_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD flags)
{
#if 1
- ASSERT(0); // Not used in WinDirStat.
+ WEAK_ASSERT(0); // Not used in WinDirStat.
- pdc; parent; surface; h; flags;
+ bitmap; parent; surface; h; flags;
#else
- ASSERT(parent->TmiGetChildrenCount() > 0);
- ASSERT(parent->TmiGetSize() > 0);
+ WEAK_ASSERT(parent->TmiGetChildrenCount() > 0);
+ WEAK_ASSERT(parent->TmiGetSize() > 0);
const CRect& rc = parent->TmiGetRectangle();
bool horizontal = (flags == 0);
int width = horizontal ? rc.Width() : rc.Height();
- ASSERT(width >= 0);
+ WEAK_ASSERT(width >= 0);
double fBegin = horizontal ? rc.left : rc.top;
int veryEnd = horizontal ? rc.right : rc.bottom;
@@ -1052,8 +1112,8 @@ void CTreemap::Simple_DrawChildren(CDC *pdc, Item *parent, const double *surface
int begin = (int)fBegin;
int end = (int)fEnd;
- ASSERT(begin <= end);
- ASSERT(end <= veryEnd);
+ WEAK_ASSERT(begin <= end);
+ WEAK_ASSERT(end <= veryEnd);
CRect rcChild;
if(horizontal)
@@ -1072,7 +1132,7 @@ void CTreemap::Simple_DrawChildren(CDC *pdc, Item *parent, const double *surface
}
RecurseDrawGraph(
- pdc,
+ bitmap,
parent->TmiGetChild(i),
rcChild,
false,
@@ -1103,7 +1163,7 @@ bool CTreemap::IsCushionShading()
&& m_options.scaleFactor > 0.0;
}
-void CTreemap::RenderLeaf(CDC *pdc, Item *item, const double *surface)
+void CTreemap::RenderLeaf(CArray<COLORREF, COLORREF> *bitmap, Item *item, const double *surface)
{
CRect rc = item->TmiGetRectangle();
@@ -1117,10 +1177,10 @@ void CTreemap::RenderLeaf(CDC *pdc, Item *item, const double *surface)
}
}
- RenderRectangle(pdc, rc, surface, item->TmiGetGraphColor());
+ RenderRectangle(bitmap, rc, surface, item->TmiGetGraphColor());
}
-void CTreemap::RenderRectangle(CDC *pdc, const CRect& rc, const double *surface, DWORD color)
+void CTreemap::RenderRectangle(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, const double *surface, DWORD color)
{
double brightness = m_options.brightness;
@@ -1145,15 +1205,15 @@ void CTreemap::RenderRectangle(CDC *pdc, const CRect& rc, const double *surface,
if(IsCushionShading())
{
- DrawCushion(pdc, rc, surface, color, brightness);
+ DrawCushion(bitmap, rc, surface, color, brightness);
}
else
{
- DrawSolidRect(pdc, rc, color, brightness);
+ DrawSolidRect(bitmap, rc, color, brightness);
}
}
-void CTreemap::DrawSolidRect(CDC *pdc, const CRect& rc, COLORREF col, double brightness)
+void CTreemap::DrawSolidRect(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, COLORREF col, double brightness)
{
int red = RGB_GET_RVALUE(col);
int green = RGB_GET_GVALUE(col);
@@ -1167,10 +1227,14 @@ void CTreemap::DrawSolidRect(CDC *pdc, const CRect& rc, COLORREF col, double bri
CColorSpace::NormalizeColor(red, green, blue);
- pdc->FillSolidRect(rc, RGB(red, green, blue));
+ for (int iy = rc.top; iy < rc.bottom; iy++)
+ for (int ix = rc.left; ix < rc.right; ix++)
+ {
+ (*bitmap)[ix + iy * m_renderArea.Width()] = BGR(blue, green, red);
+ }
}
-void CTreemap::DrawCushion(CDC *pdc, const CRect& rc, const double *surface, COLORREF col, double brightness)
+void CTreemap::DrawCushion(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, const double *surface, COLORREF col, double brightness)
{
// Cushion parameters
const double Ia = m_options.ambientLight;
@@ -1200,7 +1264,7 @@ void CTreemap::DrawCushion(CDC *pdc, const CRect& rc, const double *surface, COL
}
pixel += Ia;
- ASSERT(pixel <= 1.0);
+ WEAK_ASSERT(pixel <= 1.0);
// Now, pixel is the brightness of the pixel, 0...1.0.
@@ -1221,7 +1285,7 @@ void CTreemap::DrawCushion(CDC *pdc, const CRect& rc, const double *surface, COL
CColorSpace::NormalizeColor(red, green, blue);
// ... and set!
- pdc->SetPixel(ix, iy, RGB(red, green, blue));
+ (*bitmap)[ix + iy * m_renderArea.Width()] = BGR(blue, green, red);
}
}
@@ -1248,7 +1312,7 @@ void CTreemap::AddRidge(const CRect& rc, double *surface, double h)
int width = rc.Width();
int height = rc.Height();
- ASSERT(width > 0 && height > 0);
+ WEAK_ASSERT(width > 0 && height > 0);
double h4 = 4 * h;
diff --git a/windirstat/Controls/treemap.h b/windirstat/Controls/treemap.h
index 046bf61..505289f 100644
--- a/windirstat/Controls/treemap.h
+++ b/windirstat/Controls/treemap.h
@@ -72,7 +72,7 @@ public:
// If you prefer to use the getHead()/getNext() pattern rather
// than using an array for the children, you will have to
// rewrite CTreemap.
- //
+ //
class Item
{
public:
@@ -142,7 +142,7 @@ public:
void SetLightSourceYPercent(int n) { lightSourceY = n / 100.0; }
void SetLightSourcePoint(CPoint pt) { SetLightSourceXPercent(pt.x); SetLightSourceYPercent(pt.y); }
- int RoundDouble(double d) { return signum(d) * (int)(abs(d) + 0.5); }
+ int RoundDouble(double d) { return signum(d) * (int)(fabs(d) + 0.5); }
};
public:
@@ -187,7 +187,7 @@ public:
protected:
// The recursive drawing function
void RecurseDrawGraph(
- CDC *pdc,
+ CArray<COLORREF, COLORREF> *bitmap,
Item *item,
const CRect& rc,
bool asroot,
@@ -198,7 +198,7 @@ protected:
// This function switches to KDirStat-, SequoiaView- or Simple_DrawChildren
void DrawChildren(
- CDC *pdc,
+ CArray<COLORREF, COLORREF> *bitmap,
Item *parent,
const double *surface,
double h,
@@ -206,15 +206,15 @@ protected:
);
// KDirStat-like squarification
- void KDirStat_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD flags);
+ void KDirStat_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD flags);
bool KDirStat_ArrangeChildren(Item *parent, CArray<double, double>& childWidth, CArray<double, double>& rows, CArray<int, int>& childrenPerRow);
double KDirStat_CalcutateNextRow(Item *parent, const int nextChild, double width, int& childrenUsed, CArray<double, double>& childWidth);
// Classical SequoiaView-like squarification
- void SequoiaView_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD flags);
+ void SequoiaView_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD flags);
// No squarification (simple style, not used in WinDirStat)
- void Simple_DrawChildren(CDC *pdc, Item *parent, const double *surface, double h, DWORD flags);
+ void Simple_DrawChildren(CArray<COLORREF, COLORREF> *bitmap, Item *parent, const double *surface, double h, DWORD flags);
// Sets brightness to a good value, if system has only 256 colors
void SetBrightnessFor256();
@@ -223,16 +223,17 @@ protected:
bool IsCushionShading();
// Leaves space for grid and then calls RenderRectangle()
- void RenderLeaf(CDC *pdc, Item *item, const double *surface);
+ void RenderLeaf(CArray<COLORREF, COLORREF> *bitmap, Item *item, const double *surface);
// Either calls DrawCushion() or DrawSolidRect()
- void RenderRectangle(CDC *pdc, const CRect& rc, const double *surface, DWORD color);
+ void RenderRectangle(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, const double *surface, DWORD color);
+ // void RenderRectangle(CDC *pdc, const CRect& rc, const double *surface, DWORD color);
// Draws the surface using SetPixel()
- void DrawCushion(CDC *pdc, const CRect& rc, const double *surface, COLORREF col, double brightness);
+ void DrawCushion(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, const double *surface, COLORREF col, double brightness);
// Draws the surface using FillSolidRect()
- void DrawSolidRect(CDC *pdc, const CRect& rc, COLORREF col, double brightness);
+ void DrawSolidRect(CArray<COLORREF, COLORREF> *bitmap, const CRect& rc, COLORREF col, double brightness);
// Adds a new ridge to surface
static void AddRidge(const CRect& rc, double *surface, double h);
@@ -242,6 +243,8 @@ protected:
static const COLORREF _defaultCushionColors[]; // Standard palette for WinDirStat
static const COLORREF _defaultCushionColors256[]; // Palette for 256-colors mode
+ CRect m_renderArea;
+
Options m_options; // Current options
double m_Lx; // Derived parameters
double m_Ly;
diff --git a/windirstat/Controls/typeview.cpp b/windirstat/Controls/typeview.cpp
index 756bd7e..9b09372 100644
--- a/windirstat/Controls/typeview.cpp
+++ b/windirstat/Controls/typeview.cpp
@@ -182,13 +182,13 @@ int CExtensionListControl::CListItem::Compare(const CSortingListItem *baseOther,
case COL_COLOR:
case COL_BYTES:
{
- r = signum(m_record.bytes - other->m_record.bytes);
+ r = usignum(m_record.bytes, other->m_record.bytes);
}
break;
case COL_FILES:
{
- r = signum(m_record.files - other->m_record.files);
+ r = usignum(m_record.files, other->m_record.files);
}
break;
diff --git a/windirstat/Dialogs/SelectDrivesDlg.cpp b/windirstat/Dialogs/SelectDrivesDlg.cpp
index 7232211..7b23e21 100644
--- a/windirstat/Dialogs/SelectDrivesDlg.cpp
+++ b/windirstat/Dialogs/SelectDrivesDlg.cpp
@@ -166,12 +166,12 @@ int CDriveItem::Compare(const CSortingListItem *baseOther, int subitem) const
break;
case COL_TOTAL:
{
- r = signum(m_totalBytes - other->m_totalBytes);
+ r = usignum(m_totalBytes, other->m_totalBytes);
}
break;
case COL_FREE:
{
- r = signum(m_freeBytes - other->m_freeBytes);
+ r = usignum(m_freeBytes, other->m_freeBytes);
}
break;
case COL_GRAPH:
diff --git a/windirstat/dirstatdoc.cpp b/windirstat/dirstatdoc.cpp
index 01277ec..dee3ede 100644
--- a/windirstat/dirstatdoc.cpp
+++ b/windirstat/dirstatdoc.cpp
@@ -749,6 +749,8 @@ void CDirstatDoc::RebuildExtensionData()
CWaitCursor wc;
m_extensionData.RemoveAll();
+ // 2048 is a rough estimate for amount of different extensions
+ m_extensionData.InitHashTable(2048);
m_rootItem->RecurseCollectExtensionData(&m_extensionData);
CStringArray sortedExtensions;
@@ -808,7 +810,7 @@ int __cdecl CDirstatDoc::_compareExtensions(const void *item1, const void *item2
SExtensionRecord r2;
VERIFY(_pqsortExtensionData->Lookup(*ext1, r1));
VERIFY(_pqsortExtensionData->Lookup(*ext2, r2));
- return signum(r2.bytes - r1.bytes);
+ return usignum(r2.bytes, r1.bytes);
}
void CDirstatDoc::SetWorkingItemAncestor(CItem *item)
diff --git a/windirstat/item.cpp b/windirstat/item.cpp
index 50452d9..d788cf8 100644
--- a/windirstat/item.cpp
+++ b/windirstat/item.cpp
@@ -55,6 +55,7 @@ CItem::CItem(ITEMTYPE type, LPCTSTR name, bool dontFollow)
, m_readJobs(0)
, m_attributes(0)
{
+ m_etype = (ITEMTYPE)(m_type & ~ITF_FLAGS); // returned by GetType
if(GetType() == IT_FILE || dontFollow || GetType() == IT_FREESPACE || GetType() == IT_UNKNOWN || GetType() == IT_MYCOMPUTER)
{
SetReadJobDone();
@@ -277,7 +278,7 @@ int CItem::CompareSibling(const CTreeListItem *tlib, int subitem) const
case COL_SUBTREEPERCENTAGE:
if(MustShowReadJobs())
{
- r = signum(m_readJobs - other->m_readJobs);
+ r = usignum(m_readJobs, other->m_readJobs);
}
else
{
@@ -293,25 +294,25 @@ int CItem::CompareSibling(const CTreeListItem *tlib, int subitem) const
case COL_SUBTREETOTAL:
{
- r = signum(GetSize() - other->GetSize());
+ r = usignum(GetSize(), other->GetSize());
}
break;
case COL_ITEMS:
{
- r = signum(GetItemsCount() - other->GetItemsCount());
+ r = usignum(GetItemsCount(), other->GetItemsCount());
}
break;
case COL_FILES:
{
- r = signum(GetFilesCount() - other->GetFilesCount());
+ r = usignum(GetFilesCount(), other->GetFilesCount());
}
break;
case COL_SUBDIRS:
{
- r = signum(GetSubdirsCount() - other->GetSubdirsCount());
+ r = usignum(GetSubdirsCount(), other->GetSubdirsCount());
}
break;
@@ -829,7 +830,7 @@ double CItem::GetFraction() const
ITEMTYPE CItem::GetType() const
{
- return (ITEMTYPE)(m_type & ~ITF_FLAGS);
+ return m_etype;
}
bool CItem::IsRootItem() const
@@ -909,20 +910,27 @@ CString CItem::GetName() const
CString CItem::GetExtension() const
{
+ if (m_extension_cached)
+ return m_extension;
+
CString ext;
+ CString name = GetName();
+
switch (GetType())
{
case IT_FILE:
{
- int i = GetName().ReverseFind(wds::chrDot);
+ int i = name.ReverseFind(wds::chrDot);
if(i == -1)
{
- ext = _T(".");
+ ext = L".";
}
else
{
- ext = GetName().Mid(i);
+ // Faster than name.Mid(i);
+ LPCTSTR alpha = static_cast<LPCTSTR>(name);
+ ext = &alpha[i];
}
ext.MakeLower();
break;
@@ -930,7 +938,7 @@ CString CItem::GetExtension() const
case IT_FREESPACE:
case IT_UNKNOWN:
{
- ext = GetName();
+ ext = name;
}
break;
@@ -938,6 +946,9 @@ CString CItem::GetExtension() const
ASSERT(0);
}
+ m_extension = ext;
+ m_extension_cached = true;
+
return ext;
}
@@ -1135,6 +1146,11 @@ void CItem::DoSomeWork(DWORD ticks)
}
if(GetType() == IT_DRIVE || GetType() == IT_DIRECTORY || GetType() == IT_MYCOMPUTER)
{
+
+ // <HACK! IsDone() is set after first pass with no decend into dirs
+ UpwardSetUndone();
+ // HACK>
+
ASSERT(IsReadJobDone());
if(IsDone())
{
@@ -1600,9 +1616,10 @@ void CItem::RecurseCollectExtensionData(CExtensionData *ed)
{
GetWDSApp()->PeriodicalUpdateRamUsage();
- if(IsLeaf(GetType()))
+ auto type = GetType();
+ if(IsLeaf(type))
{
- if(GetType() == IT_FILE)
+ if(type == IT_FILE)
{
CString ext = GetExtension();
SExtensionRecord r;
@@ -1638,7 +1655,7 @@ int __cdecl CItem::_compareBySize(const void *p1, const void *p2)
// TODO: Use 2nd sort column (as set in our TreeListView?)
- return signum(size2 - size1); // biggest first
+ return usignum(size2, size1); // biggest first
}
ULONGLONG CItem::GetProgressRangeMyComputer() const
diff --git a/windirstat/item.h b/windirstat/item.h
index e6e748f..55f2bba 100644
--- a/windirstat/item.h
+++ b/windirstat/item.h
@@ -62,7 +62,7 @@ enum ITEMTYPE
};
// Whether an item type is a leaf type
-inline bool IsLeaf(ITEMTYPE t) { return t == IT_FILE || t == IT_FREESPACE || t == IT_UNKNOWN; }
+inline bool IsLeaf(ITEMTYPE t) { return ((t == IT_FILE) | (t == IT_FREESPACE) | (t == IT_UNKNOWN)); }
// Compare FILETIMEs
inline bool operator< (const FILETIME& t1, const FILETIME& t2)
@@ -220,7 +220,10 @@ private:
void DrivePacman();
ITEMTYPE m_type; // Indicates our type. See ITEMTYPE.
+ ITEMTYPE m_etype;
CString m_name; // Display name
+ mutable CString m_extension; // Cache of extension (it's used often)
+ mutable bool m_extension_cached = false;
ULONGLONG m_size; // OwnSize, if IT_FILE or IT_FREESPACE, or IT_UNKNOWN; SubtreeTotal else.
ULONGLONG m_files; // # Files in subtree
ULONGLONG m_subdirs; // # Folder in subtree
diff --git a/windirstat/stdafx.h b/windirstat/stdafx.h
index 1514704..8c34010 100644
--- a/windirstat/stdafx.h
+++ b/windirstat/stdafx.h
@@ -78,6 +78,9 @@
template<class T> int signum(T x) { return (x) < 0 ? -1 : (x) == 0 ? 0 : 1; }
+/// signum function for unsigned numbers.
+template<class T> int usignum(T x, T y) { return (x) < (y) ? -1 : (x) == (y) ? 0 : 1; }
+
#define WEAK_ASSERT /##/ ASSERT
#endif // __WDS_STDAFX_H__