|
1 /* |
|
2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of CHuiRasterizedTextMesh. CHuiRasterizedTextMesh |
|
15 * stores a rasterized bitmap version of a text string. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <s32mem.h> |
|
21 #include "HuiRasterizedTextMesh.h" |
|
22 #include "HuiRenderPlugin.h" |
|
23 #include "uiacceltk/HuiEnv.h" |
|
24 #include "uiacceltk/HuiSkin.h" |
|
25 #include "uiacceltk/HuiStatic.h" |
|
26 #include "uiacceltk/HuiFont.h" |
|
27 #include "uiacceltk/HuiTexture.h" |
|
28 #include "uiacceltk/HuiGc.h" |
|
29 #include "uiacceltk/HuiUtil.h" |
|
30 #include "uiacceltk/HuiPanic.h" |
|
31 |
|
32 #include "uiacceltk/huitextstylemanager.h" // @todo remove when text drawing is moved to THuiFont |
|
33 #include "uiacceltk/huitextstyle.h" // @todo remove when text drawing is moved to THuiFont |
|
34 #include "uiacceltk/huidropshadow.h" |
|
35 #include "uiacceltk/HuiTextureProcessor.h" |
|
36 |
|
37 #include <AknBidiTextUtils.h> |
|
38 #include <AknPictographInterface.h> |
|
39 #include <AknPictographDrawerInterface.h> |
|
40 |
|
41 |
|
42 /** Granularity of line wrapping array. */ |
|
43 const TInt KLineArrayGranularity = 4; |
|
44 |
|
45 enum THuiRasterizeLevel |
|
46 { |
|
47 ERasterizeNone = 0x0, |
|
48 ERasterizeText = 0x1, |
|
49 ERasterizePictographs = 0x2, |
|
50 ERasterizeAll = 0xFFFFFFFF |
|
51 }; |
|
52 |
|
53 EXPORT_C CHuiRasterizedTextMesh* CHuiRasterizedTextMesh::NewL() |
|
54 { |
|
55 CHuiRasterizedTextMesh* self = CHuiRasterizedTextMesh::NewLC(); |
|
56 CleanupStack::Pop(self); |
|
57 return self; |
|
58 } |
|
59 |
|
60 |
|
61 CHuiRasterizedTextMesh* CHuiRasterizedTextMesh::NewLC() |
|
62 { |
|
63 CHuiRasterizedTextMesh* self = new (ELeave) CHuiRasterizedTextMesh(); |
|
64 CleanupStack::PushL(self); |
|
65 self->ConstructL(); |
|
66 return self; |
|
67 } |
|
68 |
|
69 |
|
70 CHuiRasterizedTextMesh::CHuiRasterizedTextMesh() |
|
71 { |
|
72 } |
|
73 |
|
74 CHuiRasterizedTextMesh::~CHuiRasterizedTextMesh() |
|
75 { |
|
76 ResetLines(); |
|
77 iLines.Close(); |
|
78 ResetPictographLines(); |
|
79 iPictographLines.Close(); |
|
80 delete iPictographBitmap; |
|
81 } |
|
82 |
|
83 |
|
84 void CHuiRasterizedTextMesh::Reset() |
|
85 { |
|
86 if (!iUsingPreRasterizedMesh) |
|
87 { |
|
88 CHuiTextMesh::Reset(); |
|
89 ResetLines(); |
|
90 ResetPictographLines(); |
|
91 } |
|
92 } |
|
93 |
|
94 void CHuiRasterizedTextMesh::ResetLines() |
|
95 { |
|
96 HUI_DEBUG(_L("CHuiRasterizedTextMesh::ResetLines() - Deleting textures for all rasterized lines.")); |
|
97 |
|
98 for(TInt i = 0; i < iLines.Count(); ++i) |
|
99 { |
|
100 if (!iUsingPreRasterizedMesh) |
|
101 { |
|
102 delete iLines[i].iTexture; |
|
103 } |
|
104 iLines[i].iTexture = NULL; |
|
105 } |
|
106 |
|
107 iLines.Reset(); |
|
108 } |
|
109 |
|
110 void CHuiRasterizedTextMesh::ResetPictographLines() |
|
111 { |
|
112 HUI_DEBUG(_L("CHuiRasterizedTextMesh::ResetPictographLines() - Deleting textures for all rasterized lines.")); |
|
113 |
|
114 for(TInt i = 0; i < iPictographLines.Count(); ++i) |
|
115 { |
|
116 delete iPictographLines[i].iTexture; iPictographLines[i].iTexture = NULL; |
|
117 } |
|
118 |
|
119 iPictographLines.Reset(); |
|
120 } |
|
121 |
|
122 |
|
123 TBool CHuiRasterizedTextMesh::IsMaxLineCountReached() const |
|
124 { |
|
125 return iLines.Count() >= MaxLineCount(); |
|
126 } |
|
127 |
|
128 |
|
129 TBool CHuiRasterizedTextMesh::RasterizeLineL(const TDesC& aTextLine, SRasterizedLine & aLineOut) |
|
130 { |
|
131 if(iUsingPreRasterizedMesh) |
|
132 { |
|
133 return ETrue; |
|
134 } |
|
135 // Retrieve the used text style. |
|
136 THuiTextStyle* textStyle = CHuiStatic::Env().TextStyleManager().TextStyle(iTextStyleId); |
|
137 |
|
138 // Calculate line extents and assign it to texture size. |
|
139 TSize textureSize = textStyle->LineExtentsL(aTextLine); |
|
140 |
|
141 if(textureSize.iWidth == 0) |
|
142 { |
|
143 // This is an empty string. We will not rasterize it. |
|
144 // Just add a gap. |
|
145 aLineOut.iTexture = NULL; |
|
146 aLineOut.iGap = textureSize.iHeight; // @todo: refacture/rename iGap? iGap is used as a size of an empty line? |
|
147 |
|
148 HUI_DEBUG1(_L("CHuiRasterizedTextMesh::RasterizeLineL() - Added line gap: %i"), |
|
149 aLineOut.iGap); |
|
150 |
|
151 return !IsMaxLineCountReached(); |
|
152 } |
|
153 |
|
154 // Create a texture for storing the text into. |
|
155 if (aLineOut.iTexture == NULL) |
|
156 { |
|
157 HUI_DEBUG1(_L("CHuiRasterizedTextMesh::RasterizeLineL() - Registering self (0x%x) as a texture content observer."), this); |
|
158 aLineOut.iTexture = CHuiTexture::NewL(); |
|
159 // Register one content observer for the first texture that |
|
160 // is able to restore all lines in a single run |
|
161 if (iLines.Count()==1) |
|
162 { |
|
163 aLineOut.iTexture->iContentObservers.AppendL(*this); |
|
164 } |
|
165 aLineOut.iGap = 0; |
|
166 } |
|
167 |
|
168 // set a name for the texture |
|
169 aLineOut.iTexture->SetImageFileNameL(aTextLine); |
|
170 |
|
171 // Rasterize string using the defined text style. |
|
172 textStyle->RasterizeLineL(aTextLine, *aLineOut.iTexture); |
|
173 |
|
174 if ( RasterizedShadow() && aLineOut.iTexture ) |
|
175 { |
|
176 const TInt requestedBlurredSize = HUI_ROUND_FLOAT_TO_INT( 2*iVisual->DropShadowHandler()->iRadius.Now() ); |
|
177 aLineOut.iTexture->CreateShadowTextureL( requestedBlurredSize, EHuiTextureShadowStyleRasterizedText ); |
|
178 } |
|
179 |
|
180 |
|
181 return !IsMaxLineCountReached(); |
|
182 } |
|
183 |
|
184 TBool CHuiRasterizedTextMesh::RasterizePictographLineL(const TDesC& aTextLine, CFont* aFont, SRasterizedLine & aLineOut) |
|
185 { |
|
186 if(iUsingPreRasterizedMesh) |
|
187 { |
|
188 return EFalse; |
|
189 } |
|
190 |
|
191 // Retrieve the used text style. |
|
192 THuiTextStyle* textStyle = CHuiStatic::Env().TextStyleManager().TextStyle(iTextStyleId); |
|
193 |
|
194 // Calculate line extents and assign it to texture size. |
|
195 TSize textureSize = textStyle->LineExtentsL(aTextLine); |
|
196 |
|
197 if(textureSize.iWidth == 0 || !iPictographInterface || !iPictographInterface->Interface()->ContainsPictographs(aTextLine)) |
|
198 { |
|
199 // This is an empty string or it does not contain pictographs. We will not rasterize it. |
|
200 // Just add a gap. |
|
201 aLineOut.iTexture = NULL; |
|
202 aLineOut.iGap = textureSize.iHeight; |
|
203 return !IsMaxLineCountReached(); |
|
204 } |
|
205 |
|
206 // store the actual size to be assigned as the textures logical size |
|
207 TSize actualsize(textureSize); |
|
208 |
|
209 if (aLineOut.iTexture == NULL) |
|
210 { |
|
211 // Create a texture for storing the pictographs into. |
|
212 aLineOut.iTexture = CHuiTexture::NewL(); |
|
213 HUI_DEBUG1(_L("CHuiRasterizedTextMesh::RasterizePictographLineL() - Registering self (0x%x) as a texture content observer."), this); |
|
214 // Register one content observer for the first texture that |
|
215 // is able to restore all lines in a single run |
|
216 if (iLines.Count()==1) |
|
217 { |
|
218 aLineOut.iTexture->iContentObservers.AppendL(*this); |
|
219 } |
|
220 aLineOut.iGap = 0; |
|
221 } |
|
222 |
|
223 // set a name for the texture |
|
224 // @todo is this needed, what names to use |
|
225 aLineOut.iTexture->SetImageFileNameL(_L("Pictographs")); |
|
226 |
|
227 TSize maxTextureSize = aLineOut.iTexture->MaxTextureSize(); |
|
228 textureSize.iWidth = Min(textureSize.iWidth, maxTextureSize.iWidth); |
|
229 textureSize.iHeight = Min(textureSize.iHeight, maxTextureSize.iHeight); |
|
230 |
|
231 if((textureSize.iWidth == 0) || (textureSize.iHeight == 0)) |
|
232 { |
|
233 // Cannot draw into this tiny texture, so leave. |
|
234 HUI_DEBUG2(_L("CHuiRasterizedTextMesh::RasterizePictographLineL() - texture size was too small to draw into (%i, %i)."), textureSize.iWidth, textureSize.iHeight); |
|
235 User::Leave(KErrAbort); |
|
236 } |
|
237 |
|
238 User::LeaveIfError( iPictographBitmap->Resize(textureSize) ); |
|
239 |
|
240 CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(iPictographBitmap); |
|
241 CleanupStack::PushL(device); |
|
242 |
|
243 CFbsBitGc* gc = 0; |
|
244 User::LeaveIfError( device->CreateContext(gc) ); |
|
245 CleanupStack::PushL(gc); |
|
246 |
|
247 // Prepare the bitmap for drawing...set drawmode because of EColor16MA mode... |
|
248 gc->SetDrawMode(CGraphicsContext::EDrawModeWriteAlpha); |
|
249 |
|
250 TRgb color = KRgbWhite; |
|
251 color.SetAlpha(0x00); |
|
252 gc->SetBrushColor(color); |
|
253 gc->Clear(); |
|
254 gc->UseFont(aFont); |
|
255 |
|
256 // Draw pictorgraphs |
|
257 iPictographInterface->Interface()->DrawPictographsInText( |
|
258 *gc, |
|
259 *aFont, |
|
260 aTextLine, TPoint(0, aFont->FontMaxAscent())); |
|
261 |
|
262 CleanupStack::PopAndDestroy(gc); |
|
263 CleanupStack::PopAndDestroy(device); |
|
264 |
|
265 aLineOut.iTexture->UploadL(*iPictographBitmap, NULL, EHuiTextureUploadFlagRetainResolution); |
|
266 aLineOut.iTexture->SetSize(actualsize); |
|
267 return !IsMaxLineCountReached(); |
|
268 } |
|
269 |
|
270 void CHuiRasterizedTextMesh::BuildL(TBool aRasterize) |
|
271 { |
|
272 if (aRasterize) |
|
273 { |
|
274 DoBuildL(ERasterizeAll); |
|
275 } |
|
276 else |
|
277 { |
|
278 DoBuildL(ERasterizeNone); |
|
279 } |
|
280 } |
|
281 |
|
282 void CHuiRasterizedTextMesh::DoBuildL(TInt aRasterizeFlags) |
|
283 { |
|
284 if(iUsingPreRasterizedMesh) |
|
285 { |
|
286 return; |
|
287 } |
|
288 |
|
289 TSize extents(0, 0); |
|
290 |
|
291 HUI_DEBUG(_L("CHuiRasterizedTextMesh::BuildL() - Updating rasterized text.")); |
|
292 |
|
293 // This is never NULL during BuildL(). |
|
294 const TDesC& text = *Text(); |
|
295 |
|
296 // Retrieve the text style used when rasterizing this text mesh. |
|
297 THuiTextStyle* textStyle = CHuiStatic::Env().TextStyleManager().TextStyle(iTextStyleId); |
|
298 |
|
299 // Retrieve the CFont object used when rasterizing this text mesh. |
|
300 CFont* font = textStyle->Font().NearestFontL(iTextMeshScale); |
|
301 |
|
302 // Maximum width of a text line in pixels. |
|
303 TInt maxWidth = MaxLineWidth(); |
|
304 |
|
305 TInt startIndex = 0; |
|
306 TInt index = 0; |
|
307 TInt lineCount = 0; |
|
308 |
|
309 CArrayFixFlat<TPtrC>* linePtrs = new (ELeave) CArrayFixFlat<TPtrC>(KLineArrayGranularity); |
|
310 CleanupStack::PushL(linePtrs); |
|
311 |
|
312 while(startIndex < text.Length()) |
|
313 { |
|
314 /// @todo What is the Symbian way to determine line break chars? |
|
315 #define HUI_IS_LINE_BREAK(aChar) (aChar == '\n') |
|
316 |
|
317 // Find the next logical line. |
|
318 while(index < text.Length() && !HUI_IS_LINE_BREAK(text[index])) |
|
319 { |
|
320 index++; |
|
321 } |
|
322 |
|
323 TPtrC logicalLine = text.Mid(startIndex, index - startIndex); |
|
324 ++index; // Skip the line break. |
|
325 startIndex = index; |
|
326 |
|
327 switch(LineMode()) |
|
328 { |
|
329 case ELineModeTruncate: |
|
330 { |
|
331 ++lineCount; // there's always one line created per logical line |
|
332 HBufC* buf = logicalLine.AllocLC(); |
|
333 TPtr ptr = buf->Des(); |
|
334 // truncate line |
|
335 CHuiStatic::ConvertToVisualAndClipL(ptr, *font, maxWidth, maxWidth); |
|
336 // create the line entry if not already existing |
|
337 |
|
338 if (aRasterizeFlags != ERasterizeNone) |
|
339 { |
|
340 if (iLines.Count() < lineCount) |
|
341 { |
|
342 SRasterizedLine line; |
|
343 line.iTexture = NULL; |
|
344 line.iGap = 0; |
|
345 iLines.AppendL(line); |
|
346 |
|
347 if (iPictographInterface) |
|
348 { |
|
349 SRasterizedLine pictographline; |
|
350 pictographline.iTexture = NULL; |
|
351 pictographline.iGap = 0; |
|
352 iPictographLines.AppendL(pictographline); |
|
353 } |
|
354 } |
|
355 |
|
356 TInt currentLine = lineCount-1; |
|
357 if (aRasterizeFlags & ERasterizeText) |
|
358 { |
|
359 // rasterize a single line (updates texture in iLines[0].iTexture) |
|
360 RasterizeLineL(ptr, iLines[currentLine]); |
|
361 } |
|
362 |
|
363 if (aRasterizeFlags & ERasterizePictographs && iPictographInterface) |
|
364 { |
|
365 // Rasterize pictographs if needed |
|
366 RasterizePictographLineL(ptr, font, iPictographLines[currentLine]); |
|
367 } |
|
368 |
|
369 // Get extents from the texture we just created |
|
370 CHuiTexture* tex = iLines[currentLine].iTexture; |
|
371 extents.iHeight += iLines[currentLine].iGap; |
|
372 if(tex) |
|
373 { |
|
374 extents.iWidth = Max(extents.iWidth, tex->Size().iWidth); |
|
375 extents.iHeight += tex->Size().iHeight; |
|
376 } |
|
377 } |
|
378 else |
|
379 { |
|
380 // Don't rasterise or create textures, just get the extents of this text. |
|
381 TSize lineExtents = textStyle->LineExtentsL(ptr); |
|
382 extents.iWidth = Max(extents.iWidth, lineExtents.iWidth); |
|
383 extents.iHeight += lineExtents.iHeight; |
|
384 } |
|
385 |
|
386 |
|
387 CleanupStack::PopAndDestroy(buf); |
|
388 break; |
|
389 } |
|
390 |
|
391 case ELineModeWrap: |
|
392 { |
|
393 // wrap lines to array |
|
394 HBufC* buf = CHuiStatic::ConvertToVisualAndWrapToArrayL( |
|
395 logicalLine, maxWidth, *font, *linePtrs); |
|
396 CleanupStack::PushL(buf); |
|
397 |
|
398 // one line may create several wrapped lines |
|
399 lineCount += linePtrs->Count(); |
|
400 |
|
401 if (aRasterizeFlags != ERasterizeNone) |
|
402 { |
|
403 |
|
404 // create new entries.. |
|
405 while (iLines.Count() < lineCount) |
|
406 { |
|
407 SRasterizedLine line; |
|
408 line.iTexture = NULL; |
|
409 line.iGap = 0; |
|
410 iLines.AppendL(line); |
|
411 |
|
412 if (iPictographInterface) |
|
413 { |
|
414 SRasterizedLine pictographline; |
|
415 pictographline.iTexture = NULL; |
|
416 pictographline.iGap = 0; |
|
417 iPictographLines.AppendL(pictographline); |
|
418 } |
|
419 } |
|
420 |
|
421 // Do rasterisation if we want to render to texture. |
|
422 for(TInt i = 0; i < linePtrs->Count(); ++i) |
|
423 { |
|
424 TInt currentLine = (lineCount - linePtrs->Count()) + i; |
|
425 |
|
426 if (aRasterizeFlags & ERasterizeText) |
|
427 { |
|
428 // rasterize a single line (updates texture in iLines[i].iTexture) |
|
429 RasterizeLineL(linePtrs->At(i), iLines[currentLine]); |
|
430 } |
|
431 |
|
432 if (aRasterizeFlags & ERasterizePictographs && iPictographInterface) |
|
433 { |
|
434 // Rasterize pictographs if needed |
|
435 RasterizePictographLineL(linePtrs->At(i), font, iPictographLines[currentLine]); |
|
436 } |
|
437 // Get extents from the texture we just created |
|
438 CHuiTexture* tex = iLines[i].iTexture; |
|
439 extents.iHeight += iLines[i].iGap; |
|
440 |
|
441 if(tex) |
|
442 { |
|
443 extents.iWidth = Max(extents.iWidth, tex->Size().iWidth); |
|
444 extents.iHeight += tex->Size().iHeight; |
|
445 } |
|
446 |
|
447 TBool moreAvailable = (currentLine + 1 < MaxLineCount()); |
|
448 if (!moreAvailable) |
|
449 { |
|
450 // Maximum number of lines reached. |
|
451 break; |
|
452 } |
|
453 } |
|
454 } |
|
455 else |
|
456 { |
|
457 // Don't rasterise or create textures, just get the extents of this text. |
|
458 for(TInt i = 0; i < linePtrs->Count(); ++i) |
|
459 { |
|
460 TSize lineExtents = textStyle->LineExtentsL(linePtrs->At(i)); |
|
461 extents.iWidth = Max(extents.iWidth, lineExtents.iWidth); |
|
462 extents.iHeight += lineExtents.iHeight; |
|
463 } |
|
464 } |
|
465 |
|
466 linePtrs->Reset(); |
|
467 CleanupStack::PopAndDestroy(buf); |
|
468 break; |
|
469 } |
|
470 |
|
471 default: |
|
472 break; |
|
473 } |
|
474 |
|
475 // If we have reached the maximum number of lines, stop building. |
|
476 if(IsMaxLineCountReached()) |
|
477 { |
|
478 break; |
|
479 } |
|
480 } |
|
481 |
|
482 HUI_DEBUG(_L("CHuiRasterizedTextMesh::BuildL() - Finished rasterizing text.")); |
|
483 |
|
484 CleanupStack::PopAndDestroy(linePtrs); linePtrs = 0; |
|
485 |
|
486 if (iPictographBitmap) |
|
487 { |
|
488 iPictographBitmap->Resize(TSize(0, 0)); |
|
489 } |
|
490 |
|
491 HUI_DEBUG(_L("CHuiRasterizedTextMesh::BuildL() - Updating text extents..")); |
|
492 // The extents of the mesh depend on how many lines there are. |
|
493 SetExtents(extents); |
|
494 |
|
495 HUI_DEBUG(_L("CHuiRasterizedTextMesh::BuildL() - Done!")); |
|
496 |
|
497 } |
|
498 |
|
499 void CHuiRasterizedTextMesh::ExpandRectWithShadow(TRect& aRect) const |
|
500 { |
|
501 if ( iVisual && iLines.Count() ) |
|
502 { |
|
503 CHuiDropShadow* shadowHandler = iVisual->DropShadowHandler(); |
|
504 if ( shadowHandler && |
|
505 shadowHandler->IsShadowVisible() && |
|
506 iLines[0].iTexture ) |
|
507 { |
|
508 const TInt requestedBlurredSize = HUI_ROUND_FLOAT_TO_INT( 2*shadowHandler->iRadius.Now() ); |
|
509 THuiTextureHandle shadow; |
|
510 // take the first line as an example |
|
511 TBool haveShadowTexture = iLines[0].iTexture->GetShadowTexture( shadow,requestedBlurredSize ); |
|
512 |
|
513 if ( haveShadowTexture ) |
|
514 { |
|
515 const TRect shadowRect = shadowHandler->ShadowDrawingTRect( |
|
516 aRect.iTl, |
|
517 aRect.Size(), |
|
518 shadow.Size(), |
|
519 *iVisual ); |
|
520 |
|
521 aRect.BoundingRect( shadowRect ); |
|
522 } |
|
523 } |
|
524 } |
|
525 } |
|
526 |
|
527 |
|
528 void CHuiRasterizedTextMesh::Draw(CHuiGc& aGc, TReal32 aShadowOpacity) const __SOFTFP |
|
529 { |
|
530 THuiAlignHorizontal oldHorizAlign = aGc.AlignHorizontal(); |
|
531 THuiAlignVertical oldVertAlign = aGc.AlignVertical(); |
|
532 |
|
533 // Because we are using DrawImage, which respects Gc alignments, and the |
|
534 // context has already set up the appropriate alignment offset, we must |
|
535 // disable the alignment temporarily. |
|
536 aGc.SetAlign(EHuiAlignHLeft, EHuiAlignVTop); |
|
537 |
|
538 |
|
539 // The actual text. |
|
540 DrawLines(aGc, THuiRealPoint(0.f, 0.f), oldHorizAlign, aShadowOpacity); |
|
541 |
|
542 if(!iUsingPreRasterizedMesh) |
|
543 { |
|
544 // Pictographs, if needed. |
|
545 DrawPictographLines(aGc, THuiRealPoint(0.f, 0.f), oldHorizAlign); |
|
546 } |
|
547 |
|
548 aGc.SetAlign(oldHorizAlign, oldVertAlign); |
|
549 } |
|
550 |
|
551 |
|
552 void CHuiRasterizedTextMesh::DrawLines(CHuiGc& aGc, const THuiRealPoint& aOffset, |
|
553 THuiAlignHorizontal aLineAlignment, TReal32 aShadowOpacity) const |
|
554 { |
|
555 TInt y = 0; |
|
556 |
|
557 // Draw the built lines using THuiImages. |
|
558 for(TInt i = 0; i < iLines.Count(); ++i) |
|
559 { |
|
560 const SRasterizedLine& line = iLines[i]; |
|
561 if(line.iTexture) |
|
562 { |
|
563 |
|
564 THuiImage textImage(*line.iTexture); |
|
565 THuiRealPoint linePos(0.f, TReal32(y)); |
|
566 THuiRealSize lineSize = line.iTexture->Size(); |
|
567 |
|
568 // Do a downward scaling for line texture from TV resolution to LCD resolution. |
|
569 if(iTextMeshScale != 1) |
|
570 { |
|
571 lineSize.iHeight = lineSize.iHeight/iTextMeshScale; |
|
572 lineSize.iWidth = lineSize.iWidth/iTextMeshScale; |
|
573 } |
|
574 |
|
575 // Choose the line-specific alignment. |
|
576 switch(aLineAlignment) |
|
577 { |
|
578 case EHuiAlignHRight: |
|
579 linePos.iX = Extents().iWidth - lineSize.iWidth; |
|
580 break; |
|
581 |
|
582 case EHuiAlignHCenter: |
|
583 linePos.iX = (Extents().iWidth - lineSize.iWidth) / 2; |
|
584 break; |
|
585 |
|
586 default: |
|
587 break; |
|
588 } |
|
589 |
|
590 |
|
591 // Is there a shadow? |
|
592 if ( RasterizedShadow() ) |
|
593 { |
|
594 const TInt requestedBlurredSize = HUI_ROUND_FLOAT_TO_INT( 2*iVisual->DropShadowHandler()->iRadius.Now() ); |
|
595 THuiTextureHandle shadow; |
|
596 TBool haveShadowTexture = line.iTexture->GetShadowTexture(shadow,requestedBlurredSize ); |
|
597 |
|
598 if ( haveShadowTexture ) |
|
599 { |
|
600 THuiImage shadowImage(shadow); |
|
601 const THuiRealRect shadowDrawingRect = iVisual->DropShadowHandler()->ShadowDrawingRealRect( |
|
602 linePos, |
|
603 lineSize, |
|
604 shadow.Size(), |
|
605 *iVisual ); |
|
606 |
|
607 const TRgb oldColor = aGc.PenColorAlpha(); |
|
608 aGc.SetPenColor(iVisual->DropShadowHandler()->Color()); |
|
609 aGc.SetPenAlpha(HUI_ROUND_FLOAT_TO_INT(aShadowOpacity * 255.0f)); |
|
610 |
|
611 const THuiQuality oldQuality = aGc.Quality(); |
|
612 aGc.SetQuality(EHuiQualityFast); |
|
613 |
|
614 aGc.DrawImage(shadowImage, shadowDrawingRect.iTl + aOffset, shadowDrawingRect.Size()); |
|
615 |
|
616 aGc.SetPenColorAlpha(oldColor); |
|
617 aGc.SetQuality(oldQuality); |
|
618 } |
|
619 } |
|
620 |
|
621 aGc.DrawImage(textImage, linePos + aOffset, lineSize); |
|
622 |
|
623 // Move one line downwards. |
|
624 y += TInt(lineSize.iHeight) + line.iGap; |
|
625 } |
|
626 |
|
627 // Move extra gap downwards. |
|
628 y += line.iGap; |
|
629 |
|
630 // Add line spacing. |
|
631 y += iLineSpacing; |
|
632 } |
|
633 } |
|
634 |
|
635 void CHuiRasterizedTextMesh::DrawPictographLines(CHuiGc& aGc, const THuiRealPoint& aOffset, |
|
636 THuiAlignHorizontal aLineAlignment) const |
|
637 { |
|
638 if (!iPictographInterface || iUsingPreRasterizedMesh) |
|
639 { |
|
640 return; |
|
641 } |
|
642 |
|
643 |
|
644 TInt y = 0; |
|
645 |
|
646 // Draw the built lines using THuiImages. |
|
647 for(TInt i = 0; i < iPictographLines.Count(); ++i) |
|
648 { |
|
649 const SRasterizedLine& line = iPictographLines[i]; |
|
650 if(line.iTexture) |
|
651 { |
|
652 |
|
653 THuiImage textImage(*line.iTexture); |
|
654 THuiRealPoint linePos(0.f, TReal32(y)); |
|
655 THuiRealSize lineSize = line.iTexture->Size(); |
|
656 |
|
657 // Choose the line-specific alignment. |
|
658 switch(aLineAlignment) |
|
659 { |
|
660 case EHuiAlignHRight: |
|
661 linePos.iX = Extents().iWidth - lineSize.iWidth; |
|
662 break; |
|
663 |
|
664 case EHuiAlignHCenter: |
|
665 linePos.iX = (Extents().iWidth - lineSize.iWidth) / 2; |
|
666 break; |
|
667 |
|
668 default: |
|
669 break; |
|
670 } |
|
671 |
|
672 aGc.SetPenColor(KRgbWhite); |
|
673 aGc.DrawImage(textImage, linePos + aOffset, lineSize); |
|
674 |
|
675 // Move one line downwards. |
|
676 y += TInt(lineSize.iHeight) + line.iGap; |
|
677 } |
|
678 |
|
679 // Move extra gap downwards. |
|
680 y += line.iGap; |
|
681 |
|
682 // Add line spacing. |
|
683 y += iLineSpacing; |
|
684 } |
|
685 } |
|
686 |
|
687 |
|
688 void CHuiRasterizedTextMesh::TextureContentUploaded(CHuiTexture& /*aTexture*/) |
|
689 { |
|
690 } |
|
691 |
|
692 |
|
693 void CHuiRasterizedTextMesh::TextureContentReleased(CHuiTexture& /*aTexture*/) |
|
694 { |
|
695 } |
|
696 |
|
697 |
|
698 void CHuiRasterizedTextMesh::RestoreTextureContentL(CHuiTexture& /*aTexture*/) |
|
699 { |
|
700 // We only get one of these, so let's rebuild the text mesh. |
|
701 HUI_DEBUG(_L("CHuiRasterizedTextMesh::RestoreTextureContentL() - Rebuilding text.")); |
|
702 |
|
703 // We want to render the mesh so pass true. |
|
704 BuildL(ETrue); |
|
705 } |
|
706 void CHuiRasterizedTextMesh::InitPictographsL(CAknPictographInterface* aInterface) |
|
707 { |
|
708 if(!iUsingPreRasterizedMesh) |
|
709 { |
|
710 iPictographInterface = aInterface; |
|
711 delete iPictographBitmap; |
|
712 iPictographBitmap = NULL; |
|
713 iPictographBitmap = new (ELeave) CFbsBitmap(); |
|
714 User::LeaveIfError( iPictographBitmap->Create(TSize(0, 0), EColor16MA) ); |
|
715 } |
|
716 } |
|
717 |
|
718 void CHuiRasterizedTextMesh::BuildPictographsL() |
|
719 { |
|
720 if(!iUsingPreRasterizedMesh) |
|
721 { |
|
722 DoBuildL(ERasterizePictographs); |
|
723 } |
|
724 } |
|
725 |
|
726 void CHuiRasterizedTextMesh::UpdateMeshL(const TDesC8& aBuffer) |
|
727 { |
|
728 iUsingPreRasterizedMesh = ETrue; |
|
729 ResetLines(); |
|
730 RDesReadStream stream(aBuffer); |
|
731 TInt count = stream.ReadInt32L(); |
|
732 for (TInt i=count-1;i>=0;i--) |
|
733 { |
|
734 // lines are in reverse order |
|
735 SRasterizedLine line; |
|
736 line.iTexture = dynamic_cast<CHuiTexture*>((MHuiTexture*)stream.ReadInt32L()); //scary |
|
737 line.iGap = stream.ReadInt32L(); |
|
738 iLines.InsertL(line, 0); |
|
739 } |
|
740 TSize extents; |
|
741 extents.iWidth = stream.ReadInt32L(); |
|
742 extents.iHeight = stream.ReadInt32L(); |
|
743 SetExtents(extents); |
|
744 stream.Close(); |
|
745 |
|
746 if (RasterizedShadow()) // update shadow |
|
747 { |
|
748 for (TInt i = iLines.Count()-1; i >=0; i-- ) |
|
749 { |
|
750 if (iLines[i].iTexture) |
|
751 { |
|
752 const TInt requestedBlurredSize = HUI_ROUND_FLOAT_TO_INT( 2*iVisual->DropShadowHandler()->iRadius.Now() ); |
|
753 iLines[i].iTexture->CreateShadowTextureL( requestedBlurredSize, EHuiTextureShadowStyleRasterizedText ); |
|
754 } |
|
755 } |
|
756 } |
|
757 } |
|
758 |