graphicsdeviceinterface/directgdiadaptation/hwsrc/clippingregionmanager.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "clippingregionmanager.h"
       
    17 
       
    18 const TInt KVgClippingRectSize = sizeof(TVgClippingRect)/sizeof(VGint);
       
    19 
       
    20 RClippingRegionManager::RClippingRegionManager () : 
       
    21 	iItemsPerStep (1)
       
    22 	{
       
    23 	}
       
    24 
       
    25 void RClippingRegionManager::Close ()
       
    26 	{
       
    27 	iClippingRegion.Close();
       
    28 	iClippingRects.Close();
       
    29 	}
       
    30 
       
    31 /** 
       
    32 Initialise the iterator with run-time information.
       
    33 @param aItemsPerStep		Number of clipping rectangles to set in OpenVG per iteeration.
       
    34 @param aVgEngineTargetSize	Dimensions of image target. This is used to perform Symbian to OpenVG
       
    35 							coordinate transformations.
       
    36 */
       
    37 void RClippingRegionManager::Initialize (TUint aItemsPerStep, TSize aVgEngineTargetSize)
       
    38 	{
       
    39 	iItemsPerStep = aItemsPerStep;
       
    40 	iVgEngineTargetSize = aVgEngineTargetSize;
       
    41 	}
       
    42 
       
    43 /**
       
    44 Set the iterator to the beginning of the region.
       
    45 */
       
    46 void RClippingRegionManager::Begin()
       
    47 	{
       
    48 	iCurrentRect = 0;
       
    49 	iBegun = EFalse;
       
    50 	}
       
    51 
       
    52 /**
       
    53 Reset the state associated with the iterator, but not the clipping region.
       
    54 Note that the iItemsPerStep member is not reset.
       
    55 */
       
    56 void RClippingRegionManager::ResetIterator ()
       
    57 	{
       
    58 	iClippingRects.Reset();
       
    59 	iCurrentRect = 0;
       
    60 	iBegun = EFalse;
       
    61 	}
       
    62 
       
    63 /**
       
    64 Reset the object state.
       
    65 @see ResetIterator()
       
    66 */
       
    67 void RClippingRegionManager::Reset ()
       
    68 	{
       
    69 	iClippingRegion.Clear();
       
    70 	ResetIterator();
       
    71 	}
       
    72 
       
    73 /**
       
    74 @return The number of items before the iterator gets to the End() item.
       
    75 */
       
    76 TUint RClippingRegionManager::RemainingItems() const
       
    77 	{
       
    78 	return iClippingRects.Count() - iCurrentRect;
       
    79 	}
       
    80 
       
    81 /**
       
    82 @return The number of items to be set in this iteration. This value will be either
       
    83 		iItemsPerStep or the number of items to the end of the list (whichever
       
    84 		is smaller)
       
    85 */
       
    86 TUint RClippingRegionManager::ItemsInThisIteration() const
       
    87 	{
       
    88 	TUint remainingItems = RemainingItems();
       
    89 	return (remainingItems > iItemsPerStep) ? iItemsPerStep : remainingItems;
       
    90 	}
       
    91 
       
    92 /**
       
    93 Set the clip region for the current iteration in OpenVG. If no clipping 
       
    94 rectangles are defined in the clipping region then clipping is turned off, 
       
    95 and this method returns ETrue on the first invocation after Begin()
       
    96 (behaviour is as if one big clip rect is defined that matches the extents 
       
    97 of the target pixmap exactly).
       
    98 
       
    99 @return ETrue if a region was set, or no clipping rectangles are defined.
       
   100 */
       
   101 TBool RClippingRegionManager::ApplyClipRegion()
       
   102 	{
       
   103 	TBool result = EFalse;
       
   104 	
       
   105 	if (iClippingRects.Count() == 0)
       
   106 		{
       
   107 		if (!iBegun)
       
   108 			{
       
   109 			vgSeti(VG_SCISSORING, VG_FALSE);
       
   110 			result = ETrue;
       
   111 			}
       
   112 		else
       
   113 			{
       
   114 			result = EFalse;
       
   115 			}
       
   116 		}
       
   117 	else
       
   118 		{
       
   119 		TUint itemsInThisIteration = ItemsInThisIteration();
       
   120 		if (itemsInThisIteration)
       
   121 			{
       
   122 			vgSeti(VG_SCISSORING, VG_TRUE);
       
   123 			vgSetiv(
       
   124 				VG_SCISSOR_RECTS,
       
   125 				KVgClippingRectSize*itemsInThisIteration, 
       
   126 				reinterpret_cast<VGint*>(&iClippingRects[iCurrentRect]));
       
   127 			}
       
   128 		result = itemsInThisIteration>0;
       
   129 		}
       
   130 
       
   131 	iBegun = ETrue;
       
   132 	return result;
       
   133 	}
       
   134 
       
   135 
       
   136 /**
       
   137 Moves the iterator forward by iItemsPerStep items. 
       
   138 @return ETrue if there are items to go after the iteration, otherwise false.
       
   139 */
       
   140 TBool RClippingRegionManager::Next()
       
   141 	{
       
   142 	TBool result = EFalse;
       
   143 	if (RemainingItems() > iItemsPerStep)
       
   144 		{
       
   145 		iCurrentRect += iItemsPerStep;
       
   146 		result = ETrue;
       
   147 		}
       
   148 	else
       
   149 		{
       
   150 		iCurrentRect = iClippingRects.Count();	
       
   151 		}
       
   152 	return result;
       
   153 	}
       
   154 	
       
   155 
       
   156 /**
       
   157 @see RArray::Append()
       
   158 */
       
   159 TInt RClippingRegionManager::Append(const TPoint& aVgPosition, VGint aWidth, VGint aHeight)
       
   160 	{
       
   161 	TVgClippingRect clippingRect = {aVgPosition.iX, aVgPosition.iY, aWidth, aHeight};
       
   162 	return iClippingRects.Append(clippingRect);
       
   163 	}
       
   164 
       
   165 /**
       
   166 @see MDirectGdiEngine::SetClippingRegion(const TRegion&)
       
   167 */
       
   168 TInt RClippingRegionManager::SetClippingRegion(const TRegion& aRegion)
       
   169 	{
       
   170 	TInt result = KErrNone;
       
   171 	Reset();
       
   172 	if(aRegion.Count() != 0)
       
   173 		{
       
   174 		result = ConvertClippingRegion (aRegion);
       
   175 		
       
   176 		if (result != KErrNoMemory)
       
   177 			{
       
   178 			iClippingRegion.Copy(aRegion);
       
   179 			if(iClippingRegion.CheckError())
       
   180 				{
       
   181 				result = KErrNoMemory;
       
   182 				}
       
   183 			}
       
   184 		}
       
   185 	return result;
       
   186 	}
       
   187 
       
   188 /**
       
   189 Convert the specified clipping region to OpenVG coords and store the
       
   190 converted coords internally.
       
   191 @param aRegion	Region for conversion.
       
   192 @return  KErrNoMemory, otherwise KErrNone.
       
   193 */
       
   194 TInt RClippingRegionManager::ConvertClippingRegion(const TRegion& aRegion)
       
   195 	{
       
   196 	TInt result = KErrNone;
       
   197 	ResetIterator();
       
   198 	const TInt count = aRegion.Count();
       
   199 	if(count != 0)
       
   200 		{
       
   201 		for(TInt ii = 0; ii < count; ++ii)
       
   202 			{
       
   203 			const TRect& regionRect = aRegion[ii];
       
   204 			// Clipping regions in OpenVG are not subject to transformations, 
       
   205 			// so need to pass in coordinates which are already in OpenVG coordinate system.
       
   206 			// Get the rectangle's position, specified in OpenVG coordinate system.
       
   207 			if (Append(
       
   208 					ConvertToVgCoords(regionRect), 
       
   209 					regionRect.Width(), 
       
   210 					regionRect.Height()) == KErrNoMemory)
       
   211 				{
       
   212 				result = KErrNoMemory;
       
   213 				break;
       
   214 				}
       
   215 			}
       
   216 		}
       
   217 	return result;
       
   218 	}
       
   219 
       
   220 /** 
       
   221 If the clipping region is empty, then set it to the specified clip rect,
       
   222 otherwise set it to its intersection with the specified clip rect.
       
   223 @param aClipRect Rectangle to clip to.
       
   224 */
       
   225 void RClippingRegionManager::ClipTo(const TRect& aClipRect)
       
   226 	{
       
   227 	if (iClippingRegion.IsEmpty())
       
   228 		{
       
   229 		iClippingRegion.AddRect(aClipRect);		
       
   230 		}
       
   231 	else
       
   232 		{
       
   233 		iClippingRegion.ClipRect(aClipRect);
       
   234 		}
       
   235 	
       
   236 	ConvertClippingRegion(iClippingRegion);
       
   237 	}
       
   238 
       
   239 /**
       
   240 @return The clipping region.
       
   241 */
       
   242 const RRegion& RClippingRegionManager::ClippingRegion() const
       
   243 	{
       
   244 	return const_cast<const RRegion&>(iClippingRegion);
       
   245 	}
       
   246 
       
   247 /**
       
   248 @return 'ETrue' if aClipRect intersects with the currently defined clipping region.
       
   249 		Note that if no clipping region is defined then ETrue is always returned.
       
   250 */
       
   251 TBool RClippingRegionManager::Intersects(const TRect& aClipRect) const
       
   252 	{
       
   253 	return (iClippingRegion.IsEmpty() || iClippingRegion.Intersects(aClipRect));
       
   254 	}
       
   255 
       
   256 /**
       
   257 Converts the position of a rectangle from Symbian graphics coordinate system to OpenVG coordinate system.
       
   258 
       
   259 The Symbian coordinate system's x-axis increases positively from the origin rightwards.
       
   260 The y-axis increases positively from the origin downwards.
       
   261 A rectangle's position is specified by the top-left coordinate.
       
   262 
       
   263 The OpenVG coordinate system's x-axis increases positively from the origin rightwards.
       
   264 The y-axis increases positively from the origin upwards.
       
   265 A rectangle's position is specified by the bottom-left coordinate.
       
   266 
       
   267 A point (X,Y) in Symbian coordinate system would be equivalent to point
       
   268 (X',Y') in OpenVG coordinate system by the following transformations:
       
   269 X' = X
       
   270 Y' = (Height of rendering target) - Y
       
   271 
       
   272 @param	aRect	A rectangle whose position is to be converted for use in OpenVG.
       
   273 
       
   274 @return The bottom-left point of the rectangle, specified in OpenVG specific coordinate system.
       
   275 */
       
   276 const TPoint RClippingRegionManager::ConvertToVgCoords(const TRect& aRect) const
       
   277 	{
       
   278 	return TPoint(aRect.iTl.iX, iVgEngineTargetSize.iHeight - aRect.iBr.iY);
       
   279 	}