Update contrib.
1 // Copyright (c) 2006-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "BitDrawInterfaceId.h"
19 //The method prepares RGB value writting, calculating physical aX, aY, aWidth and aHeight.
20 //The calculated coordinates are used by methods wich do not use methods in BmDraw8Scaling.cpp
21 //file - WriteRgbMultiXOR(), WriteRgbMultiAND(), WriteRgbMultiOR().
22 //If the scaling is "off" then it is very simple - draw physical pixels. But if the scaling is
23 //"on" then a rectanngle is being drawn instead of a pixel. And rectangle coordinates are
24 //calculated depending on the device' orientation.
25 //aX, aY - logical coordinates.
26 //aWidth, aHeight - output parameters, they will be initialized in the method's body,
27 //if aDrawMode is not CGraphicsContext::EPenmode. If aDrawMode is CGraphicsContext::EPenmode,
28 //then aWidth will be set with iScalingSettings.iFactorX and aheight - with
29 //iScalingSettings.iFactorY.
30 void CDrawBitmap::PreWriteRgb(TInt& aWidth,
34 CGraphicsContext::TDrawMode aDrawMode)
36 DeOrientate(aX, aY);//aX and aY - physical coordinates
38 __ASSERT_DEBUG(aX >= 0 && aX < iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
39 __ASSERT_DEBUG(aY >= 0 && aY < iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
41 //If scaling is ON, instead of drawing single point, rectangle with size [FactorX, FactorY]
42 //is drawn. Rectangle's width and height might be swapped, depending on the orientation.
43 aWidth = iScalingSettings.iFactorX;
44 aHeight = iScalingSettings.iFactorY;
51 //Do this additional deorientation only for not EPenmode modes and when scaling is ON!
52 //EPenmode uses WriteRgb(aX,aY,aColor), which does not need any changes in
54 if(!(aDrawMode & CGraphicsContext::EPenmode))
56 //aX, aY - physical coordinates
57 //aWidth, aWidth - output parameters
58 //When scaling is ON, instead of drawing single point, rectangle is drawn
59 //and top-left coordinates, width and height has to be calculated.
60 register TInt scalingFactorX = aWidth;
61 register TInt scalingFactorY = aHeight;
62 __ASSERT_DEBUG(scalingFactorX > 0, User::Invariant());
63 __ASSERT_DEBUG(scalingFactorY > 0, User::Invariant());
64 register CFbsDrawDevice::TOrientation orientation = iOrientation;
68 case EOrientationRotated90:
69 case EOrientationRotated270:
71 if(orientation == EOrientationRotated90)
73 aX -= (scalingFactorX - 1);
75 if(orientation == EOrientationRotated270)
77 aY -= (scalingFactorY - 1);
81 case EOrientationRotated180 :
83 aX -= (scalingFactorX - 1);
84 aY -= (scalingFactorY - 1);
90 //If the calculated coordinates are negative, set them to 0.
102 //Writes RGB value at the specified physical screen coordinates.
103 //When scaling is ON - rectangle [aWidth, aHeight] is drawn instead of single point.
104 //Depending on the orientation aWidth and aHeight might be swapped.
105 //aX, aY - physical coordinates
106 //aWidth, aHeight - physical
107 void CDrawBitmap::WriteRgb(TInt& aWidth, TInt& aHeight,
108 TInt& aX, TInt& aY, TRgb aColor,
109 CGraphicsContext::TDrawMode aDrawMode)
111 MapColorToUserDisplayMode(aColor);
116 if(aDrawMode&CGraphicsContext::EInvertPen)
120 if(aDrawMode&CGraphicsContext::EPenmode)
122 WriteRgb(aX,aY,aColor);
125 __ASSERT_DEBUG(aWidth > 0, User::Invariant());
126 __ASSERT_DEBUG(aHeight > 0, User::Invariant());
127 if(aDrawMode&CGraphicsContext::EWriteAlpha)
129 // WriteRgbMulti is the only available api that writes alpha
130 WriteRgbMulti(aX,aY,aWidth,aHeight,aColor);
133 if(aDrawMode&CGraphicsContext::EInvertScreen)
135 WriteRgbMultiXOR(aX, aY, aWidth, aHeight, KRgbWhite);
137 if(aDrawMode&CGraphicsContext::EXor)
139 WriteRgbMultiXOR(aX, aY, aWidth, aHeight, aColor);
141 else if(aDrawMode&CGraphicsContext::EAnd)
143 WriteRgbMultiAND(aX, aY, aWidth, aHeight, aColor);
145 else if(aDrawMode&CGraphicsContext::EOr)
147 WriteRgbMultiOR(aX, aY, aWidth, aHeight, aColor);
152 Implementation for CFbsDrawDevice::GetDrawRect().
153 Gets logical coordinates of the drawing rectangle.
154 If the device is not scaled and with zero origin, logocal coordinates of
155 the drawing rectangle are the same as its physical coordinates.
156 If the device is rotated, drawing rectangle width and height are swapped.
157 Always prefer GetDrawRect() to SizeInPixels() call. SizeInPixels() will return
158 drawing rectangle width and height. But if the device is scaled or with nonzero origin,
159 GetDrawRect() will take into account and the top-left corner of the drawing rectangle too,
160 which may not be [0, 0].
161 @param aRect Upon return aRect contains drawing rectangle logical coordinates.
163 void CDrawBitmap::GetDrawRect(TRect& aDrawRect) const
165 aDrawRect = iDrawRect;
166 if (iOrientation & 1)
168 if (iOrigin.iX!=iOrigin.iY || iScalingSettings.iFactorX!=iScalingSettings.iFactorY)
169 { //When the scales are different between the dimensions the origin needs to recalculating
170 aDrawRect.iTl.iX=Origin(iOrigin.iX,iScalingSettings.iFactorY);
171 aDrawRect.iTl.iY=Origin(iOrigin.iY,iScalingSettings.iFactorX);
173 aDrawRect.SetWidth(iDrawRect.Height());
174 aDrawRect.SetHeight(iDrawRect.Width());
179 Implementation for MScalingSettings::Set().
180 Sets scaling factor by which the drawing device should scale the drawing images.
181 If you want to un-scale the device, call Set() with
182 factorX = 1, factorY = 1, divisorX = 1, divisorY = 1.
183 @param aFactorX Scaling factor for the X-axis of the screen device.
184 @param aFactorY Scaling factor for the y-axis of the screen device.
185 @param aDivisorX Not used. Should be set to 1.
186 @param aDivisorY Not used. Should be set to 1.
187 @return KErrNone success.
189 TInt CDrawBitmap::Set(TInt aFactorX, TInt aFactorY, TInt aDivisorX, TInt aDivisorY)
191 __ASSERT_DEBUG(aDivisorX == 1 && aDivisorY == 1, User::Invariant());
192 __ASSERT_DEBUG(aFactorX > 0 && aFactorY > 0, User::Invariant());
194 iScalingSettings.iFactorX = aFactorX;
195 iScalingSettings.iFactorY = aFactorY;
196 iScalingSettings.iDivisorX = aDivisorX;
197 iScalingSettings.iDivisorY = aDivisorY;
199 iScalingOff = aFactorX == 1 && aFactorY == 1 && aDivisorX == 1 && aDivisorY == 1;
201 InitLogicalCoordinates();
207 Implementation for MScalingSettings::Get().
208 Retrieves X-axis and Y-axis scaling factors.
209 @param aFactorX Upon return contains X-axis scaling factor.
210 @param aFactorY Upon return contains Y-axis scaling factor.
211 @param aDivisorX Upon return contains the decimal fraction of X-axis scaling factor.
212 @param aDivisorY Upon return contains the decimal fraction of Y-axis scaling factor.
214 void CDrawBitmap::Get(TInt& aFactorX, TInt& aFactorY, TInt& aDivisorX, TInt& aDivisorY)
216 aFactorX = iScalingSettings.iFactorX;
217 aFactorY = iScalingSettings.iFactorY;
218 aDivisorX = iScalingSettings.iDivisorX;
219 aDivisorY = iScalingSettings.iDivisorY;
223 Implementation for MScalingSettings::IsScalingOff().
224 Notifies the caller whether the drawing device is scaled or not.
225 @return ETrue Drawing device is not scaled, EFalse - it is scaled.
227 TBool CDrawBitmap::IsScalingOff()
233 Implementation for MDrawDeviceOrigin::Set().
234 Sets drawing device origin.
235 If you want to the default origin, call Set() with Origin (0,0).
236 @param aOrigin Specifies physical coordinates of the new scaling origin
237 of the drawing device. The drawing device maps the logical point [0,0] to
238 the "aOrigin" physical point .
239 @return KErrNone success.
241 TInt CDrawBitmap::Set(const TPoint& aOrigin)
243 __ASSERT_DEBUG(aOrigin.iX >= 0 && aOrigin.iY >= 0, User::Invariant());
244 __ASSERT_DEBUG(aOrigin.iX < iSize.iWidth && aOrigin.iY < iSize.iHeight, User::Invariant());
248 iOriginIsZero = iOrigin.iX == 0 && iOrigin.iY == 0;
250 InitLogicalCoordinates();
256 Implementation for MDrawDeviceOrigin::Get().
257 Retrieves origin point.
258 @param aOrigin Upon return contains scaling origin point.
260 void CDrawBitmap::Get(TPoint& aOrigin)
265 //Initializes iDrawRect data member, which contains logical coordinates of
266 //the drawing(screen) rectangle.
267 //The method does not use iOrientation data member.
268 void CDrawBitmap::InitLogicalCoordinates()
270 register TInt orgX = iOrigin.iX;
271 register TInt orgY = iOrigin.iY;
272 register TInt fX = iScalingSettings.iFactorX;
273 register TInt fY = iScalingSettings.iFactorY;
275 iDrawRect.iTl.iX = Origin(orgX, fX);
276 iDrawRect.iTl.iY = Origin(orgY, fY);
277 iDrawRect.iBr.iX = OtherSide(orgX, iSize.iWidth, fX);
278 iDrawRect.iBr.iY = OtherSide(orgY, iSize.iHeight, fY);
280 { //The number of addressable pixels in the physical dimensions
281 //Sometimes needs to be one less when rotationed by 90 or 270
282 //If so set it one less all the time as the value is not recalculated
284 { //Calculated the physical left and right of screen when rotation by 90 or 270
285 //Use this width if it is smaller
286 TInt left = Origin(orgY, fX);
287 TInt right = OtherSide(orgY, iSize.iWidth, fX);
288 iDrawRect.iBr.iX = Min(iDrawRect.iBr.iX, iDrawRect.iTl.iX+(right-left));
291 { //Calculated the physical top and bottom of screen when rotation by 90 or 270
292 //Use this height if it is smaller
293 TInt top = Origin(orgX, fY);
294 TInt bottom = OtherSide(orgX, iSize.iHeight, fY);
295 iDrawRect.iBr.iY = Min(iDrawRect.iBr.iY, iDrawRect.iTl.iY+(bottom-top));
301 Notifies the caller whether the drawing device can be scaled or not.
302 @return ETrue Drawing device can be scaled, EFalse - it can't be scaled.
304 TBool CDrawBitmap::CanBeScaled() const
306 //The function will return true for all display modes
311 Notifies the caller whether the drawing device origin can be moved from (0, 0) point or not.
312 @return ETrue Drawing device origin can be moved, EFalse - it can't be moved.
314 TBool CDrawBitmap::CanOriginBeMoved() const
316 //The function will return true for all display modes
320 //This method calculates pixel increment value and row increment value depending
321 //on the orientation. The device might be scaled. The result is returned in
322 //aPixelInc and aRowInc parameters.
323 void CDrawBitmap::SetPixelInc(TInt& aPixelInc, TInt& aRowInc) const
325 register TInt scalingFactorX = iScalingSettings.iFactorX;
326 register TInt scalingFactorY = iScalingSettings.iFactorY;
329 case EOrientationNormal:
331 aPixelInc = scalingFactorX;
332 aRowInc = iLongWidth * scalingFactorY;
335 case EOrientationRotated90:
337 aPixelInc = iLongWidth * scalingFactorY;
338 aRowInc = -scalingFactorX;
341 case EOrientationRotated180:
343 aPixelInc = -scalingFactorX;
344 aRowInc = -iLongWidth * scalingFactorY;
347 default: // EOrientationRotated270
349 aPixelInc = -iLongWidth * scalingFactorY;
350 aRowInc = scalingFactorX;
356 //Calculates "Y" increment value and assigns it to aY parameter.
357 //The device might be scaled and rotated.
358 //It is used by WriteBinary(), WriteBinaryOp(), ... methods and only there.
359 //The method is very specific for the methods mentioned above -
360 //if the device is scaled and rotated 0 or 180 degrees, Y-axis coordinate has to
361 //be incremented not by 1, but by iScalingSettings.iFactorY. Because of the integer divison
362 //when transforming logical to physical coordinates, incremented Y-axis coordinates may
363 //go negative or greater than drawing rectangle height. Then it has to be adjusted to 0
364 //or rectangle height.
365 void CDrawBitmap::IncScaledY(TInt& aY, TInt aYOrg) const
367 const TOrientation orientation = iOrientation;
368 const TInt fY = iScalingSettings.iFactorY;
371 case EOrientationNormal:
374 const TInt height = iSize.iHeight - 1;
381 case EOrientationRotated180:
397 //Calculates "Y" increment value and assigns it to aY parameter.
398 //The device might be scaled and rotated.
399 //It is used by WriteBinary(), WriteBinaryOp(), WriteLine...() methods and only there.
400 //The method is very specific for the methods mentioned above -
401 //if the device is scaled and rotated 90 or 270 degrees, Y-axis coordinate has to
402 //be incremented not by 1, but by iScalingSettings.iFactorX. Because of the integer divison
403 //when transforming logical to physical coordinates, incremented Y-axis coordinates may
404 //go negative or greater than drawing rectangle height. Then it has to be adjusted to 0
405 //or rectangle height.
406 void CDrawBitmap::IncScaledY(TInt& aY) const
408 const TOrientation orientation = iOrientation;
409 const TInt fX = iScalingSettings.iFactorY;
410 if(orientation == EOrientationRotated90)
413 const TInt height = iSize.iHeight - 1;
419 else if(orientation == EOrientationRotated270)
429 //Increment without scaling
430 TInt CDrawBitmap::PixelAddressIncrement() const
432 switch (iOrientation)
434 case EOrientationNormal:
436 case EOrientationRotated90:
438 case EOrientationRotated180:
440 case EOrientationRotated270:
445 return KInvalidValue;
448 //Pixel increment with scaling.
449 //It is used by CDrawEightBppBitmapCommon::SetPixels,
450 //CDrawEightBppBitmapCommon::XORPixels, CDrawEightBppBitmapCommon::ANDPixels,
451 //CDrawEightBppBitmapCommon::ORPixels methods
452 TInt CDrawBitmap::LogicalPixelAddressIncrement() const
454 register TInt scalingFactorX = iScalingSettings.iFactorX;
455 register TInt scalingFactorY = iScalingSettings.iFactorY;
456 switch (iOrientation)
458 case EOrientationNormal:
459 return scalingFactorX;
460 case EOrientationRotated90:
461 return iLongWidth * scalingFactorY;
462 case EOrientationRotated180:
463 return -scalingFactorX;
464 case EOrientationRotated270:
465 return -iLongWidth * scalingFactorY;
469 return KInvalidValue;
472 inline TInt CDrawBitmap::Origin(TInt aPhysOrg, TInt aScale) const
474 return -(aPhysOrg/aScale + (aPhysOrg%aScale ? 1:0));
477 inline TInt CDrawBitmap::OtherSide(TInt aPhysOrg, TInt aPhysSize, TInt aScale) const
479 return (aPhysSize-1-aPhysOrg) / aScale + 1;