|
1 /* |
|
2 * Copyright (c) 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: Visual aligning class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 //<cmail> removed __FS_ALFRED_SUPPORT flag |
|
20 //#include <fsconfig.h> |
|
21 //</cmail> removed __FS_ALFRED_SUPPORT flag |
|
22 #include "emailtrace.h" |
|
23 #include <gdi.h> |
|
24 #include <w32std.h> |
|
25 // <cmail> SF |
|
26 #include <alf/alfenv.h> |
|
27 #include <alf/alftextstyle.h> |
|
28 #include <alf/alftextstylemanager.h> |
|
29 // </cmail> |
|
30 #include <AknLayoutFont.h> |
|
31 #include <AknFontAccess.h> |
|
32 #include <AknBidiTextUtils.h> |
|
33 // <cmail> |
|
34 #include <alf/alftextvisual.h> |
|
35 // </cmail> |
|
36 |
|
37 #include "fstextviewervisualizer.h" |
|
38 |
|
39 #include "fstextviewerlayouter.h" |
|
40 #include "fsrichtextobject.h" |
|
41 #include "fstextstylemanager.h" |
|
42 #include "fsrichtext.h" |
|
43 #include "fsrichtexttext.h" |
|
44 #include "fsrichtextsmiley.h" |
|
45 #include "fsrichtextpicture.h" |
|
46 #include "fstextviewercoordinator.h" |
|
47 #include "fstextviewervisualizerdata.h" |
|
48 #include "fstextparser.h" |
|
49 |
|
50 // --------------------------------------------------------------------------- |
|
51 // NewL |
|
52 // --------------------------------------------------------------------------- |
|
53 CFsTextViewerLayouter* CFsTextViewerLayouter::NewL( CAlfEnv* aEnv ) |
|
54 { |
|
55 FUNC_LOG; |
|
56 CFsTextViewerLayouter* self = |
|
57 new (ELeave) CFsTextViewerLayouter( aEnv ); |
|
58 CleanupStack::PushL( self ); |
|
59 self->ConstructL(); |
|
60 CleanupStack::Pop( self ); |
|
61 return self; |
|
62 } |
|
63 |
|
64 // --------------------------------------------------------------------------- |
|
65 // ~CFsTextViewerLayouter |
|
66 // --------------------------------------------------------------------------- |
|
67 CFsTextViewerLayouter::~CFsTextViewerLayouter() |
|
68 { |
|
69 FUNC_LOG; |
|
70 iCurrentLineArray.Close(); |
|
71 } |
|
72 |
|
73 // --------------------------------------------------------------------------- |
|
74 // MeasureBidiTextBoundsWidth |
|
75 // --------------------------------------------------------------------------- |
|
76 TInt CFsTextViewerLayouter::MeasureBidiTextBoundsWidth( |
|
77 const CFont& aFont, |
|
78 const TDesC& aText, |
|
79 CFont::TMeasureTextInput::TFlags aOrder) |
|
80 { |
|
81 FUNC_LOG; |
|
82 // return AknBidiTextUtils::MeasureTextBoundsWidth( aFont, aText, aOrder); |
|
83 CFont::TMeasureTextInput input; |
|
84 input.iFlags = aOrder; |
|
85 CFont::TMeasureTextOutput output; |
|
86 |
|
87 TInt textAdvance = aFont.MeasureText( aText, &input, &output ); |
|
88 |
|
89 TRect bounds = output.iBounds; |
|
90 bounds.iTl.iX = Min(bounds.iTl.iX, 0); |
|
91 bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance); |
|
92 return bounds.Width(); |
|
93 } |
|
94 |
|
95 |
|
96 // --------------------------------------------------------------------------- |
|
97 // CalculateSizeL |
|
98 // --------------------------------------------------------------------------- |
|
99 TSize CFsTextViewerLayouter::CalculateSizeL( MFsRichTextObject* aObject ) |
|
100 { |
|
101 FUNC_LOG; |
|
102 TSize retVal; |
|
103 |
|
104 switch ( aObject->GetType() ) |
|
105 { |
|
106 case MFsRichTextObject::EFsText: |
|
107 { |
|
108 if ( static_cast<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 ) |
|
109 { |
|
110 CAlfTextVisual* tmp = CAlfTextVisual::AddNewL( *iControl, iVisualizer->BackgroundLayout() ); |
|
111 tmp->SetTextL( static_cast<CFsRichTextText*>(aObject)->GetText() ); |
|
112 tmp->SetTextStyle( static_cast<CFsRichTextText*>(aObject)->GetStyleId() ); |
|
113 tmp->SetAlign( EAlfAlignHLeft, EAlfAlignVTop ); |
|
114 tmp->SetPadding( 0 ); |
|
115 // retVal = tmp->SubstringExtents( 0, static_cast<CFsRichTextText*>(aObject)->GetText().Length() - 1 ).Size(); |
|
116 retVal = tmp->TextExtents(); |
|
117 // <cmail> Platform layout change |
|
118 //retVal.iWidth -= 4; |
|
119 // </cmail> Platform layout change |
|
120 tmp->RemoveAndDestroyAllD(); |
|
121 break; |
|
122 } |
|
123 |
|
124 CFont* font; |
|
125 User::LeaveIfNull( iScreenDev ); |
|
126 |
|
127 CAlfTextStyle* textStyle( |
|
128 iEnv->TextStyleManager().TextStyle( |
|
129 static_cast<CFsRichTextText*>(aObject)->GetStyleId() ) ); |
|
130 |
|
131 HBufC* typeface( textStyle->TypefaceNameL() ); |
|
132 CleanupStack::PushL( typeface ); |
|
133 TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); |
|
134 if ( textStyle->IsBold() ) |
|
135 { |
|
136 fontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold ); |
|
137 } |
|
138 if ( textStyle->IsItalic() ) |
|
139 { |
|
140 fontSpec.iFontStyle.SetPosture( EPostureItalic ); |
|
141 } |
|
142 |
|
143 User::LeaveIfError( |
|
144 iScreenDev->GetNearestFontInTwips( |
|
145 font, fontSpec ) ); |
|
146 |
|
147 // TAknFontSpecification aknFs(EAknFontCategoryPrimary, fontSpec, iScreenDev); |
|
148 // aknFs.SetTextPaneHeight( iScreenDev->VerticalTwipsToPixels(fontSpec.iHeight)); |
|
149 // aknFs.SetTextPaneHeightIsDesignHeight( ETrue ); |
|
150 // font = |
|
151 // AknFontAccess::CreateLayoutFontFromSpecificationL( |
|
152 // *iScreenDev, |
|
153 // fontSpec.iTypeface, |
|
154 // aknFs ); |
|
155 |
|
156 |
|
157 // retVal = TSize( |
|
158 // font->TextWidthInPixels( |
|
159 // static_cast<CFsRichTextText*>(aObject)->GetText() ), |
|
160 // font->FontMaxHeight() ); |
|
161 |
|
162 CleanupStack::PopAndDestroy( typeface ); |
|
163 TSize retVal1( MeasureBidiTextBoundsWidth( *font, static_cast<CFsRichTextText*>(aObject)->GetText(), CFont::TMeasureTextInput::EFVisualOrder), font->FontMaxHeight() ); |
|
164 |
|
165 retVal = retVal1; |
|
166 |
|
167 const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( font ); |
|
168 if ( layoutFont ) |
|
169 { |
|
170 retVal.iHeight = font->HeightInPixels(); |
|
171 TInt textPaneHeight = layoutFont->TextPaneHeight(); |
|
172 TInt textPaneTopToBaseline = layoutFont->TextPaneTopToBaseline(); |
|
173 |
|
174 retVal.iHeight += textPaneHeight - textPaneTopToBaseline; |
|
175 retVal.iHeight += 1; |
|
176 } |
|
177 else |
|
178 { |
|
179 retVal.iHeight = Max(retVal.iHeight, font->HeightInPixels()); |
|
180 retVal.iHeight += 5; // the best approximation - fails on big (>=72) fonts |
|
181 } |
|
182 iScreenDev->ReleaseFont( font ); |
|
183 // if ( static_cast<CFsRichTextText*>(aObject)->GetHotSpot() && static_cast<CFsRichTextText*>(aObject)->GetText().Length() > 1 ) |
|
184 // { |
|
185 // retVal.iWidth += 3; |
|
186 // } |
|
187 break; |
|
188 } |
|
189 case MFsRichTextObject::EFsTexture: |
|
190 { |
|
191 retVal = static_cast<CFsRichTextPicture*> |
|
192 (aObject)->GetTextureSize(); |
|
193 retVal.iWidth += 3; |
|
194 break; |
|
195 } |
|
196 case MFsRichTextObject::EFsSmiley: |
|
197 { |
|
198 if ( iSmileyEnabled ) |
|
199 { |
|
200 retVal = static_cast<CFsRichTextSmiley*> |
|
201 (aObject)->GetPictureObject()->GetTextureSize(); |
|
202 } |
|
203 else |
|
204 { |
|
205 CFont* font; |
|
206 CFsRichTextText* object = |
|
207 static_cast<CFsRichTextSmiley*> |
|
208 (aObject)->GetTextObject(); |
|
209 User::LeaveIfNull(iScreenDev); |
|
210 |
|
211 CAlfTextStyle* textStyle( |
|
212 iEnv->TextStyleManager().TextStyle( |
|
213 object->GetStyleId() ) ); |
|
214 |
|
215 HBufC* typeface( textStyle->TypefaceNameL() ); |
|
216 CleanupStack::PushL( typeface ); |
|
217 TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); |
|
218 |
|
219 User::LeaveIfError( |
|
220 iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); |
|
221 |
|
222 retVal = TSize( |
|
223 font->TextWidthInPixels( object->GetText() ), |
|
224 font->FontMaxHeight() ); |
|
225 iScreenDev->ReleaseFont( font ); |
|
226 CleanupStack::PopAndDestroy( typeface ); |
|
227 break; |
|
228 } |
|
229 } |
|
230 default: |
|
231 { |
|
232 break; |
|
233 } |
|
234 } |
|
235 return retVal; |
|
236 } |
|
237 |
|
238 // --------------------------------------------------------------------------- |
|
239 // FindMaxLengthL |
|
240 // --------------------------------------------------------------------------- |
|
241 TInt CFsTextViewerLayouter::FindMaxLengthL( MFsRichTextObject* aObject ) |
|
242 { |
|
243 FUNC_LOG; |
|
244 TInt retVal = 0; |
|
245 if ( aObject->GetType() == MFsRichTextObject::EFsText ) |
|
246 { |
|
247 CFont* font; |
|
248 User::LeaveIfNull( iScreenDev ); |
|
249 |
|
250 CAlfTextStyle* textStyle( |
|
251 iEnv->TextStyleManager().TextStyle( |
|
252 static_cast<CFsRichTextText*>( aObject )->GetStyleId() ) ); |
|
253 |
|
254 HBufC* typeface( textStyle->TypefaceNameL() ); |
|
255 CleanupStack::PushL( typeface ); |
|
256 TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); |
|
257 |
|
258 User::LeaveIfError( |
|
259 iScreenDev->GetNearestFontInTwips( |
|
260 font, fontSpec ) ); |
|
261 |
|
262 retVal = font->TextCount( static_cast<CFsRichTextText*>(aObject)->GetText(), iDisplaySize.iWidth ) - 1; |
|
263 iScreenDev->ReleaseFont( font ); |
|
264 CleanupStack::PopAndDestroy( typeface ); |
|
265 } |
|
266 return retVal; |
|
267 } |
|
268 |
|
269 // --------------------------------------------------------------------------- |
|
270 // PrepareRangedVisL |
|
271 // --------------------------------------------------------------------------- |
|
272 TFsRangedVisual* CFsTextViewerLayouter::PrepareRangedVisL( |
|
273 MFsRichTextObject* aObject, |
|
274 CAlfLayout* aLayout ) |
|
275 { |
|
276 FUNC_LOG; |
|
277 TFsRangedVisual* retVal = new (ELeave) TFsRangedVisual; |
|
278 retVal->iVisual = NULL; |
|
279 retVal->iHotspot = EFalse; |
|
280 retVal->iEmbed = EFalse; |
|
281 |
|
282 switch ( aObject->GetType() ) |
|
283 { |
|
284 case MFsRichTextObject::EFsText: |
|
285 { |
|
286 retVal->iStart = aObject->GetBeginOfObject(); |
|
287 retVal->iEnd = aObject->GetEndOfObject(); |
|
288 retVal->iIsActive = ETrue; |
|
289 retVal->iLayout = aLayout; |
|
290 retVal->iIsText = ETrue; |
|
291 retVal->iTextColor = |
|
292 static_cast<CFsRichTextText*>(aObject)->GetTextColor(); |
|
293 retVal->iTextStyleId = static_cast<CFsRichTextText*>(aObject)->GetStyleId(); |
|
294 retVal->iDirection = |
|
295 static_cast<CFsRichTextText*>(aObject)->GetTextDirection(); |
|
296 retVal->iSmiley = EFalse; |
|
297 break; |
|
298 } |
|
299 case MFsRichTextObject::EFsTexture: |
|
300 { |
|
301 retVal->iStart = aObject->GetBeginOfObject(); |
|
302 retVal->iEnd = aObject->GetEndOfObject(); |
|
303 retVal->iIsActive = ETrue; |
|
304 retVal->iLayout = aLayout; |
|
305 retVal->iIsText = EFalse; |
|
306 retVal->iSmiley = EFalse; |
|
307 break; |
|
308 } |
|
309 case MFsRichTextObject::EFsSmiley: |
|
310 { |
|
311 if ( iSmileyEnabled ) |
|
312 { |
|
313 retVal->iStart = aObject->GetBeginOfObject(); |
|
314 retVal->iEnd = aObject->GetEndOfObject(); |
|
315 retVal->iIsActive = ETrue; |
|
316 retVal->iLayout = aLayout; |
|
317 retVal->iIsText = EFalse; |
|
318 retVal->iTextColor = |
|
319 static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor(); |
|
320 retVal->iTextStyleId = |
|
321 static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetStyleId(); |
|
322 } |
|
323 else |
|
324 { |
|
325 retVal->iStart = aObject->GetBeginOfObject(); |
|
326 retVal->iEnd = aObject->GetEndOfObject(); |
|
327 retVal->iIsActive = ETrue; |
|
328 retVal->iLayout = aLayout; |
|
329 retVal->iIsText = ETrue; |
|
330 retVal->iTextColor = |
|
331 static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetTextColor(); |
|
332 retVal->iTextStyleId = |
|
333 static_cast<CFsRichTextSmiley*>(aObject)->GetTextObject()->GetStyleId(); |
|
334 } |
|
335 retVal->iSmiley = ETrue; |
|
336 break; |
|
337 } |
|
338 case MFsRichTextObject::EFsNewLine: |
|
339 { |
|
340 break; |
|
341 } |
|
342 default: |
|
343 { |
|
344 break; |
|
345 } |
|
346 } |
|
347 |
|
348 if ( retVal->iIsActive ) |
|
349 { |
|
350 if ( aObject->GetEmbeded() ) |
|
351 { |
|
352 retVal->iId = aObject->GetIdOfEmbeded(); |
|
353 retVal->iEmbed = ETrue; |
|
354 } |
|
355 if ( aObject->GetHotSpot() ) |
|
356 { |
|
357 retVal->iHotspotType = aObject->GetTypeOfHotSpot(); |
|
358 retVal->iId = aObject->GetIdOfHotSpot(); |
|
359 retVal->iHotspot = ETrue; |
|
360 } |
|
361 } |
|
362 |
|
363 return retVal; |
|
364 } |
|
365 |
|
366 // --------------------------------------------------------------------------- |
|
367 // SetDisplaySize |
|
368 // --------------------------------------------------------------------------- |
|
369 void CFsTextViewerLayouter::SetDisplaySize( TSize aDisplaySize ) |
|
370 { |
|
371 FUNC_LOG; |
|
372 iDisplaySize = aDisplaySize; |
|
373 } |
|
374 |
|
375 // --------------------------------------------------------------------------- |
|
376 // AppendObjectL |
|
377 // --------------------------------------------------------------------------- |
|
378 TBool CFsTextViewerLayouter::AppendObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects ) |
|
379 { |
|
380 FUNC_LOG; |
|
381 TRect objectRect; |
|
382 TRect naturalRect; |
|
383 TSize objectSize = CalculateSizeL( aObject ); |
|
384 |
|
385 if ( objectSize.iWidth > iDisplaySize.iWidth ) |
|
386 { |
|
387 if ( iLowestPicPosition > iCurrentLineOffset ) |
|
388 { |
|
389 iCurrentLineOffset = iLowestPicPosition; |
|
390 ConstructLineL(); |
|
391 } |
|
392 if ( aObject->GetType() != MFsRichTextObject::EFsText ) |
|
393 { |
|
394 // Resizing object to fit display width |
|
395 const TInt KScalingFactor = 65536; |
|
396 const TInt KTwo = 2; |
|
397 |
|
398 TInt resizeFactor = KScalingFactor * iDisplaySize.iWidth / |
|
399 objectSize.iWidth; |
|
400 TInt height = objectSize.iHeight; |
|
401 |
|
402 objectSize.iWidth = iDisplaySize.iWidth; |
|
403 |
|
404 height = height * resizeFactor + KScalingFactor / KTwo; |
|
405 objectSize.iHeight = height / KScalingFactor; |
|
406 } |
|
407 else |
|
408 { |
|
409 aParser->CutWord( |
|
410 aObject->GetBeginOfObject(), |
|
411 FindMaxLengthL( aObject ) ); |
|
412 return EFalse; |
|
413 } |
|
414 } |
|
415 |
|
416 TFsRangedVisual* currentVisual; |
|
417 currentVisual = PrepareRangedVisL( aObject, aLayout ); |
|
418 if ( !aRegisterSelects ) |
|
419 { |
|
420 currentVisual->iEmbed = EFalse; |
|
421 } |
|
422 |
|
423 if ( iMainDirection == TBidiText::ELeftToRight ) |
|
424 { |
|
425 objectRect = TRect( TPoint( iLastCol, iCurrentLineOffset ), objectSize ); |
|
426 } |
|
427 else |
|
428 { |
|
429 objectRect = TRect( TPoint( iLastCol - objectSize.iWidth, iCurrentLineOffset ), objectSize ); |
|
430 } |
|
431 iNewLine = EFalse; |
|
432 naturalRect = objectRect; |
|
433 if ( iHelper->NextFreeCol( objectRect, iMainDirection ) ) |
|
434 { |
|
435 ConstructLineL(); |
|
436 delete currentVisual; |
|
437 currentVisual = NULL; |
|
438 AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
439 } |
|
440 else |
|
441 { |
|
442 if ( objectRect != naturalRect ) |
|
443 { |
|
444 currentVisual->iMoved = ETrue; |
|
445 } |
|
446 else |
|
447 { |
|
448 currentVisual->iMoved = EFalse; |
|
449 } |
|
450 |
|
451 if ( iMainDirection == TBidiText::ELeftToRight ) |
|
452 { |
|
453 currentVisual->iRect = objectRect; |
|
454 iLastCol = objectRect.iBr.iX; |
|
455 iCurrentLineArray.Append( currentVisual ); |
|
456 } |
|
457 else |
|
458 { |
|
459 currentVisual->iRect = objectRect; |
|
460 iLastCol = objectRect.iTl.iX; |
|
461 iCurrentLineArray.Append( currentVisual ); |
|
462 } |
|
463 } |
|
464 if ( objectRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) |
|
465 { |
|
466 iLineHeight = objectRect.Height(); |
|
467 } |
|
468 else if ( aObject->GetType() == MFsRichTextObject::EFsTexture || aObject->GetHotSpot() ) |
|
469 { |
|
470 iHelper->RegisterObstacleL( objectRect ); |
|
471 if ( objectRect.iBr.iY > iLowestPicPosition ) |
|
472 { |
|
473 iLowestPicPosition = objectRect.iBr.iY; |
|
474 } |
|
475 } |
|
476 // if ( text ) |
|
477 // { |
|
478 // delete text; |
|
479 // } |
|
480 return ETrue; |
|
481 } |
|
482 |
|
483 // --------------------------------------------------------------------------- |
|
484 // InsertObjectL |
|
485 // --------------------------------------------------------------------------- |
|
486 TBool CFsTextViewerLayouter::InsertObjectL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TBool aRegisterSelects ) |
|
487 { |
|
488 FUNC_LOG; |
|
489 return AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
490 //<cmail> following lines are commented out to avoid warnings |
|
491 /* |
|
492 TBool retVal = EFalse; |
|
493 |
|
494 TSize objectSize = CalculateSizeL( aObject ); |
|
495 if ( objectSize.iWidth > iDisplaySize.iWidth ) |
|
496 { |
|
497 aParser->CutWord( |
|
498 aObject->GetBeginOfObject(), |
|
499 FindMaxLengthL( aObject ) ); |
|
500 return EFalse; |
|
501 } |
|
502 |
|
503 if ( ( objectSize.iWidth > iDisplaySize.iWidth - iLastCol && iMainDirection == TBidiText::ELeftToRight ) |
|
504 || ( objectSize.iWidth > iLastCol && iMainDirection == TBidiText::ERightToLeft ) ) |
|
505 { |
|
506 ConstructLineL(); |
|
507 retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
508 } |
|
509 else //if ( 0 == iCurrentLineArray.Count() ) |
|
510 { |
|
511 retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
512 }*/ |
|
513 //</cmail> |
|
514 // else |
|
515 // { |
|
516 // if ( iMainDirection == TBidiText::ELeftToRight ) |
|
517 // { |
|
518 //// retVal = ReorderLineFromLeftL( aObject, aLayout, aParser, objectSize, aRegisterSelects ); |
|
519 // } |
|
520 // else |
|
521 // { |
|
522 //// retVal = ReorderLineFromRightL( aObject, aLayout, aParser, objectSize, aRegisterSelects ); |
|
523 // } |
|
524 // } |
|
525 //<cmail> following lines are commented out to avoid warnings |
|
526 //return retVal; |
|
527 //</cmail> |
|
528 } |
|
529 |
|
530 // --------------------------------------------------------------------------- |
|
531 // ConstructLineL |
|
532 // --------------------------------------------------------------------------- |
|
533 void CFsTextViewerLayouter::ConstructLineL( TInt aHeight ) |
|
534 { |
|
535 FUNC_LOG; |
|
536 TInt i = 0; |
|
537 TInt dY; |
|
538 RPointerArray<TFsRangedVisual> finalLine; |
|
539 |
|
540 if ( 0 == iLineHeight ) |
|
541 { |
|
542 iLineHeight = aHeight; |
|
543 } |
|
544 |
|
545 for ( i = 0; i < iCurrentLineArray.Count(); ++i ) |
|
546 { |
|
547 iCurrentLineArray[i]->iLineNumber = iLines; |
|
548 if ( iCurrentLineArray[i]->iIsText ) |
|
549 { |
|
550 dY = iLineHeight - iCurrentLineArray[i]->iRect.Height(); |
|
551 iCurrentLineArray[i]->iRect.iTl.iY += dY; |
|
552 iCurrentLineArray[i]->iRect.iBr.iY += dY; |
|
553 } |
|
554 if ( i > 0 |
|
555 && iCurrentLineArray[i]->iIsText |
|
556 && finalLine[finalLine.Count() - 1]->iIsText |
|
557 // && iCurrentLineArray[i]->iDirection == finalLine[finalLine.Count() - 1]->iDirection |
|
558 // && iCurrentLineArray[i]->iDirection == iMainDirection |
|
559 && iCurrentLineArray[i]->iTextStyleId == finalLine[finalLine.Count() - 1]->iTextStyleId |
|
560 && iCurrentLineArray[i]->iTextColor == finalLine[finalLine.Count() - 1]->iTextColor |
|
561 && ( !iCurrentLineArray[i]->iHotspot |
|
562 || |
|
563 iCurrentLineArray[i]->iId == finalLine[finalLine.Count() - 1]->iId |
|
564 ) |
|
565 // && !finalLine[finalLine.Count() - 1]->iHotspot |
|
566 && !iCurrentLineArray[i]->iMoved |
|
567 // && !iCurrentLineArray[i]->iEmbed |
|
568 // && !finalLine[finalLine.Count() - 1]->iEmbed |
|
569 ) |
|
570 |
|
571 { |
|
572 JoinRangedVisuals( finalLine[finalLine.Count() - 1], iCurrentLineArray[i] ); |
|
573 delete iCurrentLineArray[i]; |
|
574 iCurrentLineArray[i] = NULL; |
|
575 } |
|
576 else |
|
577 { |
|
578 finalLine.Append( iCurrentLineArray[i] ); |
|
579 } |
|
580 } |
|
581 |
|
582 for ( i = 0; i < finalLine.Count(); ++i ) |
|
583 { |
|
584 iNavigator->AppendVisualL( finalLine[i] ); |
|
585 } |
|
586 finalLine.Close(); |
|
587 |
|
588 if ( iMainDirection == TBidiText::ELeftToRight ) |
|
589 { |
|
590 iLastCol = iLeftMargin; |
|
591 } |
|
592 else |
|
593 { |
|
594 iLastCol = iDisplaySize.iWidth + iLeftMargin; |
|
595 } |
|
596 |
|
597 iNewLine = ETrue; |
|
598 |
|
599 iCurrentLineArray.Reset(); |
|
600 iCurrentLineOffset += iLineHeight; |
|
601 iLineHeight = 0; |
|
602 ++iLines; |
|
603 } |
|
604 |
|
605 // --------------------------------------------------------------------------- |
|
606 // JoinRangedVisuals |
|
607 // --------------------------------------------------------------------------- |
|
608 void CFsTextViewerLayouter::JoinRangedVisuals( TFsRangedVisual* aFirst, TFsRangedVisual* aSecond ) |
|
609 { |
|
610 FUNC_LOG; |
|
611 /* if ( aFirst->iRect.iTl.iX > aSecond->iRect.iTl.iX ) |
|
612 { |
|
613 aFirst->iRect.iTl.iX = aSecond->iRect.iTl.iX; |
|
614 } |
|
615 else |
|
616 { |
|
617 aFirst->iRect.iBr.iX = aSecond->iRect.iBr.iX; |
|
618 } |
|
619 */ |
|
620 TInt a = aFirst->iRect.iTl.iX; |
|
621 TInt b = aFirst->iRect.iBr.iX; |
|
622 TInt c = aSecond->iRect.iTl.iX; |
|
623 TInt d = aSecond->iRect.iBr.iX; |
|
624 |
|
625 TInt max = Max( Max(a, b), Max(d, c) ); |
|
626 TInt min = Min( Min(a, b), Min(d, c) ); |
|
627 aFirst->iRect.iTl.iX = min; |
|
628 aFirst->iRect.iBr.iX = max; |
|
629 aFirst->iStart = Min( aFirst->iStart, aSecond->iStart ); |
|
630 aFirst->iEnd = Max( aFirst->iEnd, aSecond->iEnd ); |
|
631 } |
|
632 |
|
633 // --------------------------------------------------------------------------- |
|
634 // GetCurrentLineOffset |
|
635 // --------------------------------------------------------------------------- |
|
636 TInt CFsTextViewerLayouter::GetCurrentLineOffset() |
|
637 { |
|
638 FUNC_LOG; |
|
639 return iCurrentLineOffset; |
|
640 } |
|
641 |
|
642 // --------------------------------------------------------------------------- |
|
643 // SetMargins |
|
644 // --------------------------------------------------------------------------- |
|
645 void CFsTextViewerLayouter::SetCurrentLineOffset( TInt aOffset ) |
|
646 { |
|
647 FUNC_LOG; |
|
648 iCurrentLineOffset = aOffset; |
|
649 } |
|
650 |
|
651 // --------------------------------------------------------------------------- |
|
652 // SetMargins |
|
653 // --------------------------------------------------------------------------- |
|
654 void CFsTextViewerLayouter::SetMargins( const TInt aLeft, const TInt aRight ) |
|
655 { |
|
656 FUNC_LOG; |
|
657 iLeftMargin = aLeft; |
|
658 iRightMargin = aRight; |
|
659 if ( iMainDirection == TBidiText::ELeftToRight ) |
|
660 { |
|
661 iLastCol = iLeftMargin; |
|
662 } |
|
663 else |
|
664 { |
|
665 iLastCol = iDisplaySize.iWidth + iLeftMargin; |
|
666 } |
|
667 } |
|
668 |
|
669 // --------------------------------------------------------------------------- |
|
670 // SetHelper |
|
671 // --------------------------------------------------------------------------- |
|
672 void CFsTextViewerLayouter::SetHelper( CFsTextViewerCoordinator* aHelper ) |
|
673 { |
|
674 FUNC_LOG; |
|
675 iHelper = aHelper; |
|
676 } |
|
677 |
|
678 // --------------------------------------------------------------------------- |
|
679 // SetNavigator |
|
680 // --------------------------------------------------------------------------- |
|
681 void CFsTextViewerLayouter::SetNavigator( CFsTextViewerVisualizerData* aNavigator ) |
|
682 { |
|
683 FUNC_LOG; |
|
684 iNavigator = aNavigator; |
|
685 } |
|
686 |
|
687 // --------------------------------------------------------------------------- |
|
688 // Lines |
|
689 // --------------------------------------------------------------------------- |
|
690 TInt CFsTextViewerLayouter::Lines() |
|
691 { |
|
692 FUNC_LOG; |
|
693 return iLines; |
|
694 } |
|
695 |
|
696 // --------------------------------------------------------------------------- |
|
697 // EnableSmileys |
|
698 // --------------------------------------------------------------------------- |
|
699 void CFsTextViewerLayouter::EnableSmileys( TBool aEnable ) |
|
700 { |
|
701 FUNC_LOG; |
|
702 iSmileyEnabled = aEnable; |
|
703 } |
|
704 |
|
705 // --------------------------------------------------------------------------- |
|
706 // SetPosition |
|
707 // --------------------------------------------------------------------------- |
|
708 void CFsTextViewerLayouter::SetPosition( TInt aLine, TInt aLineOffset ) |
|
709 { |
|
710 FUNC_LOG; |
|
711 iLines = aLine; |
|
712 iCurrentLineOffset = aLineOffset; |
|
713 } |
|
714 |
|
715 // --------------------------------------------------------------------------- |
|
716 // ChangeDirection |
|
717 // --------------------------------------------------------------------------- |
|
718 void CFsTextViewerLayouter::ChangeDirection( TBidiText::TDirectionality aDirection ) |
|
719 { |
|
720 FUNC_LOG; |
|
721 iMainDirection = aDirection; |
|
722 if ( iMainDirection == TBidiText::ELeftToRight && iCurrentLineArray.Count() < 1 ) |
|
723 { |
|
724 iLastCol = iLeftMargin; |
|
725 } |
|
726 else if ( iMainDirection == TBidiText::ERightToLeft && iCurrentLineArray.Count() < 1 ) |
|
727 { |
|
728 iLastCol = iDisplaySize.iWidth + iLeftMargin; |
|
729 } |
|
730 } |
|
731 |
|
732 // --------------------------------------------------------------------------- |
|
733 // SetDirection |
|
734 // --------------------------------------------------------------------------- |
|
735 void CFsTextViewerLayouter::SetDirection( TBidiText::TDirectionality aDirection ) |
|
736 { |
|
737 FUNC_LOG; |
|
738 iMainDirection = aDirection; |
|
739 if ( iMainDirection == TBidiText::ELeftToRight ) |
|
740 { |
|
741 iLastCol = iLeftMargin; |
|
742 } |
|
743 else |
|
744 { |
|
745 iLastCol = iDisplaySize.iWidth + iLeftMargin; |
|
746 } |
|
747 } |
|
748 |
|
749 // --------------------------------------------------------------------------- |
|
750 // GetDirection |
|
751 // --------------------------------------------------------------------------- |
|
752 TBidiText::TDirectionality CFsTextViewerLayouter::GetDirection() |
|
753 { |
|
754 FUNC_LOG; |
|
755 return iMainDirection; |
|
756 } |
|
757 |
|
758 // --------------------------------------------------------------------------- |
|
759 // IsNewLine |
|
760 // --------------------------------------------------------------------------- |
|
761 TBool CFsTextViewerLayouter::IsNewLine() |
|
762 { |
|
763 FUNC_LOG; |
|
764 if ( iCurrentLineArray.Count() < 1 ) |
|
765 { |
|
766 return ETrue; |
|
767 } |
|
768 return EFalse; |
|
769 } |
|
770 |
|
771 // --------------------------------------------------------------------------- |
|
772 // ConstructL |
|
773 // --------------------------------------------------------------------------- |
|
774 void CFsTextViewerLayouter::ConstructL() |
|
775 { |
|
776 FUNC_LOG; |
|
777 |
|
778 } |
|
779 |
|
780 // --------------------------------------------------------------------------- |
|
781 // CFsTextViewerLayouter |
|
782 // --------------------------------------------------------------------------- |
|
783 CFsTextViewerLayouter::CFsTextViewerLayouter( CAlfEnv* aEnv ) |
|
784 { |
|
785 FUNC_LOG; |
|
786 iScreenDev = CCoeEnv::Static()->ScreenDevice(); |
|
787 iEnv = aEnv; |
|
788 iLines = 0; |
|
789 iLowestPicPosition = 0; |
|
790 iMainDirection = TBidiText::ELeftToRight; |
|
791 } |
|
792 |
|
793 // --------------------------------------------------------------------------- |
|
794 // ReorderLineFromLeftL |
|
795 // --------------------------------------------------------------------------- |
|
796 TBool CFsTextViewerLayouter::ReorderLineFromLeftL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects ) |
|
797 { |
|
798 FUNC_LOG; |
|
799 // TBool retVal = EFalse; |
|
800 // TInt i = iCurrentLineArray.Count() - 1; |
|
801 // TInt dX = aObjectSize.iWidth; |
|
802 // TInt moveFrom = 0; |
|
803 // TRect translatedObject; |
|
804 // TRect origRect; |
|
805 // while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
806 // { |
|
807 // translatedObject = iCurrentLineArray[i]->iRect; |
|
808 //// if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) |
|
809 //// { |
|
810 // iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); |
|
811 // translatedObject.iTl.iX += dX; |
|
812 // translatedObject.iBr.iX += dX; |
|
813 // origRect = translatedObject; |
|
814 // if ( iHelper->NextFreeCol( translatedObject, iMainDirection ) ) |
|
815 // { |
|
816 // i = -100; |
|
817 // } |
|
818 // if ( origRect != translatedObject ) |
|
819 // { |
|
820 // iCurrentLineArray[i]->iMoved = ETrue; |
|
821 // } |
|
822 //// } |
|
823 // moveFrom = i; |
|
824 // --i; |
|
825 // } |
|
826 // if ( -101 == i ) |
|
827 // { |
|
828 // ConstructLineL(); |
|
829 // retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
830 // } |
|
831 // else |
|
832 // { |
|
833 // TFsRangedVisual* currentVisual; |
|
834 // currentVisual = PrepareRangedVisL( aObject, aLayout ); |
|
835 // if ( !aRegisterSelects ) |
|
836 // { |
|
837 // currentVisual->iEmbed = EFalse; |
|
838 // } |
|
839 // currentVisual->iRect = TRect( iCurrentLineArray[moveFrom]->iRect.iTl, aObjectSize ); |
|
840 // iCurrentLineArray.Insert( currentVisual, moveFrom ); |
|
841 // for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) |
|
842 // { |
|
843 // if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) |
|
844 // { |
|
845 // iCurrentLineArray[i]->iRect.iTl.iX += dX; |
|
846 // iCurrentLineArray[i]->iRect.iBr.iX += dX; |
|
847 // } |
|
848 // } |
|
849 // if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) |
|
850 // { |
|
851 // iLineHeight = currentVisual->iRect.Height(); |
|
852 // } |
|
853 // } |
|
854 // return retVal; |
|
855 TBool retVal = EFalse; |
|
856 TInt dX = aObjectSize.iWidth; |
|
857 TInt moveFrom = 0; |
|
858 TRect translatedObject; |
|
859 TFsRangedVisual* visual = NULL; |
|
860 TInt maxCol = 0; |
|
861 // <cmail>TInt tmp = 0; |
|
862 |
|
863 TInt i = iCurrentLineArray.Count() - 1; |
|
864 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
865 { |
|
866 if ( !iCurrentLineArray[i]->iIsText ) |
|
867 { |
|
868 iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); |
|
869 } |
|
870 --i; |
|
871 } |
|
872 i = iCurrentLineArray.Count() - 1; |
|
873 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
874 { |
|
875 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); |
|
876 visual = iCurrentLineArray[i]; |
|
877 translatedObject.iTl.iX += dX; |
|
878 translatedObject.iBr.iX += dX; |
|
879 // <cmail> tmp = translatedObject.iTl.iX; |
|
880 moveFrom = i; |
|
881 if ( iHelper->NextFreeCol( translatedObject, TBidiText::ELeftToRight ) ) |
|
882 { |
|
883 i = -100; |
|
884 } |
|
885 --i; |
|
886 } |
|
887 if ( -101 == i ) |
|
888 { |
|
889 i = iCurrentLineArray.Count() - 1; |
|
890 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
891 { |
|
892 if ( !iCurrentLineArray[i]->iIsText ) |
|
893 { |
|
894 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); |
|
895 translatedObject.iTl.iX += dX; |
|
896 translatedObject.iBr.iX += dX; |
|
897 iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect ); |
|
898 } |
|
899 --i; |
|
900 } |
|
901 ConstructLineL(); |
|
902 retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
903 } |
|
904 else |
|
905 { |
|
906 TFsRangedVisual* currentVisual; |
|
907 currentVisual = PrepareRangedVisL( aObject, aLayout ); |
|
908 currentVisual->iMoved = EFalse; |
|
909 if ( !aRegisterSelects ) |
|
910 { |
|
911 currentVisual->iEmbed = EFalse; |
|
912 } |
|
913 |
|
914 currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iTl.iX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize ); |
|
915 iCurrentLineArray.Insert( currentVisual, moveFrom ); |
|
916 |
|
917 if ( aObject->GetType() == MFsRichTextObject::EFsTexture ) |
|
918 { |
|
919 iHelper->RegisterObstacleL( currentVisual->iRect ); |
|
920 } |
|
921 if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) |
|
922 { |
|
923 iLineHeight = currentVisual->iRect.Height(); |
|
924 } |
|
925 |
|
926 for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) |
|
927 { |
|
928 // if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) |
|
929 // { |
|
930 visual = iCurrentLineArray[i]; |
|
931 iCurrentLineArray[i]->iRect.iTl.iX += dX; |
|
932 iCurrentLineArray[i]->iRect.iBr.iX += dX; |
|
933 iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ELeftToRight ); |
|
934 if ( !(visual->iIsText) ) |
|
935 { |
|
936 iHelper->RegisterObstacleL( visual->iRect ); |
|
937 } |
|
938 if ( visual->iRect.iBr.iX > maxCol ) |
|
939 { |
|
940 maxCol = visual->iRect.iBr.iX; |
|
941 } |
|
942 } |
|
943 } |
|
944 iLastCol = maxCol; |
|
945 return retVal; |
|
946 } |
|
947 |
|
948 // --------------------------------------------------------------------------- |
|
949 // ReorderLineFromRightL |
|
950 // --------------------------------------------------------------------------- |
|
951 TBool CFsTextViewerLayouter::ReorderLineFromRightL( MFsRichTextObject* aObject, CAlfLayout* aLayout, CFsTextParser* aParser, TSize aObjectSize, TBool aRegisterSelects ) |
|
952 { |
|
953 FUNC_LOG; |
|
954 TBool retVal = EFalse; |
|
955 TInt dX = aObjectSize.iWidth; |
|
956 TInt moveFrom = 0; |
|
957 TRect translatedObject; |
|
958 TFsRangedVisual* visual = NULL; |
|
959 |
|
960 TInt i = iCurrentLineArray.Count() - 1; |
|
961 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
962 { |
|
963 if ( !iCurrentLineArray[i]->iIsText ) |
|
964 { |
|
965 iHelper->RemoveRect( iCurrentLineArray[i]->iRect ); |
|
966 } |
|
967 --i; |
|
968 } |
|
969 i = iCurrentLineArray.Count() - 1; |
|
970 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
971 { |
|
972 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); |
|
973 visual = iCurrentLineArray[i]; |
|
974 translatedObject.iTl.iX -= dX; |
|
975 translatedObject.iBr.iX -= dX; |
|
976 moveFrom = i; |
|
977 if ( iHelper->NextFreeCol( translatedObject, TBidiText::ERightToLeft ) ) |
|
978 { |
|
979 i = -100; |
|
980 } |
|
981 --i; |
|
982 } |
|
983 if ( -101 == i ) |
|
984 { |
|
985 i = iCurrentLineArray.Count() - 1; |
|
986 while ( i >= 0 && iCurrentLineArray[i]->iDirection != iMainDirection ) |
|
987 { |
|
988 if ( !iCurrentLineArray[i]->iIsText ) |
|
989 { |
|
990 translatedObject = TRect(iCurrentLineArray[i]->iRect.iTl, iCurrentLineArray[i]->iRect.iBr ); |
|
991 translatedObject.iTl.iX -= dX; |
|
992 translatedObject.iBr.iX -= dX; |
|
993 iHelper->RegisterObstacleL( iCurrentLineArray[i]->iRect ); |
|
994 } |
|
995 --i; |
|
996 } |
|
997 ConstructLineL(); |
|
998 retVal = AppendObjectL( aObject, aLayout, aParser, aRegisterSelects ); |
|
999 } |
|
1000 else |
|
1001 { |
|
1002 TFsRangedVisual* currentVisual; |
|
1003 currentVisual = PrepareRangedVisL( aObject, aLayout ); |
|
1004 currentVisual->iMoved = EFalse; |
|
1005 if ( !aRegisterSelects ) |
|
1006 { |
|
1007 currentVisual->iEmbed = EFalse; |
|
1008 } |
|
1009 |
|
1010 currentVisual->iRect = TRect( TPoint( iCurrentLineArray[moveFrom]->iRect.iBr.iX - dX, iCurrentLineArray[moveFrom]->iRect.iTl.iY ), aObjectSize ); |
|
1011 iCurrentLineArray.Insert( currentVisual, moveFrom ); |
|
1012 |
|
1013 if ( aObject->GetType() == MFsRichTextObject::EFsTexture ) |
|
1014 { |
|
1015 iHelper->RegisterObstacleL( currentVisual->iRect ); |
|
1016 } |
|
1017 if ( currentVisual->iRect.Height() > iLineHeight && aObject->GetType() != MFsRichTextObject::EFsTexture ) |
|
1018 { |
|
1019 iLineHeight = currentVisual->iRect.Height(); |
|
1020 } |
|
1021 |
|
1022 for ( i = moveFrom + 1; i < iCurrentLineArray.Count(); ++i ) |
|
1023 { |
|
1024 // if ( iCurrentLineArray[i]->iIsText || iCurrentLineArray[i]->iSmiley ) |
|
1025 // { |
|
1026 visual = iCurrentLineArray[i]; |
|
1027 iCurrentLineArray[i]->iRect.iTl.iX -= dX; |
|
1028 iCurrentLineArray[i]->iRect.iBr.iX -= dX; |
|
1029 iHelper->NextFreeCol( iCurrentLineArray[i]->iRect, TBidiText::ERightToLeft ); |
|
1030 if ( !(visual->iIsText) ) |
|
1031 { |
|
1032 iHelper->RegisterObstacleL( visual->iRect ); |
|
1033 } |
|
1034 } |
|
1035 } |
|
1036 return retVal; |
|
1037 } |
|
1038 |