author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Wed, 13 Oct 2010 14:23:59 +0300 | |
branch | RCL_3 |
changeset 83 | 26b2b12093af |
parent 66 | 2455ef1f5bbc |
permissions | -rw-r--r-- |
66 | 1 |
/******************************************************************************* |
2 |
* Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 |
* All rights reserved. This program and the accompanying materials |
|
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
|
5 |
* which accompanies this distribution, and is available at |
|
6 |
* http://www.eclipse.org/legal/epl-v10.html |
|
7 |
* |
|
8 |
* Contributors: |
|
9 |
* Nokia Corporation - S60 implementation |
|
10 |
*******************************************************************************/ |
|
11 |
||
12 |
||
13 |
#include <baclipb.h> |
|
14 |
#include <s32ucmp.h> |
|
15 |
#include "swtcontrolhelper.h" |
|
16 |
||
17 |
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
18 |
#include <txtclipboard.h> |
|
19 |
#endif |
|
20 |
||
21 |
// ======== MEMBER FUNCTIONS ======== |
|
22 |
||
23 |
||
24 |
/** |
|
25 |
* Creates a copy of the bitmap passed as a parameter and returns a pointer to the copy. |
|
26 |
* The caller is responsible for destroying the returned pointer, which is on the cleanup stack. |
|
27 |
*/ |
|
28 |
CFbsBitmap* SwtControlHelper::GetCopyOfBitmapLC(const CFbsBitmap* aBitmap, |
|
29 |
const TSize& aTargetSize) |
|
30 |
{ |
|
31 |
if (!aBitmap) |
|
32 |
{ |
|
33 |
return NULL; |
|
34 |
} |
|
35 |
||
36 |
TSize bmpSize(aBitmap->SizeInPixels()); |
|
37 |
TBool doScaledCopy(ETrue); |
|
38 |
if ((aTargetSize == TSize(-1, -1)) || (aTargetSize == bmpSize)) |
|
39 |
{ |
|
40 |
doScaledCopy = EFalse; |
|
41 |
} |
|
42 |
||
43 |
CFbsBitmap* result = new(ELeave) CFbsBitmap; |
|
44 |
CleanupStack::PushL(result); |
|
45 |
||
46 |
TSize size; |
|
47 |
if (doScaledCopy) |
|
48 |
{ |
|
49 |
size = aTargetSize; |
|
50 |
} |
|
51 |
else |
|
52 |
{ |
|
53 |
size = bmpSize; |
|
54 |
} |
|
55 |
||
56 |
User::LeaveIfError(result->Create(size, aBitmap->DisplayMode())); |
|
57 |
||
58 |
if (doScaledCopy) |
|
59 |
{ |
|
60 |
// Create a gc for drawing to the bitmap |
|
61 |
CFbsBitGc* fbsBitGc = CFbsBitGc::NewL(); |
|
62 |
CleanupStack::PushL(fbsBitGc); |
|
63 |
CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL(result); |
|
64 |
CleanupStack::Pop(fbsBitGc); |
|
65 |
fbsBitGc->Activate(bmpDevice); |
|
66 |
||
67 |
// Draw the scaled copy |
|
68 |
fbsBitGc->DrawBitmap(TRect(TPoint(0, 0), size), aBitmap); |
|
69 |
||
70 |
delete bmpDevice; |
|
71 |
delete fbsBitGc; |
|
72 |
} |
|
73 |
else // Do a same-sized copy |
|
74 |
{ |
|
75 |
TInt len = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, aBitmap->DisplayMode()); |
|
76 |
||
77 |
ASSERT(len > 0); |
|
78 |
||
79 |
result->LockHeap(); |
|
80 |
Mem::Copy(reinterpret_cast<TUint8*>(result->DataAddress()), |
|
81 |
reinterpret_cast<const TUint8*>(aBitmap->DataAddress()), len); |
|
82 |
result->UnlockHeap(); |
|
83 |
} |
|
84 |
||
85 |
return result; |
|
86 |
} |
|
87 |
||
88 |
||
89 |
/** |
|
90 |
* Creates a copy of the bitmap passed as a parameter and returns a pointer to the copy. |
|
91 |
* The caller is responsible for destroying the returned pointer. |
|
92 |
*/ |
|
93 |
CFbsBitmap* SwtControlHelper::GetCopyOfBitmapL(const CFbsBitmap* aBitmap, |
|
94 |
const TSize& aTargetSize) |
|
95 |
{ |
|
96 |
CFbsBitmap* result = GetCopyOfBitmapLC(aBitmap, aTargetSize); |
|
97 |
if (result) |
|
98 |
{ |
|
99 |
CleanupStack::Pop(result); |
|
100 |
} |
|
101 |
return result; |
|
102 |
} |
|
103 |
||
104 |
||
105 |
/** |
|
106 |
* Creates a copy of the bitmap passed as a parameter and returns a pointer to the copy. |
|
107 |
* The caller is responsible for destroying the returned pointer, which is on the cleanup stack. |
|
108 |
* If the parameter bitmap is a monochrome bitmap then the copy will be inverted. |
|
109 |
* This function is intended to be used in cases where the component doing the drawing |
|
110 |
* is expecting an inverted mask bitmap. |
|
111 |
*/ |
|
112 |
CFbsBitmap* SwtControlHelper::GetInvertedCopyOfMonoBitmapLC(const CFbsBitmap* aBitmap, |
|
113 |
const TSize& aTargetSize) |
|
114 |
{ |
|
115 |
if (!aBitmap) |
|
116 |
{ |
|
117 |
return NULL; |
|
118 |
} |
|
119 |
||
120 |
if (!aBitmap->IsMonochrome()) |
|
121 |
{ |
|
122 |
return GetCopyOfBitmapLC(aBitmap, aTargetSize); |
|
123 |
} |
|
124 |
||
125 |
TBool doScaledCopy(aTargetSize == TSize(-1, -1) ? EFalse : ETrue); |
|
126 |
TSize size; |
|
127 |
if (doScaledCopy) |
|
128 |
{ |
|
129 |
size = aTargetSize; |
|
130 |
} |
|
131 |
else |
|
132 |
{ |
|
133 |
size = aBitmap->SizeInPixels(); |
|
134 |
} |
|
135 |
||
136 |
CFbsBitmap* target = new(ELeave) CFbsBitmap; |
|
137 |
CleanupStack::PushL(target); |
|
138 |
User::LeaveIfError(target->Create(size, EGray2)); |
|
139 |
CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(target); |
|
140 |
CleanupStack::PushL(device); |
|
141 |
CFbsBitGc* gc = NULL; |
|
142 |
User::LeaveIfError(device->CreateContext(gc)); |
|
143 |
TInt drawMode = CGraphicsContext::EDrawModeWriteAlpha | CGraphicsContext::EInvertPen; |
|
144 |
gc->SetDrawMode(CGraphicsContext::TDrawMode(drawMode)); |
|
145 |
if (doScaledCopy) |
|
146 |
{ |
|
147 |
gc->DrawBitmap(TRect(TPoint(0, 0), size), aBitmap); |
|
148 |
} |
|
149 |
else |
|
150 |
{ |
|
151 |
gc->BitBlt(TPoint(), aBitmap); |
|
152 |
} |
|
153 |
delete gc; |
|
154 |
CleanupStack::PopAndDestroy(device); |
|
155 |
||
156 |
return target; |
|
157 |
} |
|
158 |
||
159 |
||
160 |
/** |
|
161 |
* Creates a copy of the bitmap passed as a parameter and returns a pointer to the copy. |
|
162 |
* The caller is responsible for destroying the returned pointer, which is on the cleanup stack. |
|
163 |
* If the parameter bitmap is a monochrome bitmap then the copy will be inverted. |
|
164 |
* This function is intended to be used in cases where the component doing the drawing |
|
165 |
* is expecting an inverted mask bitmap. |
|
166 |
*/ |
|
167 |
CFbsBitmap* SwtControlHelper::GetInvertedCopyOfMonoBitmapL(const CFbsBitmap* aBitmap, |
|
168 |
const TSize& aTargetSize) |
|
169 |
{ |
|
170 |
CFbsBitmap* result = GetInvertedCopyOfMonoBitmapLC(aBitmap, aTargetSize); |
|
171 |
if (result) |
|
172 |
{ |
|
173 |
CleanupStack::Pop(result); |
|
174 |
} |
|
175 |
return result; |
|
176 |
} |
|
177 |
||
178 |
||
179 |
/** |
|
180 |
* Retrieves the clipboard's text content |
|
181 |
* |
|
182 |
* It is up to the caller to free the descriptor by calling |
|
183 |
* <code>CleanupStack::PopAndDestroy()</code> if the descriptor's |
|
184 |
* pointer is not <code>NULL</code> |
|
185 |
* |
|
186 |
* @return A descriptor containing the clipboard's content. |
|
187 |
*/ |
|
188 |
TPtr SwtControlHelper::GetClipboardTextContentLC() |
|
189 |
{ |
|
190 |
// Get the clipboard |
|
191 |
CClipboard* cb = NULL; |
|
192 |
TRAPD(error, (cb = CClipboard::NewForReadingL(CEikonEnv::Static()->FsSession()))); // codescanner::eikonenvstatic |
|
193 |
if (error == KErrPathNotFound || error==KErrNotFound) // Nothing in the clipboard, not an error |
|
194 |
return TPtr(NULL, 0, 0); |
|
195 |
User::LeaveIfError(error); |
|
196 |
||
197 |
CleanupStack::PushL(cb); |
|
198 |
TStreamId id(cb->StreamDictionary().At(KClipboardUidTypePlainText)); //lint !e613 |
|
199 |
if (id == KNullStreamId) |
|
200 |
{ |
|
201 |
CleanupStack::PopAndDestroy(cb); |
|
202 |
return TPtr(NULL, 0, 0); |
|
203 |
} |
|
204 |
||
205 |
RStoreReadStream stream; |
|
206 |
stream.OpenLC(cb->Store(), id); //lint !e613 |
|
207 |
TInt length = stream.ReadInt32L(); |
|
208 |
CBufFlat* buffer = CBufFlat::NewL(length); |
|
209 |
CleanupStack::PushL(buffer); |
|
210 |
||
211 |
RBufWriteStream bufStream(*buffer); |
|
212 |
CleanupClosePushL(bufStream); |
|
213 |
TMemoryStreamUnicodeSink sink(bufStream); |
|
214 |
TUnicodeExpander e; |
|
215 |
e.ExpandL(sink, stream, length); |
|
216 |
bufStream.CommitL(); |
|
217 |
||
218 |
CleanupStack::PopAndDestroy(); // bufStream |
|
219 |
CleanupStack::Pop(buffer); |
|
220 |
CleanupStack::PopAndDestroy(2, cb); // stream, cb |
|
221 |
||
222 |
CleanupStack::PushL(buffer); |
|
223 |
||
224 |
TPtrC8 ptr8(buffer->Ptr(0)); |
|
83
26b2b12093af
Revision: v2.2.17
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
66
diff
changeset
|
225 |
#ifdef _UNICODE |
66 | 226 |
return TPtr16(reinterpret_cast<TText16*>(const_cast<TText8*>(ptr8.Ptr())), |
227 |
length, |
|
228 |
length); //lint !e826 |
|
83
26b2b12093af
Revision: v2.2.17
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
66
diff
changeset
|
229 |
#else |
26b2b12093af
Revision: v2.2.17
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
66
diff
changeset
|
230 |
return TPtr8(const_cast<TText8*>(ptr8.Ptr()), ptr8.Length(), ptr8.Length()); |
26b2b12093af
Revision: v2.2.17
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
66
diff
changeset
|
231 |
#endif |
66 | 232 |
} |
233 |
||
234 |
/* |
|
235 |
* Returns size for a bitmap that is scaled to fit inside aMaxDestSize |
|
236 |
* if aSourceSize > aMaxDestSize. The scaling is done so that aspect ratio of the |
|
237 |
* result is the same as in source. |
|
238 |
* |
|
239 |
* If aSourceSize < aMaxDestSize, no scaling is done. |
|
240 |
*/ |
|
241 |
TSize SwtControlHelper::GetAspectRatioScaledBitmapSize(const TSize& aSourceSize, |
|
242 |
const TSize& aMaxDestSize) |
|
243 |
{ |
|
244 |
TSize imageSize = aSourceSize; |
|
245 |
TInt yDiff = 0, xDiff = 0; |
|
246 |
TBool scalingNeeded = EFalse; |
|
247 |
||
248 |
if (aSourceSize.iWidth == 0 || aSourceSize.iHeight == 0) |
|
249 |
{ |
|
250 |
return imageSize; |
|
251 |
} |
|
252 |
||
253 |
// Figure out if any scaling is needed |
|
254 |
if (aSourceSize.iHeight > aMaxDestSize.iHeight) |
|
255 |
{ |
|
256 |
yDiff = aSourceSize.iHeight - aMaxDestSize.iHeight; |
|
257 |
scalingNeeded = ETrue; |
|
258 |
} |
|
259 |
if (aSourceSize.iWidth > aMaxDestSize.iWidth) |
|
260 |
{ |
|
261 |
xDiff = aSourceSize.iWidth - aMaxDestSize.iWidth; |
|
262 |
scalingNeeded = ETrue; |
|
263 |
} |
|
264 |
||
265 |
if (scalingNeeded) |
|
266 |
{ |
|
267 |
if (xDiff > yDiff) |
|
268 |
{ |
|
269 |
imageSize.iWidth = aMaxDestSize.iWidth; |
|
270 |
imageSize.iHeight = (aSourceSize.iHeight * aMaxDestSize.iWidth) / aSourceSize.iWidth; |
|
271 |
} |
|
272 |
else if (yDiff > xDiff) |
|
273 |
{ |
|
274 |
imageSize.iHeight = aMaxDestSize.iHeight; |
|
275 |
imageSize.iWidth = (aSourceSize.iWidth * aMaxDestSize.iHeight) / aSourceSize.iHeight; |
|
276 |
} |
|
277 |
else |
|
278 |
{ |
|
279 |
// aspect ratios are the same |
|
280 |
imageSize = aMaxDestSize; |
|
281 |
} |
|
282 |
} |
|
283 |
||
284 |
return imageSize; |
|
285 |
} |