diff -r 8e12a575a9b5 -r 15296fd0af4a sysperfana/heapanalyser/Libraries/UI/HeapCtrlLib/Utilities/HeapCellLargestRectangleCalculator.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/heapanalyser/Libraries/UI/HeapCtrlLib/Utilities/HeapCellLargestRectangleCalculator.cs Tue Jun 15 12:47:20 2010 +0300 @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* - Neither the name of Nokia Corporation nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +using System; +using System.Drawing; +using HeapLib.Cells; + +namespace HeapCtrlLib.Utilities +{ + public class HeapCellLargestRectangleCalculator + { + #region Constructors & destructor + public HeapCellLargestRectangleCalculator( HeapRenderingNavigator aNavigator ) + : this( aNavigator, 0 ) + { + } + + public HeapCellLargestRectangleCalculator( HeapRenderingNavigator aNavigator, int aStartingBoxNumber ) + { + aNavigator.iNavBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavBegin( Navigator_NavBegin ); + aNavigator.iNavEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavEnd( Navigator_NavEnd ); + aNavigator.iNavHeapCellBegin += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellBegin( Navigator_NavHeapCellBegin ); + aNavigator.iNavHeapCellEnd += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavHeapCellEnd( Navigator_NavHeapCellEnd ); + aNavigator.iNavNewColumn += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewColumn( Navigator_NavNewColumn ); + aNavigator.iNavNewRowBody += new HeapCtrlLib.Utilities.HeapRenderingNavigator.NavNewRowBody( Navigator_NavNewRowBody ); + // + iStartingBoxNumber = aStartingBoxNumber; + } + #endregion + + #region API + #endregion + + #region Properties + public Rectangle Rectangle + { + get { return new Rectangle( iPosition, iSize ); } + } + + public int NumberOfContinuousBoxes + { + get { return iMaxRunLength; } + } + #endregion + + #region Navigator call backs + public void Navigator_NavBegin() + { + } + + public void Navigator_NavEnd() + { + } + + public void Navigator_NavHeapCellBegin( HeapCell aCell, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) + { + CaptureStart( aPosition, aBoxSize, aPadding ); + } + + public void Navigator_NavHeapCellEnd( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) + { + } + + public void Navigator_NavNewRowBody( HeapCellMetaData aMetaData, uint aAddress, Point aPosition, Size aDimensions, Size aBoxSize, Size aPadding ) + { + if ( aAddress == 0x700144 ) + { int x = 0; x++; } + + if ( !iFoundMaximumSize ) + { + if ( aMetaData.CellRowIndex == 1 ) + { + // If the last row was just a few items and this second row has + // more (or it is a complete row) then we start the tracing again + // from the beginning. + int remaining = aMetaData.RemainingBoxes; + if ( remaining > iMaxRunLength ) + { + // Reset - this row is longer + if ( iMaxRunLength < aDimensions.Width ) + { + iMaxRunLength = 0; + iPosition = aPosition; + iSize = new Size( 0, aBoxSize.Height + aPadding.Height ); // aBoxSize + aPadding; + } + else + { + iSize.Width = 0; + iSize.Height += aBoxSize.Height + aPadding.Height; + } + } + else + { + iFoundMaximumSize = true; + } + } + else if ( aMetaData.RemainingBoxes > aDimensions.Width ) + { + iSize.Width = 0; + iSize.Height += aBoxSize.Height + aPadding.Height; + } + else + { + iFoundMaximumSize = true; + } + } + } + + public void Navigator_NavNewColumn( HeapCell aCell, HeapCellMetaData aMetaData, uint aAddress, Point aPixelPos, Point aBoxPos, Size aDimensions, Size aBoxSize, Size aPadding ) + { + if ( aCell.Address == 0x700144 ) + { int x=0; x++; } + + if ( !iFoundMaximumSize ) + { + // If we must exclude the first box from our rectangle calculations, + // then begin the capture process again. + if ( aMetaData.CellBoxIndex == iStartingBoxNumber ) + { + CaptureStart( aPixelPos, aBoxSize, aPadding ); + } + // + ++iMaxRunLength; + iSize.Width += aBoxSize.Width + aPadding.Width; + } + } + #endregion + + #region Internal methods + private void CaptureStart( Point aPosition, Size aBoxSize, Size aPadding ) + { + iFoundMaximumSize = false; + iPosition = aPosition; + iMaxRunLength = 0; + iSize = new Size( 0, aBoxSize.Height + aPadding.Height ); + } + #endregion + + #region Data members + private readonly int iStartingBoxNumber; + private bool iFoundMaximumSize = false; + private int iMaxRunLength = 0; + private Size iSize = new Size(); + private Point iPosition = new Point(); + #endregion + } +}