|
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)); |
|
225 #ifdef _UNICODE |
|
226 return TPtr16(reinterpret_cast<TText16*>(const_cast<TText8*>(ptr8.Ptr())), |
|
227 length, |
|
228 length); //lint !e826 |
|
229 #else |
|
230 return TPtr8(const_cast<TText8*>(ptr8.Ptr()), ptr8.Length(), ptr8.Length()); |
|
231 #endif |
|
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 } |