|
1 // Copyright (c) 1997-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 "BMDRAW.H" |
|
17 #include "BitDrawInterfaceId.h" |
|
18 |
|
19 // CDrawEightBppBitmapCommon |
|
20 //EColor256 screen/bitmap device might be scaled. |
|
21 //In this case right-bottom coordinate might go outside the drawing rectangle. |
|
22 //Then - we need to check that we do not try to draw something outside the drawing rectangle. |
|
23 |
|
24 //Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members. |
|
25 //It should be called every time when iSize is going to be changed - from Construct(). |
|
26 //@param aSize Physical screen size in pixels. |
|
27 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the |
|
28 //device is scaled and the scaling origin goes outside physical drawing rectangle. |
|
29 void CDrawEightBppBitmapCommon::SetSize(const TSize& aSize) |
|
30 { |
|
31 CDrawBitmap::SetSize(aSize); |
|
32 __ASSERT_DEBUG(iSize == aSize, User::Invariant()); |
|
33 iLongWidth = (iSize.iWidth + 3) & ~3; |
|
34 iScanLineWords = iLongWidth / 4; |
|
35 } |
|
36 |
|
37 TInt CDrawEightBppBitmapCommon::Construct(TSize aSize, TInt aStride) |
|
38 { |
|
39 iBits = NULL; |
|
40 CDrawBitmap::SetSize(aSize); |
|
41 __ASSERT_DEBUG(iSize == aSize, User::Invariant()); |
|
42 if (aStride & 3) |
|
43 return KErrArgument; |
|
44 iLongWidth = aStride; |
|
45 if (iLongWidth < aSize.iWidth) |
|
46 return KErrArgument; |
|
47 iScanLineWords = aStride >> 2; |
|
48 TInt size = Max(aSize.iWidth,aSize.iHeight); |
|
49 if(size < 0) |
|
50 return KErrArgument; |
|
51 iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size)); |
|
52 if(iScanLineBuffer == NULL) |
|
53 return KErrNoMemory; |
|
54 return KErrNone; |
|
55 } |
|
56 |
|
57 //aX, aY - physical coordinates |
|
58 TUint8* CDrawEightBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const |
|
59 { |
|
60 return (TUint8*)iBits + aY * iLongWidth + aX; |
|
61 } |
|
62 |
|
63 void CDrawEightBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer) |
|
64 { |
|
65 const TUint32* limit = aBuffer + (aLength + 3) / 4; |
|
66 |
|
67 while (aBuffer < limit) |
|
68 *aBuffer++ ^= 0xffffffff; |
|
69 } |
|
70 |
|
71 //CDrawEightBppBitmapCommon::ReadLine() called from CDrawBitmap::ReadLine() |
|
72 //aX and aY - physical coordinates. |
|
73 //Reads aLength pixel values and places them in aBuffer. |
|
74 //aBuffer size should be at least aLength. |
|
75 void CDrawEightBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const |
|
76 { |
|
77 const TUint8* pixelPtr = PixelAddress(aX,aY); |
|
78 |
|
79 if (iOrientation == EOrientationNormal && iScalingOff) |
|
80 Mem::Copy(aBuffer,pixelPtr,aLength); |
|
81 else |
|
82 { |
|
83 register TInt pixelPtrInc = LogicalPixelAddressIncrement(); |
|
84 |
|
85 TUint8* bufferPtr = static_cast <TUint8*> (aBuffer); |
|
86 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
87 |
|
88 while (bufferPtr < bufferPtrLimit) |
|
89 { |
|
90 *bufferPtr++ = *pixelPtr; |
|
91 pixelPtr += pixelPtrInc; |
|
92 } |
|
93 } |
|
94 } |
|
95 |
|
96 //CDrawEightBppBitmapCommon::WriteRgb() called from exported CDrawBitmap::WriteRgb() |
|
97 //aX, aY - physical coordinates |
|
98 void CDrawEightBppBitmapCommon::WriteRgb(TInt aX,TInt aY,TUint8 aPixel) |
|
99 { |
|
100 register TUint8* pixelAddr = PixelAddress(aX, aY); |
|
101 if(iScalingOff) |
|
102 { |
|
103 *pixelAddr = aPixel; |
|
104 } |
|
105 else |
|
106 { |
|
107 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
108 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
109 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
110 SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
111 } |
|
112 } |
|
113 |
|
114 //CDrawEightBppBitmapCommon::WriteBinary() called from exported CDrawBitmap::WriteBinary() |
|
115 //aX, aY - logical coordinates |
|
116 //"aData" parameter has "aHeight" 32 bits words |
|
117 //"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word |
|
118 //This method is used for bitmap font symbols drawing |
|
119 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then |
|
120 //writing could be made on 32 bits words (they has to be aligned before the operation) |
|
121 void CDrawEightBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength, |
|
122 TInt aHeight,TUint8 aPixel) |
|
123 { |
|
124 DeOrientate(aX,aY);//aX, aY - physical coordinates |
|
125 TInt pixelInc; |
|
126 TInt rowInc; |
|
127 SetPixelInc(pixelInc, rowInc); |
|
128 const TUint32* dataLimit = aData + aHeight; |
|
129 register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; |
|
130 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
131 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
132 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
133 TInt orgY = aY; |
|
134 while (aData < dataLimit) |
|
135 { |
|
136 register TUint32 dataWord = *aData++; |
|
137 register TUint32 dataMask = 1; |
|
138 register TUint8* tempPixelPtr = pixelPtr; |
|
139 if(iScalingOff) |
|
140 { |
|
141 while (dataMask != dataMaskLimit) |
|
142 { |
|
143 if(dataWord & dataMask) |
|
144 { |
|
145 *tempPixelPtr = aPixel; |
|
146 } |
|
147 tempPixelPtr += pixelInc; |
|
148 dataMask <<= 1; |
|
149 } |
|
150 } |
|
151 else |
|
152 { |
|
153 while (dataMask != dataMaskLimit) |
|
154 { |
|
155 if(dataWord & dataMask) |
|
156 { |
|
157 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
158 SetPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
159 } |
|
160 tempPixelPtr += pixelInc; |
|
161 dataMask <<= 1; |
|
162 IncScaledY(aY); |
|
163 } |
|
164 } |
|
165 pixelPtr += rowInc; |
|
166 IncScaledY(aY, orgY); |
|
167 } |
|
168 } |
|
169 |
|
170 //CDrawEightBppBitmapCommon::WriteBinaryOp() called from exported CDrawBitmap::WriteBinary() |
|
171 //aX, aY - logical coordinates |
|
172 //"aData" parameter has "aHeight" 32 bits words |
|
173 //"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word |
|
174 //This method is used for bitmap font symbols drawing |
|
175 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then |
|
176 //writing could be made on 32 bits words (they has to be aligned before the operation) |
|
177 void CDrawEightBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength, |
|
178 TInt aHeight,TUint8 aPixel, |
|
179 CGraphicsContext::TDrawMode aDrawMode) |
|
180 { |
|
181 if(aLength <= 0) |
|
182 { |
|
183 return; |
|
184 } |
|
185 DeOrientate(aX,aY);//aX, aY - physical coordinates |
|
186 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
187 const TUint32* dataPtrLimit = aData + aHeight; |
|
188 register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; |
|
189 TInt pixelInc; |
|
190 TInt rowInc; |
|
191 SetPixelInc(pixelInc, rowInc); |
|
192 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
193 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
194 TInt orgY = aY; |
|
195 if(aPixel) |
|
196 { |
|
197 while(aData < dataPtrLimit) |
|
198 { |
|
199 register TUint32 dataWord = *aData++; |
|
200 register TUint32 dataMask = 1; |
|
201 register TUint8* tempPixelPtr = pixelPtr; |
|
202 if(iScalingOff) |
|
203 { |
|
204 while(dataMask != dataMaskLimit) |
|
205 { |
|
206 if(dataWord & dataMask) |
|
207 { |
|
208 if(aDrawMode==CGraphicsContext::EDrawModeXOR) |
|
209 { |
|
210 *tempPixelPtr ^= aPixel; |
|
211 } |
|
212 else if(aDrawMode==CGraphicsContext::EDrawModeAND) |
|
213 { |
|
214 *tempPixelPtr &= aPixel; |
|
215 } |
|
216 else if(aDrawMode==CGraphicsContext::EDrawModeOR) |
|
217 { |
|
218 *tempPixelPtr |= aPixel; |
|
219 } |
|
220 } |
|
221 tempPixelPtr += pixelInc; |
|
222 dataMask <<= 1; |
|
223 } |
|
224 } |
|
225 else |
|
226 { |
|
227 while(dataMask != dataMaskLimit) |
|
228 { |
|
229 if(dataWord & dataMask) |
|
230 { |
|
231 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
232 if(aDrawMode==CGraphicsContext::EDrawModeXOR) |
|
233 { |
|
234 XORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
235 } |
|
236 else if(aDrawMode==CGraphicsContext::EDrawModeAND) |
|
237 { |
|
238 ANDPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
239 } |
|
240 else if(aDrawMode==CGraphicsContext::EDrawModeOR) |
|
241 { |
|
242 ORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
243 } |
|
244 } |
|
245 tempPixelPtr += pixelInc; |
|
246 dataMask <<= 1; |
|
247 IncScaledY(aY); |
|
248 } |
|
249 } |
|
250 pixelPtr += rowInc; |
|
251 IncScaledY(aY, orgY); |
|
252 } |
|
253 } |
|
254 else if(aDrawMode==CGraphicsContext::EDrawModeAND) |
|
255 { |
|
256 while(aData < dataPtrLimit) |
|
257 { |
|
258 register TUint32 dataWord = *aData++; |
|
259 register TUint32 dataMask = 1; |
|
260 register TUint8* tempPixelPtr = pixelPtr; |
|
261 if(iScalingOff) |
|
262 { |
|
263 while(dataMask != dataMaskLimit) |
|
264 { |
|
265 if(dataWord & dataMask) |
|
266 { |
|
267 *tempPixelPtr = 0; |
|
268 } |
|
269 tempPixelPtr += pixelInc; |
|
270 dataMask <<= 1; |
|
271 } |
|
272 } |
|
273 else |
|
274 { |
|
275 while(dataMask != dataMaskLimit) |
|
276 { |
|
277 if(dataWord & dataMask) |
|
278 { |
|
279 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
280 SetPixels(tempPixelPtr, TUint8(0), pixelRowPtrLimit, bitsStart, bitsEnd); |
|
281 } |
|
282 tempPixelPtr += pixelInc; |
|
283 dataMask <<= 1; |
|
284 } |
|
285 } |
|
286 pixelPtr += rowInc; |
|
287 IncScaledY(aY, orgY); |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 //aX, aY - logical coordinates |
|
293 //"aData" parameter has 32 bits words |
|
294 //"aLength" parameter tells how many pixels have to be written |
|
295 //This method is used for bitmap font symbols vertical drawing |
|
296 //The method should not be called if the scaling is ON! |
|
297 void CDrawEightBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData, |
|
298 TInt aLength,TUint8 aPixel,TBool aUp) |
|
299 { |
|
300 __ASSERT_DEBUG(iScalingOff, User::Invariant()); |
|
301 |
|
302 DeOrientate(aX,aY);//aX, aY - physical coordinates |
|
303 |
|
304 TInt scanlineByteLength; |
|
305 switch(iOrientation) |
|
306 { |
|
307 case EOrientationNormal: |
|
308 scanlineByteLength = iLongWidth; |
|
309 break; |
|
310 case EOrientationRotated90: |
|
311 scanlineByteLength = -1; |
|
312 break; |
|
313 case EOrientationRotated180: |
|
314 scanlineByteLength = -iLongWidth; |
|
315 break; |
|
316 default: // EOrientationRotated270 |
|
317 scanlineByteLength = 1; |
|
318 } |
|
319 |
|
320 if (aUp) |
|
321 scanlineByteLength = -scanlineByteLength; |
|
322 |
|
323 register TUint8* pixelPtr = PixelAddress(aX,aY); |
|
324 const TUint8* pixelPtrLimit = pixelPtr + aLength * scanlineByteLength; |
|
325 register TUint32 dataWord = *aData; |
|
326 register TUint32 dataMask = 1; |
|
327 |
|
328 while(pixelPtr != pixelPtrLimit) |
|
329 { |
|
330 if(!dataMask) |
|
331 { |
|
332 dataMask = 1; |
|
333 aData++; |
|
334 dataWord = *aData; |
|
335 } |
|
336 if(dataWord & dataMask) |
|
337 { |
|
338 *pixelPtr = aPixel; |
|
339 } |
|
340 dataMask <<= 1; |
|
341 pixelPtr += scanlineByteLength; |
|
342 } |
|
343 } |
|
344 |
|
345 //CDrawEightBppBitmapCommon::WriteLine() called from CDrawBitmap::WriteLine() |
|
346 //aX and aY - physical coordinates |
|
347 void CDrawEightBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) |
|
348 { |
|
349 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
350 if (iOrientation == EOrientationNormal && iScalingOff) |
|
351 { |
|
352 Mem::Copy(pixelPtr,aBuffer,aLength); |
|
353 } |
|
354 else |
|
355 { |
|
356 register TInt pixelPtrInc = LogicalPixelAddressIncrement(); |
|
357 TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer); |
|
358 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
359 if(iScalingOff) |
|
360 { |
|
361 while(bufferPtr < bufferPtrLimit) |
|
362 { |
|
363 *pixelPtr = *bufferPtr++; |
|
364 pixelPtr += pixelPtrInc; |
|
365 } |
|
366 } |
|
367 else |
|
368 { |
|
369 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
370 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
371 while(bufferPtr < bufferPtrLimit) |
|
372 { |
|
373 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
374 SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
375 pixelPtr += pixelPtrInc; |
|
376 IncScaledY(aY); |
|
377 } |
|
378 } |
|
379 } |
|
380 } |
|
381 |
|
382 //CDrawEightBppBitmapCommon::WriteLineXOR() called from CDrawBitmap::WriteLine() |
|
383 //aX and aY - physical coordinates |
|
384 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then |
|
385 //XOR could be made on 32 bits words (they has to be aligned before the operation) |
|
386 void CDrawEightBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) |
|
387 { |
|
388 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
389 register TInt pixelPtrInc = LogicalPixelAddressIncrement(); |
|
390 TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer); |
|
391 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
392 if(iScalingOff) |
|
393 { |
|
394 while(bufferPtr < bufferPtrLimit) |
|
395 { |
|
396 *pixelPtr ^= *bufferPtr++; |
|
397 pixelPtr += pixelPtrInc; |
|
398 } |
|
399 } |
|
400 else |
|
401 { |
|
402 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
403 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
404 while(bufferPtr < bufferPtrLimit) |
|
405 { |
|
406 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
407 XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
408 pixelPtr += pixelPtrInc; |
|
409 IncScaledY(aY); |
|
410 } |
|
411 } |
|
412 } |
|
413 |
|
414 //CDrawEightBppBitmapCommon::WriteLineAND() called from CDrawBitmap::WriteLine() |
|
415 //aX and aY - deorientated and scaled |
|
416 //aLength - not scaled |
|
417 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then |
|
418 //AND could be made on 32 bits words (they has to be aligned before the operation) |
|
419 void CDrawEightBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) |
|
420 { |
|
421 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
422 register TInt pixelPtrInc = LogicalPixelAddressIncrement(); |
|
423 TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer); |
|
424 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
425 if(iScalingOff) |
|
426 { |
|
427 while(bufferPtr < bufferPtrLimit) |
|
428 { |
|
429 *pixelPtr &= *bufferPtr++; |
|
430 pixelPtr += pixelPtrInc; |
|
431 } |
|
432 } |
|
433 else |
|
434 { |
|
435 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
436 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
437 while(bufferPtr < bufferPtrLimit) |
|
438 { |
|
439 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
440 ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
441 pixelPtr += pixelPtrInc; |
|
442 IncScaledY(aY); |
|
443 } |
|
444 } |
|
445 } |
|
446 |
|
447 //CDrawEightBppBitmapCommon::WriteLineOR() called from CDrawBitmap::WriteLine() |
|
448 //aX and aY - physical coordinates |
|
449 //One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then |
|
450 //OR could be made on 32 bits words (they has to be aligned before the operation) |
|
451 void CDrawEightBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) |
|
452 { |
|
453 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
454 register TInt pixelPtrInc = LogicalPixelAddressIncrement(); |
|
455 TUint8* bufferPtr = reinterpret_cast <TUint8*> (aBuffer); |
|
456 const TUint8* bufferPtrLimit = bufferPtr + aLength; |
|
457 if(iScalingOff) |
|
458 { |
|
459 while(bufferPtr < bufferPtrLimit) |
|
460 { |
|
461 *pixelPtr |= *bufferPtr++; |
|
462 pixelPtr += pixelPtrInc; |
|
463 } |
|
464 } |
|
465 else |
|
466 { |
|
467 const TUint8* bitsStart = reinterpret_cast <const TUint8*> (iBits); |
|
468 const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; |
|
469 while(bufferPtr < bufferPtrLimit) |
|
470 { |
|
471 const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; |
|
472 ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); |
|
473 pixelPtr += pixelPtrInc; |
|
474 IncScaledY(aY); |
|
475 } |
|
476 } |
|
477 } |
|
478 |
|
479 //CDrawEightBppBitmapCommon::WriteRgbMulti() called from CDrawBitmap::WriteRgbMulti() |
|
480 //aX and aY - physical coordinates |
|
481 //aLength and aRows - physical length and rows |
|
482 void CDrawEightBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aRows, |
|
483 TUint8 aPixel) |
|
484 { |
|
485 register TInt longWidth = iLongWidth; |
|
486 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
487 const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; |
|
488 register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight; |
|
489 if(pixelRowPtrLimit >= bitsEnd) |
|
490 { |
|
491 pixelRowPtrLimit = bitsEnd; |
|
492 } |
|
493 |
|
494 while (pixelPtr < pixelRowPtrLimit) |
|
495 { |
|
496 Mem::Fill(pixelPtr,aLength,aPixel); |
|
497 pixelPtr += longWidth; |
|
498 } |
|
499 } |
|
500 |
|
501 //CDrawEightBppBitmapCommon::WriteRgbMultiXOR() called from CDrawBitmap::WriteRgbMulti() |
|
502 //aX and aY - physical coordinates |
|
503 //aLength and aRows - physical length and rows |
|
504 void CDrawEightBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aRows, |
|
505 TUint8 aPixel) |
|
506 { |
|
507 register TInt longWidth = iLongWidth; |
|
508 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
509 TUint8* pixelPtrLimit = pixelPtr + aLength; |
|
510 const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; |
|
511 register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight; |
|
512 if(pixelRowPtrLimit >= bitsEnd) |
|
513 { |
|
514 pixelRowPtrLimit = bitsEnd; |
|
515 } |
|
516 |
|
517 while (pixelPtr < pixelRowPtrLimit) |
|
518 { |
|
519 TUint8* tempPixelPtr = pixelPtr; |
|
520 |
|
521 while (tempPixelPtr < pixelPtrLimit) |
|
522 *tempPixelPtr++ ^= aPixel; |
|
523 |
|
524 pixelPtr += longWidth; |
|
525 pixelPtrLimit += longWidth; |
|
526 } |
|
527 } |
|
528 |
|
529 //CDrawEightBppBitmapCommon::WriteRgbMultiAND() called from CDrawBitmap::WriteRgbMulti() |
|
530 //aX and aY - physical coordinates |
|
531 //aLength and aRows - physical length and rows |
|
532 void CDrawEightBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aRows, |
|
533 TUint8 aPixel) |
|
534 { |
|
535 register TInt longWidth = iLongWidth; |
|
536 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
537 const TUint8* pixelPtrLimit = pixelPtr + aLength; |
|
538 const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; |
|
539 register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight; |
|
540 if(pixelRowPtrLimit >= bitsEnd) |
|
541 { |
|
542 pixelRowPtrLimit = bitsEnd; |
|
543 } |
|
544 |
|
545 while (pixelPtr < pixelRowPtrLimit) |
|
546 { |
|
547 TUint8* tempPixelPtr = pixelPtr; |
|
548 |
|
549 while (tempPixelPtr < pixelPtrLimit) |
|
550 *tempPixelPtr++ &= aPixel; |
|
551 |
|
552 pixelPtr += longWidth; |
|
553 pixelPtrLimit += longWidth; |
|
554 } |
|
555 } |
|
556 |
|
557 //CDrawEightBppBitmapCommon::WriteRgbMultiOR() called from CDrawBitmap::WriteRgbMulti() |
|
558 //aX and aY - physical coordinates |
|
559 //aLength and aRows - physical length and rows |
|
560 void CDrawEightBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aRows,TUint8 aPixel) |
|
561 { |
|
562 register TInt longWidth = iLongWidth; |
|
563 TUint8* pixelPtr = PixelAddress(aX,aY); |
|
564 TUint8* pixelPtrLimit = pixelPtr + aLength; |
|
565 const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; |
|
566 register const TUint8* bitsEnd = reinterpret_cast <const TUint8*> (iBits) + iLongWidth * iSize.iHeight; |
|
567 if(pixelRowPtrLimit >= bitsEnd) |
|
568 { |
|
569 pixelRowPtrLimit = bitsEnd; |
|
570 } |
|
571 |
|
572 while (pixelPtr < pixelRowPtrLimit) |
|
573 { |
|
574 TUint8* tempPixelPtr = pixelPtr; |
|
575 |
|
576 while (tempPixelPtr < pixelPtrLimit) |
|
577 *tempPixelPtr++ |= aPixel; |
|
578 |
|
579 pixelPtr += longWidth; |
|
580 pixelPtrLimit += longWidth; |
|
581 } |
|
582 } |
|
583 |
|
584 /** |
|
585 Implementation for CFbsDrawDevice::GetInterface(). |
|
586 Retrieves a pointer to a specified interface of CFbsDrawDevice implementation. |
|
587 @param aInterfaceId Interface identifier of the interface to be retrieved. |
|
588 @param aInterface Address of variable that retrieves the specified interface. |
|
589 @return KErrNone If the interface is supported, KErrNotSupported otherwise. |
|
590 */ |
|
591 |
|
592 TInt CDrawEightBppBitmapCommon::GetInterface(TInt aInterfaceId, TAny*& aInterface) |
|
593 { |
|
594 aInterface = NULL; |
|
595 TInt ret = KErrNotSupported; |
|
596 |
|
597 if (aInterfaceId == KFastBlit2InterfaceID) |
|
598 { |
|
599 aInterface = static_cast<MFastBlit2*>(this); |
|
600 ret = KErrNone; |
|
601 } |
|
602 else |
|
603 return CDrawBitmap::GetInterface(aInterfaceId, aInterface); |
|
604 |
|
605 return ret; |
|
606 } |
|
607 |
|
608 /** |
|
609 CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation. |
|
610 @internalTechnology |
|
611 @see MFastBlit2::WriteBitmapBlock() |
|
612 */ |
|
613 TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest, |
|
614 CFbsDrawDevice* aSrcDrawDevice, |
|
615 const TRect& aSrcRect) |
|
616 { |
|
617 __ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor256) || (aSrcDrawDevice->DisplayMode()==EGray256)), Panic(EScreenDriverPanicInvalidParameter)); |
|
618 |
|
619 TAny* interface=NULL; |
|
620 TInt ret = aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface); |
|
621 if (ret != KErrNone) |
|
622 { |
|
623 return KErrNotSupported; |
|
624 } |
|
625 |
|
626 TAny* interface1=NULL; |
|
627 ret = aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, interface1); |
|
628 if(ret != KErrNone || (interface1 && !reinterpret_cast<MScalingSettings*>(interface1)->IsScalingOff())) |
|
629 { |
|
630 return KErrNotSupported; |
|
631 } |
|
632 |
|
633 ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1); |
|
634 if(ret != KErrNone || (interface1 && reinterpret_cast<MDrawDeviceOrientation*>(interface1)->Orientation() != 0)) |
|
635 { |
|
636 return KErrNotSupported; |
|
637 } |
|
638 |
|
639 ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1); |
|
640 if(ret != KErrNone) |
|
641 { |
|
642 return KErrNotSupported; |
|
643 } |
|
644 |
|
645 if(interface1) |
|
646 { |
|
647 TPoint pt; |
|
648 reinterpret_cast<MDrawDeviceOrigin*>(interface1)->Get(pt); |
|
649 if(pt.iX != 0 || pt.iY != 0) |
|
650 { |
|
651 return KErrNotSupported; |
|
652 } |
|
653 } |
|
654 |
|
655 const TUint32* srcBase = reinterpret_cast<MFastBlit2*>(interface)->Bits(); |
|
656 __ASSERT_DEBUG(srcBase!=NULL, Panic(EScreenDriverPanicInvalidParameter)); |
|
657 TInt srcStride = aSrcDrawDevice->ScanLineBytes(); |
|
658 __ASSERT_DEBUG((srcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter)); // stride is assumed to be a multiple of 4 |
|
659 TSize srcSize = aSrcDrawDevice->SizeInPixels(); |
|
660 |
|
661 return WriteBitmapBlock(aDest, srcBase, srcStride, srcSize, aSrcRect); |
|
662 } |
|
663 |
|
664 |
|
665 /** |
|
666 CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation. |
|
667 @internalTechnology |
|
668 @see MFastBlit2::WriteBitmapBlock() |
|
669 */ |
|
670 TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest, |
|
671 const TUint32* aSrcBase, |
|
672 TInt aSrcStride, |
|
673 const TSize& aSrcSize, |
|
674 const TRect& aSrcRect) |
|
675 { |
|
676 __ASSERT_DEBUG(aSrcBase, Panic(EScreenDriverPanicInvalidParameter)); |
|
677 __ASSERT_DEBUG((aSrcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter)); |
|
678 __ASSERT_DEBUG(iBits, Panic(EScreenDriverPanicInvalidPointer)); |
|
679 |
|
680 if (iShadowMode!=NULL || |
|
681 (iUserDispMode!=NULL && iUserDispMode!=iDispMode) || |
|
682 iOrientation!=EOrientationNormal || |
|
683 !IsScalingOff() || |
|
684 !iOriginIsZero) |
|
685 { |
|
686 return KErrNotSupported; |
|
687 } |
|
688 |
|
689 __ASSERT_DEBUG(aSrcRect.iTl.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); |
|
690 __ASSERT_DEBUG(aSrcRect.iTl.iY >= 0, Panic(EScreenDriverPanicOutOfBounds)); |
|
691 __ASSERT_DEBUG(aSrcRect.iBr.iX <= aSrcSize.iWidth, Panic(EScreenDriverPanicOutOfBounds)); |
|
692 __ASSERT_DEBUG(aSrcRect.iBr.iY <= aSrcSize.iHeight, Panic(EScreenDriverPanicOutOfBounds)); |
|
693 __ASSERT_DEBUG(aDest.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); |
|
694 __ASSERT_DEBUG(aDest.iY >= 0, Panic(EScreenDriverPanicOutOfBounds)); |
|
695 __ASSERT_DEBUG((aDest.iX + aSrcRect.Width()) <= SizeInPixels().iWidth, Panic(EScreenDriverPanicOutOfBounds)); |
|
696 __ASSERT_DEBUG((aDest.iY + aSrcRect.Height()) <= SizeInPixels().iHeight, Panic(EScreenDriverPanicOutOfBounds)); |
|
697 |
|
698 const TInt srcStride8 = aSrcStride; |
|
699 const TInt dstStride8 = iScanLineWords << 2; |
|
700 |
|
701 if (aSrcSize.iWidth == aSrcRect.Width() && |
|
702 aSrcSize.iWidth == SizeInPixels().iWidth && |
|
703 srcStride8 == dstStride8) |
|
704 { |
|
705 // Optimum case - one memcpy |
|
706 __ASSERT_DEBUG(aSrcRect.iTl.iX==0 && aDest.iX==0, Panic(EScreenDriverPanicInvalidParameter)); // this is implied by the above conditions |
|
707 const TUint32* srcPtr = aSrcBase + (iScanLineWords * aSrcRect.iTl.iY); |
|
708 TUint32* dstPtr = iBits + (iScanLineWords * aDest.iY); |
|
709 const TInt length = aSrcStride * aSrcRect.Height(); |
|
710 Mem::Move(dstPtr, srcPtr, length); |
|
711 return KErrNone; |
|
712 } |
|
713 |
|
714 // Sub-optimal case - one memcpy per line |
|
715 const TUint8* srcPtr = (TUint8*)aSrcBase + (srcStride8 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX; |
|
716 TUint8* dstPtr = (TUint8*)iBits + (dstStride8 * aDest.iY ) + aDest.iX; |
|
717 const TInt length = aSrcRect.Width(); |
|
718 TInt lines = aSrcRect.Height(); |
|
719 while (lines--) |
|
720 { |
|
721 Mem::Copy(dstPtr, srcPtr, length); |
|
722 srcPtr += srcStride8; |
|
723 dstPtr += dstStride8; |
|
724 } |
|
725 return KErrNone; |
|
726 } |
|
727 |
|
728 |
|
729 /** |
|
730 CDrawEightBppBitmapCommon::Bits() implementation. |
|
731 @internalTechnology |
|
732 @see MFastBlit2::Bits() |
|
733 */ |
|
734 const TUint32* CDrawEightBppBitmapCommon::Bits() const |
|
735 { |
|
736 return iBits; |
|
737 } |