Applied patch 1, to provide a syborg specific minigui oby file.
Need to compare this with the "stripped" version currently in the tree.
This supplied version applies for Nokia builds, but need to repeat the
test for SF builds to see if pruning is needed, or if the file needs to
be device-specific.
// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
#include <e32def.h>
#include "regionextend.h"
//Only call this if certain neither rectangle is empty.
//Region rectangles are always non-empty
inline /*static*/
TRegionExtend::TOverlapFlags TestDifferenceNotEmpty(const TRect& aThis,const TRect& aThat)
{
struct SubAdd
{
inline static TRegionExtend::TOverlapFlags Conv(TInt delta)
{ //returns sub, exact or add for delta of each edge pair
//neg --> +1 //pos --> +2 //zero ==> 0
return TRegionExtend::TOverlapFlags(
((delta>>31)&1) +(((-delta)>>30)&2) );
}
};
//could use SubAdd for this if...
if ( aThis.iTl.iX>=aThat.iBr.iX
|| aThis.iTl.iY>=aThat.iBr.iY
|| aThat.iTl.iX>=aThis.iBr.iX
|| aThat.iTl.iY>=aThis.iBr.iY
)
return TRegionExtend::TOverlapFlags(TRegionExtend::EDiffers|TRegionExtend::ENoIntersect);
TInt subAdd=( SubAdd::Conv(aThis.iTl.iX-aThat.iTl.iX)
| SubAdd::Conv(aThis.iTl.iY-aThat.iTl.iY)
| SubAdd::Conv(aThat.iBr.iX-aThis.iBr.iX)
| SubAdd::Conv(aThat.iBr.iY-aThis.iBr.iY)
);
return
TRegionExtend::TOverlapFlags(subAdd);
}
/** Calc total area of a list of non-intersecting rectangles (ie a region)
* @param aThisRects the array of rectangles
* @param aThisCount the number in the array
*/
inline TUint RectListArea(const TRect* aThisRects,TInt aThisCount)
{
TInt thisArea=0;
for (TInt stepThis=aThisCount-1;stepThis>=0;stepThis--)
{
TSize size=aThisRects[stepThis].Size();
__ASSERT_DEBUG((size.iWidth|size.iHeight)<32768,User::Panic(_L("TRegionExtend"),4003));
thisArea+=size.iWidth*size.iHeight;
}
return thisArea;
}
/** Returns the result code flag based on the calculated intersection of two areas
* The intersection is always less than or equal to this and that.
* @param aThisArea Start area
* @param aIntersectArea Intersection
* @param aThatArea Final area
* @return
* - EDiffers if both this and that differ from intersect
* - EExact if both this and that are same as intersect
* - ESub if only that is same as intersect, so this is bigger
* - EAdd if only this is same as intersect, so that is bigger
*
**/
inline TRegionExtend::TOverlapFlags AreaDiffResults(TUint aThisArea,TUint aIntersectArea,TUint aThatArea)
{
if (aThisArea>aIntersectArea)
if (aThatArea>aIntersectArea)
return TRegionExtend::EDiffers;
else
return TRegionExtend::ESub;
else
if (aThatArea>aIntersectArea)
return TRegionExtend::EAdd;
else
return TRegionExtend::EExact;
}
/** Calculates the intersection area of one rectangle with an array of non intersecting rectangles
* It is presumed that the caller will loop through all the cells of a target region,
* repeating this call for a source region, so we can add an extra optimisation
* to avoid revisiting any source rectangles that have been consumed completely in later passes.
* The simplest test is that the source cell is wholy inside the target rect.
* The simplest record is a bit field, but that only works up to 32 elements, then will not optimise further elements.
* @param aThisCount num elements in rect array
* @param aThisRects array of rectangles
* @param aThatRect intersecting rectangle
* @param aOptimiseThisBits record of elements of rect aray that have been fully consumed
* @return total intersection area
**/
inline TUint TestDifferenceRegionInnerLoop(TInt aThisCount,const TRect* aThisRects,TRect& aThatRect,TUint& aOptimiseThisBits)
{
TUint intersectArea=0;
for (TInt stepThis=aThisCount-1,bit=1;stepThis>=0;stepThis--,bit<<=1)
{
if (!(aOptimiseThisBits&bit))
{
const TRect& thisRect=aThisRects[stepThis];
TRegionExtend::TOverlapFlags flags=TestDifferenceNotEmpty(thisRect,aThatRect);
if (!(flags&TRegionExtend::ENoIntersect))
{
if (!(flags&TRegionExtend::EAdd))
{ //Skip rest of inner loop if a containing rect is found
TSize size=aThatRect.Size();
intersectArea+=size.iWidth*size.iHeight;
if (!(flags&TRegionExtend::ESub)) //equal rects...
{ //skip this cell for rest of outer loop if a contains rect is found
aOptimiseThisBits|=bit;
}
break; //this cell contains the target rect so don't bother checking any more
}
else
if (!(flags&TRegionExtend::ESub))
{ //skip this cell for rest of outer loop if a contains rect is found
aOptimiseThisBits|=bit;
TSize size=thisRect.Size();
intersectArea+=size.iWidth*size.iHeight;
}
else
{
TRect intersect=thisRect;
intersect.Intersection(aThatRect);
TSize size=intersect.Size();
intersectArea+=size.iWidth*size.iHeight;
}
}
}
}
return intersectArea;
}
/** Avoids the use of a temp region by performing area calc on the fly.
* If both regions are empty then EOverlapNoIntersect only is returned.
* @param aThat target region
* @return flags from TOverlapFlags enumeration
* - EExact =0 if rgions are exactly identical
* - ESub Flagged if some rectangles are removed converting current region to that target
* - EAdd Flagged if some rectangles are added converting current region to that target
* - ENoIntersect if there is no common region between the current region and that target
* - EErrorRegion One of the regions is signalling CheckError()
**/
TRegionExtend::TOverlapFlags TRegionExtend::TestDifference(const TRegion& aThat)const
{
TInt intersectArea=0;
TInt thisArea=0;
TInt thatArea=0;
const TRect* thisRects=RectangleList();
const TRect* thatRects=aThat.RectangleList();
TInt thatCount=aThat.Count();
TInt thisCount=Count();
if (CheckError()||aThat.CheckError())
return EErrorRegion;
if (thisCount==0)
if (thatCount==0)
return ENoIntersect;
else
return TOverlapFlags(ENoIntersect|EAdd);
//both regions are populated. How big is the intersection?
//The following optimisation bit is that
//if any rect is fully contained by a rect in the opposite region
//then further compares against that rect are skipped. For this, inner loop is skipped immediately
//Can track the first 32 rects of aThat. The remainder won't benefit from the optimisation
TUint optimiseThisBits=0;
for (TInt stepThat=thatCount-1;stepThat>=0;stepThat--)
{
TRect thatRect=thatRects[stepThat];
intersectArea+=TestDifferenceRegionInnerLoop(thisCount,thisRects,thatRect,optimiseThisBits);
}
if (intersectArea==0)
if (thatCount==0)
return TOverlapFlags(ENoIntersect|ESub);
else
return TOverlapFlags(ENoIntersect|EAdd|ESub);
thatArea=RectListArea(thatRects,thatCount);
thisArea=RectListArea(thisRects,thisCount);
return AreaDiffResults( thisArea, intersectArea, thatArea );
}
/** Avoids the use of a temp region by performing area calc on the fly.
* This version further optimises the process by avoiding the client having to re-origin either region.
* If both regions are empty then EOverlapNoIntersect only is returned.
* @param aThat target region
* @return flags from TOverlapFlags enumeration
* - EExact =0 if rgions are exactly identical
* - ESub Flagged if some rectangles are removed converting current region to that target
* - EAdd Flagged if some rectangles are added converting current region to that target
* - ENoIntersect if there is no common region between the current region and that target
* - EErrorRegion One of the regions is signalling CheckError()
**/
TRegionExtend::TOverlapFlags TRegionExtend::TestDifference(const TRegion& aThat,TPoint aOffsetToThat)const
{
TInt intersectArea=0;
TInt thisArea=0;
TInt thatArea=0;
const TRect* thisRects=RectangleList();
const TRect* thatRects=aThat.RectangleList();
TInt thatCount=aThat.Count();
TInt thisCount=Count();
if (CheckError()||aThat.CheckError())
return EErrorRegion;
if (thisCount==0)
if (thatCount==0)
return ENoIntersect;
else
return TOverlapFlags(ENoIntersect|EAdd);
//both regions are populated. How big is the intersection?
//The following optimisation bit is that
//if any rect is fully contained by a rect in the opposite region
//then further compares against that rect are skipped. For this, inner loop is skipped immediately
//Can track the first 32 rects of aThat. The remainder won't benefit from the optimisation
TUint optimiseThisBits=0;
for (TInt stepThat=thatCount-1;stepThat>=0;stepThat--)
{
TRect thatRect=thatRects[stepThat];
thatRect.Move(-aOffsetToThat.iX,-aOffsetToThat.iY); //this line is the only difference, but the next lump has a lot of parameters...
intersectArea+=TestDifferenceRegionInnerLoop(thisCount,thisRects,thatRect,optimiseThisBits);
}
if (intersectArea==0)
if (thatCount==0)
return TOverlapFlags(ENoIntersect|ESub);
else
return TOverlapFlags(ENoIntersect|EAdd|ESub);
thatArea=RectListArea(thatRects,thatCount);
thisArea=RectListArea(thisRects,thisCount);
return AreaDiffResults( thisArea, intersectArea, thatArea );
}
/** This returns the same comparrison flags between two rectangles.
* Note that a zero return means exact intersection...
* Intended as an internal method, but there doesn't seem to be a useful public alternative.
* @param aThis source rectangle
* @param aThat target rectangle
* @return flags from TOverlapFlags enumeration
* - EExact =0 if rgions are exactly identical
* - ESub Flagged if some rectangles are removed converting this source rectangle to that target
* - EAdd Flagged if some rectangles are added converting this source rectangle to that target
* - ENoIntersect if there is no common region between this source rectangle and that target
**/
TRegionExtend::TOverlapFlags TRegionExtend::TestDifference(const TRect& aThis,const TRect& aThat)
{
if (aThis.IsEmpty())
if (aThat.IsEmpty())
return ENoIntersect;
else
return TOverlapFlags(EAdd|ENoIntersect);
else
if (aThat.IsEmpty())
return TOverlapFlags(ESub|ENoIntersect);
return TestDifferenceNotEmpty(aThis,aThat);
}
/** Returns total area of the region
* @return total area
**/
TUint TRegionExtend::Area()const
{
return RectListArea(RectangleList(),Count());
}
/** Avoids the use of a temp region by performing area calc on the fly.
* If both are empty then EOverlapNoIntersect only is returned.
* @param aThat target rectangle
* @return flags from TOverlapFlags enumeration
* - EExact =0 if region exactly fills rectangle
* - ESub Flagged if some rectangles are removed converting current region to that target
* - EAdd Flagged if some rectangles are added converting current region to that target
* - ENoIntersect if there is no common region between the current region and that target
* - EErrorRegion One of the region is signalling CheckError()
**/
TRegionExtend::TOverlapFlags TRegionExtend::TestDifference(const TRect& aThat)const
{
TInt intersectArea=0;
const TRect* thisRects=RectangleList();
TInt thisCount=Count();
if (aThat.IsEmpty())
if (thisCount==0)
return ENoIntersect;
else
return TOverlapFlags(ENoIntersect|ESub);
if (CheckError())
return EErrorRegion;
TInt output=ENoIntersect;
for (TInt stepThis=thisCount-1,bit=1;stepThis>=0;stepThis--,bit+=bit)
{
TOverlapFlags flags=TestDifferenceNotEmpty(thisRects[stepThis],aThat);
if (!(flags&ENoIntersect))
{
if (!(flags&EAdd)) //the target rect does not add anything to this region element
{ //Skip rest of inner loop if a containing rect is found
if ((flags&ESub)||thisCount>1)
return ESub; //the region element is bigger or there are more region elements
else
return EExact;
}
else
{
TRect intersect=thisRects[stepThis];
intersect.Intersection(aThat);
TSize size=intersect.Size();
__ASSERT_DEBUG((size.iWidth|size.iHeight)<32768,User::Panic(_L("TRegionExtend"),1003));
intersectArea+=size.iWidth*size.iHeight;
}
output&=~ENoIntersect;
}
output|=(flags&ESub);
}
if (intersectArea==0)
{
return TOverlapFlags(output|EAdd);
}
TSize size=aThat.Size();
__ASSERT_DEBUG((size.iWidth|size.iHeight)<32768,User::Panic(_L("TRegionExtend"),2003));
TInt thatArea=size.iWidth*size.iHeight;
if (thatArea>intersectArea)
return TOverlapFlags(output|EAdd);
else
return TOverlapFlags(output);
}