707// This emulates the Mac smarts for painting rects intelligently. This is very
708// important for us, since we double buffer based off dirty rects.
709static void getUpdateRects(HRGN region, const IntRect& dirtyRect, Vector<IntRect>& rects)
710{
711 ASSERT_ARG(region, region);
712
713 const int cRectThreshold = 10;
714 const float cWastedSpaceThreshold = 0.75f;
715
716 rects.clear();
717
718 DWORD regionDataSize = GetRegionData(region, sizeof(RGNDATA), NULL);
719 if (!regionDataSize) {
720 rects.append(dirtyRect);
721 return;
722 }
723
724 Vector<unsigned char> buffer(regionDataSize);
725 RGNDATA* regionData = reinterpret_cast<RGNDATA*>(buffer.data());
726 GetRegionData(region, regionDataSize, regionData);
727 if (regionData->rdh.nCount > cRectThreshold) {
728 rects.append(dirtyRect);
729 return;
730 }
731
732 double singlePixels = 0.0;
733 unsigned i;
734 RECT* rect;
735 for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
736 singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);
737
738 double unionPixels = dirtyRect.width() * dirtyRect.height();
739 double wastedSpace = 1.0 - (singlePixels / unionPixels);
740 if (wastedSpace <= cWastedSpaceThreshold) {
741 rects.append(dirtyRect);
742 return;
743 }
744
745 for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
746 rects.append(*rect);
747}
748