lafagnosticuifoundation/cone/src/coetextdrawer.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 2004-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 <coetextdrawer.h>
       
    17  
       
    18  
       
    19 //
       
    20 // class XCoeTextDrawer
       
    21 //
       
    22 const TInt KDefaultLineGap = 1;	
       
    23 
       
    24 
       
    25 //
       
    26 // class CCoeTextDrawerBaseExt 
       
    27 //
       
    28 
       
    29 /**
       
    30 This extension block is used to to avoid BC breaks in adding to the
       
    31 main data structures.
       
    32 @internalComponent
       
    33 */
       
    34 NONSHARABLE_CLASS(CCoeTextDrawerBaseExt) : public CBase
       
    35 	{
       
    36 public:
       
    37 	static CCoeTextDrawerBaseExt* New();
       
    38 	~CCoeTextDrawerBaseExt();	
       
    39 	
       
    40 	void SetAppLanguage(TLanguage aAppLang);
       
    41 	TBidiText::TDirectionality DirectionalityToConsider(const TCoeTextTypeAdaptor& aText) const;
       
    42 private:
       
    43 	CCoeTextDrawerBaseExt();
       
    44 	TInt	 Construct();	
       
    45 private:
       
    46 	enum TScriptDirectionality
       
    47 		{
       
    48 		EScriptDirUndefined,
       
    49 		EScriptDirLeftToRight,
       
    50 		EScriptDirRightToLeft
       
    51 		};	
       
    52 private:	
       
    53 	TScriptDirectionality iAppScriptDirectionality;
       
    54 	};
       
    55 
       
    56 /**
       
    57 Create a CCoeTextDrawerBaseExt object.
       
    58 */
       
    59 CCoeTextDrawerBaseExt* CCoeTextDrawerBaseExt::New()
       
    60 	{
       
    61 	CCoeTextDrawerBaseExt* self = new CCoeTextDrawerBaseExt();
       
    62 	if(self->Construct() != KErrNone)
       
    63 		{
       
    64 		delete self;
       
    65 		self = NULL;
       
    66 		}
       
    67 		
       
    68 	return self;
       
    69 	}
       
    70 
       
    71 /**
       
    72 Constructor.
       
    73 */
       
    74 CCoeTextDrawerBaseExt::CCoeTextDrawerBaseExt()
       
    75 	{}
       
    76 
       
    77 /**
       
    78 Destructor.
       
    79 */
       
    80 CCoeTextDrawerBaseExt::~CCoeTextDrawerBaseExt()
       
    81 	{}
       
    82 
       
    83 /**
       
    84 Second-phase object construction.
       
    85 */	
       
    86 TInt CCoeTextDrawerBaseExt::Construct()
       
    87 //lint --e{1762} Suppress member function could be made const
       
    88 	{
       
    89 	return KErrNone;
       
    90 	}
       
    91 
       
    92 /**
       
    93 Set the application language directionality based on the TLanguage passed as argument.
       
    94 Passing ELangNone will set the application language directionality to "undefined".
       
    95 */	
       
    96 void CCoeTextDrawerBaseExt::SetAppLanguage(TLanguage aAppLang)
       
    97 	{
       
    98 	if(aAppLang == ELangNone)
       
    99 		iAppScriptDirectionality = EScriptDirUndefined;
       
   100 	else if (TBidiText::ScriptDirectionality(aAppLang) == TBidiText::ELeftToRight)
       
   101 		iAppScriptDirectionality = EScriptDirLeftToRight;
       
   102 	else
       
   103 		iAppScriptDirectionality = EScriptDirRightToLeft;
       
   104 	}
       
   105 
       
   106 /**
       
   107 Return the language directionality to consider when deciding whether to swap left and right alignment
       
   108 (for non-absolute horizontal alignment, left and right shall be swapped for scrips with RightToLeft 
       
   109 directionality, such as Arabic).
       
   110 
       
   111 If the application language has been set using SetAppLanguage(), the directionality of the languange that the
       
   112 application is currently running in will be used. If not, the directionality of the actual text being printed
       
   113 at the moment will be used.
       
   114 */	
       
   115 TBidiText::TDirectionality CCoeTextDrawerBaseExt::DirectionalityToConsider(const TCoeTextTypeAdaptor& aText) const
       
   116 	{		
       
   117 	TBidiText::TDirectionality textDirectionality = TBidiText::ELeftToRight;
       
   118 	if(iAppScriptDirectionality == EScriptDirRightToLeft)
       
   119 		textDirectionality = TBidiText::ERightToLeft;
       
   120 	else if(iAppScriptDirectionality == EScriptDirUndefined)
       
   121 		textDirectionality = (aText.HasRightToLeftDirectionality() ? TBidiText::ERightToLeft : TBidiText::ELeftToRight);
       
   122 	
       
   123 	return textDirectionality;
       
   124 	}
       
   125 	
       
   126 	
       
   127 //
       
   128 // Class XCoeTextDrawer
       
   129 //
       
   130 
       
   131 
       
   132 /**
       
   133 Use this constructor to create a XCoeTextDrawer object on the stack, inside your control's
       
   134 Draw() method. The XCoeTextDrawer object will work as a smart-pointer to the CCoeTextDrawerBase
       
   135 object, managing its life. Get the CCoeTextDrawerBase-derived object to use by calling 
       
   136 CCoeControl::TextDrawer(). Do not create a new CCoeTextDrawerBase-derived object inside the
       
   137 Draw() method. If you want to change the text drawer used by the control or any of the control's
       
   138 children, override the CCoeControl::GetTextDrawer() method. Inside it you can create a new 
       
   139 CCoeTextDrawerBase object or change the properties of the CCoeTextDrawerBase object passed to it.
       
   140 */
       
   141 EXPORT_C XCoeTextDrawer::XCoeTextDrawer(CCoeTextDrawerBase& aTextDrawer) 
       
   142 	: iTextDrawer(&aTextDrawer) 
       
   143 	{
       
   144 	iClipRect = TRect();	
       
   145 	}
       
   146 
       
   147 	
       
   148 /**
       
   149 Destructor. The XCoeTextDrawer object work as a smart-pointer object to the CCoeTextDrawerBase
       
   150 object actually performing the text drawing. The XCoeTextDrawer object shall be allocated on
       
   151 the stack (i.e. not using "new") in the CCoeControl's Draw() method. Once the XCoeTextDrawer object 
       
   152 goes out of scope, this destructor will be called. It will call Reset() on the CCoeTextDrawerBase
       
   153 object, if it was been set to be resuable by its owner. If not, the CCoeTextDrawerBase object
       
   154 will be deleted. Note that it is up to the creator/owner of the CCoeTextDrawerBase to decide 
       
   155 whether it shall be reusable or not. A user of the XCoeTextDrawer must not change the re-use'ness
       
   156 of the CCoeTextDrawerBase.
       
   157 */	
       
   158 EXPORT_C XCoeTextDrawer::~XCoeTextDrawer()
       
   159 	{
       
   160 	if(iTextDrawer && iTextDrawer->IsReusable())
       
   161 		iTextDrawer->Reset();
       
   162 	else
       
   163 		delete iTextDrawer;
       
   164 	}
       
   165  
       
   166 /**
       
   167 Assignment operator for CCoeTextDrawerBase objects.
       
   168 
       
   169 Due to compiler defect/feature, this method may not work.
       
   170 I.e. if
       
   171 <code> XCoeTextDrawer textDrawer = TextDrawer(); </code>
       
   172 does not compile, restate as 
       
   173 <code> XCoeTextDrawer textDrawer(TextDrawer()); </code>
       
   174 
       
   175 @param aTextDrawer A text drawer.
       
   176 */
       
   177 EXPORT_C void XCoeTextDrawer::operator=(CCoeTextDrawerBase& aTextDrawer)
       
   178 	{
       
   179 	// The currently owned CCoeTextDrawerBase object may be reusable and should just
       
   180 	// be reset rather than deleted.
       
   181 	if(iTextDrawer && iTextDrawer->IsReusable())
       
   182 		iTextDrawer->Reset();
       
   183 	else
       
   184 		delete iTextDrawer;
       
   185 	
       
   186 	iTextDrawer = &aTextDrawer;
       
   187 	} 	//lint !e1539 Suppress Member 'XCoeTextDrawer::iClipRect' not assigned by assignment operator
       
   188 
       
   189 /**
       
   190 Deprecated.
       
   191 */
       
   192 EXPORT_C CCoeTextDrawerBase * XCoeTextDrawer::operator ->() 
       
   193 	{	
       
   194  	return iTextDrawer;
       
   195  	}
       
   196  
       
   197 /**
       
   198 An XCoeTextDrawer object should not be copied as only one handle should exist to a CCoeTextDrawer.
       
   199 Therefore this copy constructor is private and just contains a panic statement.
       
   200 @internalComponent
       
   201 */
       
   202 XCoeTextDrawer::XCoeTextDrawer(const XCoeTextDrawer& /*aTextDrawer*/)
       
   203 	{  
       
   204 	ASSERT(0);
       
   205 	} //lint !e1744 Suppress Member 'XCoeTextDrawer::iTextDrawer' possibly not initialized by private constructor
       
   206 	
       
   207 /**
       
   208 Call this method to draw text contained i a TBidiText object. This is the 
       
   209 recommended way of drawing any widget text, as it will manage both left-to-right 
       
   210 scripts like English as well as right-to-left scripts such as Arabic and Hebrew.
       
   211 
       
   212 Before calling this method, be sure to set the text alignment, margins, clip rect, 
       
   213 etc using the XCoeTextDrawer methods SetAlignment(), SetMargins(), and SetClipRect().
       
   214 
       
   215 Note that before a TBidiText text can be drawn, it has to be line-broken using 
       
   216 TBidiText::WrapText() with a wrap width that match the text rect minus margins.
       
   217 
       
   218 @param aGc 			The graphics context.
       
   219 @param aText 		TBidiText reference containing the text to be drawn.
       
   220 @param aTextRect 	Rectangle text will be drawn in
       
   221 @param aFont 		Font to be used.
       
   222 */
       
   223 EXPORT_C void XCoeTextDrawer::DrawText(CGraphicsContext& aGc, const TBidiText& aText, const TRect& aTextRect, const CFont& aFont) const
       
   224 	{
       
   225 	ASSERT(iTextDrawer);
       
   226 	iTextDrawer->DrawText(aGc, TCoeTextTypeAdaptor(aText), aFont, aTextRect, iClipRect);	
       
   227 	}
       
   228 
       
   229 /**
       
   230 Call this method to draw vertical text contained in a TBidiText object. This is the 
       
   231 recommended way of drawing any widget text, as it will manage both left-to-right 
       
   232 scripts like English as well as right-to-left scripts such as Arabic and Hebrew.
       
   233 
       
   234 Before calling this method, be sure to set the text alignment, margins, clip rect, 
       
   235 etc using the XCoeTextDrawer methods SetAlignment(), SetMargins(), and SetClipRect().
       
   236 
       
   237 Note that before a TBidiText text can be drawn, it has to be line-broken using 
       
   238 TBidiText::WrapText() with a wrap width that match the text rect minus margins.
       
   239 
       
   240 Also note that the margines are relative to the orientation of the text.
       
   241 
       
   242 @param aGc 	    	The graphics context.
       
   243 @param aText 		TBidiText reference containing the text to be drawn.
       
   244 @param aTextRect 	Rectangle text will be drawn in
       
   245 @param aFont 		Font to be used.
       
   246 @param aUp 			ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
       
   247 @see 				XCoeTextDrawer::SetClipRect
       
   248 */
       
   249 EXPORT_C void XCoeTextDrawer::DrawTextVertical(CGraphicsContext& aGc, const TBidiText& aText, const TRect& aTextRect, const CFont& aFont, TBool aUp) const
       
   250 	{
       
   251 	ASSERT(iTextDrawer);
       
   252 	iTextDrawer->DrawTextVertical(aGc, TCoeTextTypeAdaptor(aText), aFont, aTextRect, iClipRect, aUp);	
       
   253 	}
       
   254 
       
   255 /**
       
   256 Low level text drawing is always performed left-to-right on the screen. This 
       
   257 means that for any script with right-to-left directionality (like Arabic), 
       
   258 the in-memory order of the glyphs has to be changed (reordered) from the 
       
   259 logical order (start of sentence first, before end of sentence) to the 
       
   260 display order (end of sentence before (i.e. left of) start of sentence). 
       
   261 This operation is performed by TBidiText.
       
   262 
       
   263 However, sometimes text is reordered through some other means than the TBidiText 
       
   264 class. In these cases, this method can be used to draw the text contained in a 
       
   265 descriptor object in the same order (left-to-right) as it appears in the descriptor 
       
   266 memory. I.e. this method assumes that the text has already been changed into the
       
   267 display order. If this is not the case, and the text is in a right-to-left script,
       
   268 it will come out backwards.
       
   269 
       
   270 @param aGc 			The graphics context.
       
   271 @param aText 		TDesC reference containing the text to be drawn.
       
   272 @param aTextRect 	Rectangle text will be drawn in
       
   273 @param aFont 		Font to be used.
       
   274 */
       
   275 EXPORT_C void XCoeTextDrawer::DrawDisplayOrderedText(CGraphicsContext& aGc, const TDesC& aText, const TRect& aTextRect, const CFont& aFont) const
       
   276 	{
       
   277 	ASSERT(iTextDrawer);
       
   278 	iTextDrawer->DrawText(aGc, aText, aFont, aTextRect, iClipRect);	
       
   279 	}
       
   280 
       
   281 /**
       
   282 Low level text drawing is always performed left-to-right on the screen. This 
       
   283 means that for any script with right-to-left directionality (like Arabic), 
       
   284 the in-memory order of the glyphs has to be changed (reordered) from the 
       
   285 logical order (start of sentence first, before end of sentence) to the 
       
   286 display order (end of sentence before (i.e. left of) start of sentence). 
       
   287 This operation is performed by TBidiText.
       
   288 
       
   289 However, sometimes text is reordered through some other means than the TBidiText 
       
   290 class. In these cases, this method can be used to draw the text contained in a 
       
   291 descriptor object in the same order (left-to-right) as it appears in the descriptor 
       
   292 memory. I.e. this method assumes that the text has already been changed into the
       
   293 display order. If this is not the case, and the text is in a right-to-left script,
       
   294 it will come out backwards.
       
   295 
       
   296 Note that the margines are relative to the orientation of the text.
       
   297 
       
   298 @param aGc 			The graphics context.
       
   299 @param aText 		TDesC reference containing the text to be drawn.
       
   300 @param aTextRect 	Rectangle text will be drawn in
       
   301 @param aFont 		Font to be used.
       
   302 */
       
   303 EXPORT_C void XCoeTextDrawer::DrawDisplayOrderedTextVertical(CGraphicsContext& aGc, const TDesC& aText, const TRect& aTextRect, const CFont& aFont, TBool aUp) const
       
   304 	{
       
   305 	ASSERT(iTextDrawer);
       
   306 	iTextDrawer->DrawTextVertical(aGc, aText, aFont, aTextRect, iClipRect, aUp);	
       
   307 	}
       
   308 
       
   309 /**
       
   310 Return the clip rect that will be used by DrawText() and DrawDisplayOrderedText().
       
   311 Any text falling outside this rectangle will not be visible. This is used to crop text.
       
   312 
       
   313 @return The clipping rect.
       
   314 */	
       
   315 EXPORT_C TRect XCoeTextDrawer::ClipRect() const
       
   316 	{
       
   317 	return  iClipRect;
       
   318 	}
       
   319 
       
   320 /**
       
   321 Set the clip rect that will be used by DrawText() and DrawDisplayOrderedText().
       
   322 Any text falling outside this rectangle will not be visible. This is used to crop text.
       
   323 
       
   324 @param aClipRect TRect value to set iClipRect to.  
       
   325 */		
       
   326 EXPORT_C void XCoeTextDrawer::SetClipRect(const TRect& aClipRect)
       
   327 	{
       
   328  	iClipRect = aClipRect;
       
   329 	}
       
   330 
       
   331 
       
   332 //
       
   333 // class CCoeTextDrawerBase
       
   334 //
       
   335 
       
   336 /**
       
   337 Constructor.
       
   338 */
       
   339 EXPORT_C CCoeTextDrawerBase::CCoeTextDrawerBase()  
       
   340 	{
       
   341 	Reset();	// N.B. This will always call local implementation, never derived overrides
       
   342  	} //lint !e1506 Supress Call to virtual function 'Reset(void)' within constructor
       
   343 
       
   344 /**
       
   345 This method is called from the destructor of the XCoeTextDrawer object managing the
       
   346 life of the CCoeTextDrawerBase object, if the CCoeTextDrawerBase object has been set
       
   347 to be reusable (by its owner calling SetReusable()). 
       
   348 
       
   349 Any derived class must override this method to reset its drawing parameters to their 
       
   350 defaults, so that the object is ready to be used again. Any overriding implementation 
       
   351 must call the base implementation as well.
       
   352 */	
       
   353 EXPORT_C void CCoeTextDrawerBase::Reset() 
       
   354 	{ 
       
   355  	// Don't change iIsReusable! 
       
   356     iAlignment = EHLeftVTop; 
       
   357     iMargins = TMargins8(); 
       
   358     iLineGap = KDefaultLineGap; 
       
   359 	} 
       
   360 
       
   361 /**
       
   362 Destructor.
       
   363 */	
       
   364 EXPORT_C CCoeTextDrawerBase::~CCoeTextDrawerBase()  
       
   365 	{ 
       
   366   	delete iExtension;
       
   367 	}
       
   368 
       
   369 /**
       
   370 Second phase object construction.
       
   371 Note that this method is non-leaving as it may be called indirectly from a Draw() 
       
   372 method, which must not leave.
       
   373 
       
   374 @return returns KErrNone if successful, otherwise KErrNoMemory.
       
   375 */	
       
   376 EXPORT_C TInt CCoeTextDrawerBase::Construct()
       
   377 	{
       
   378 	// allocate extension block
       
   379 	iExtension = CCoeTextDrawerBaseExt::New();
       
   380 
       
   381 	if (!iExtension)
       
   382 		return KErrNoMemory;
       
   383 	else
       
   384 		return KErrNone;
       
   385 	} 
       
   386 	
       
   387 /**
       
   388 Unless absolute horizontal aligment has been selected (see TGulAlignment), the actual 
       
   389 horizontal text alignment used when drawing text depends on whether the directionality 
       
   390 of the scrip is left-to-right or right-to-left. In the latter case left and right 
       
   391 is swapped. By default, the directionality of the actual text being drawn will define 
       
   392 whether the horizontal alignment will be swapped or not. However, if (as recommended) the 
       
   393 directionality of the application's main language shall be considered instead (rather 
       
   394 than the directionality of the text being printed at the moment), then call this method. 
       
   395 
       
   396 If ELangNone is specified, the text drawer will be reset to swap horizontal alignment 
       
   397 depending on the directionality of the text being printed.
       
   398 
       
   399 @param aAppLang The application language (e.g. from CEikonEnv::ApplicationLanguage()).
       
   400 */
       
   401 EXPORT_C void CCoeTextDrawerBase::SetAppLanguage(TLanguage aAppLang)
       
   402 	{
       
   403 	if(iExtension)
       
   404 		iExtension->SetAppLanguage(aAppLang);
       
   405 	}
       
   406 
       
   407 /**
       
   408 This method returns the actual (absolute) horizontal text alignment to be used 
       
   409 when drawing text in any CCoeTextDrawerBase-derived DrawText() implementation. 
       
   410 The actual alignment depends on the application language directionality if the 
       
   411 application language has been set calling CCoeTextDrawerBase::SetAppLanguage(), 
       
   412 or otherwise on the directionality of the actual text being printed. If the 
       
   413 directionality is right-to-left (and the horizontal alignment has not been set 
       
   414 to be absolute, using TGulAlignment::SetAbsoluteHAlignment()), left and right 
       
   415 alignment (set using XCoeTextDrawer::SetAlignment()) will be swapped.
       
   416 */
       
   417 EXPORT_C TGulHAlignment CCoeTextDrawerBase::ActualHorizontalAlignment(const TCoeTextTypeAdaptor& aText) const
       
   418 	{
       
   419 	if(iAlignment.HasAbsoluteHAlignment())
       
   420 		return iAlignment.HAlignment();
       
   421 	
       
   422 	if(iExtension)
       
   423 		{
       
   424 		const TBidiText::TDirectionality directionalityToConsider = iExtension->DirectionalityToConsider(aText);
       
   425 		return iAlignment.HAlignment(directionalityToConsider);
       
   426 		}
       
   427 	else
       
   428 		return iAlignment.HAlignment();
       
   429 	}
       
   430 		
       
   431 // Accessor/Set Methods
       
   432 
       
   433 /**
       
   434 Returns whether the CCoeTextDrawerBase-derived text drawer object has been set 
       
   435 to be reusable or not. If reusable, the text drawer is assumed to have an owner 
       
   436 that will delete it when appropriate. If not reusable, the XCoeTextDrawer will 
       
   437 delete it in its destructor.
       
   438 
       
   439 @return bool value of iIsReusable data member
       
   440 */			
       
   441 EXPORT_C TBool CCoeTextDrawerBase::IsReusable() const
       
   442 	{
       
   443 	return iIsReusable;
       
   444 	}
       
   445 
       
   446 /**
       
   447 Set whether the text drawer is reusable or not. A reusable text drawer will be
       
   448 reset (through a call to Reset()) rather than deleted when the XCoeTextDrawer
       
   449 referring to it is deleted. This decision has to be made by the creator of the 
       
   450 CCoeTextDrawerBase object. I.e. this method must not be called by a mere user 
       
   451 of the XCoeTextDrawer.
       
   452 
       
   453 @param aIsReusable Boolean indicating whether the text drawer can be re-used.
       
   454 */	
       
   455 EXPORT_C void CCoeTextDrawerBase::SetReusable(TBool aIsReusable)
       
   456 	{
       
   457 	iIsReusable = aIsReusable;
       
   458 	}
       
   459 
       
   460 /**
       
   461 Returns the text alignment that will be used by DrawText() and DrawDisplayOrderedText().
       
   462 Note that left and right alignment will be swapped for right-to-left scripts, unless
       
   463 the alignment has been set to be absolute (see TGulAlignment).
       
   464 
       
   465 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   466 
       
   467 @return TGulAlignment value of iAlignment data member
       
   468 */	
       
   469 EXPORT_C TGulAlignment CCoeTextDrawerBase::Alignment() const
       
   470 	{
       
   471 	return  iAlignment;
       
   472 	}
       
   473 
       
   474 /**
       
   475 Set the text alignment that will be used by DrawText() and DrawDisplayOrderedText().
       
   476 Note that left and right alignment will be swapped for right-to-left scripts, unless
       
   477 the alignment has been set to be absolute (see TGulAlignment).
       
   478 
       
   479 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   480 
       
   481 @param aAlignment TGulAlignment value.  
       
   482 */		
       
   483 EXPORT_C void CCoeTextDrawerBase::SetAlignment(const TGulAlignment& aAlignment)
       
   484 	{
       
   485 	iAlignment = aAlignment;
       
   486 	}
       
   487 	
       
   488 /**
       
   489 Returns the text margins that will be used by DrawText() and DrawDisplayOrderedText().
       
   490 
       
   491 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   492 
       
   493 @return The margins between the text rect and the actual text, in pixels.
       
   494 */	
       
   495 EXPORT_C TMargins8 CCoeTextDrawerBase::Margins() const
       
   496 	{
       
   497 	return iMargins;
       
   498 	}
       
   499 
       
   500 /**
       
   501 Set the text margins that will be used by DrawText() and DrawDisplayOrderedText().
       
   502 
       
   503 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   504 
       
   505 @param aMargins The margins between the text rect and the actual text, in pixels.
       
   506 */		
       
   507 EXPORT_C void CCoeTextDrawerBase::SetMargins(const TMargins8& aMargins)
       
   508 	{
       
   509  	iMargins = aMargins;
       
   510 	}
       
   511 
       
   512 /**
       
   513 Returns the gap (in pixels) between lines of text. Default gap is 1 (one) pixel.
       
   514 
       
   515 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   516 
       
   517 @return The gap between lines of text, in pixels.
       
   518 */	
       
   519 EXPORT_C TInt CCoeTextDrawerBase::LineGapInPixels() const
       
   520 	{
       
   521 	return iLineGap;
       
   522 	}
       
   523 
       
   524 /**
       
   525 Set the gap (in pixels) between lines of text. Default gap is 1 (one) pixel.
       
   526 
       
   527 A typical user of the text drawer mechanism will use the XCoeTextDrawer version of this API.
       
   528 
       
   529 @param aLineGapInPixels The gap between lines of text, in pixels.
       
   530 */			
       
   531 EXPORT_C void CCoeTextDrawerBase::SetLineGapInPixels(TInt aLineGapInPixels)
       
   532 	{
       
   533  	iLineGap = aLineGapInPixels;
       
   534 	}
       
   535 
       
   536 /**
       
   537 Any text drawer implementation must override this method, returning the "margins" 
       
   538 that the text effect will add to the text extent. I.e. a one-pixel drop-shadow
       
   539 to the lower right will add an effect margin of TMargins8(0,0,1,1), while a 
       
   540 one-pixel all-around outline will add an effect margin of TMargins8(1,1,1,1).
       
   541 */
       
   542 EXPORT_C TMargins8 CCoeTextDrawerBase::EffectMargins()
       
   543 	{
       
   544 	return TMargins8();
       
   545 	}
       
   546 
       
   547 /**
       
   548 Draws the vertical text provided as parameter.
       
   549 
       
   550 @param aGc The graphics context.
       
   551 @param aText The TCoeTextTypeAdaptor text object to draw. 
       
   552 @param aFont Font to be used for drawing the text.
       
   553 @param aTextRect The rectangle to draw the text in.
       
   554 @param aClipRect The clipping rectangle.
       
   555 @param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
       
   556 */
       
   557 EXPORT_C void CCoeTextDrawerBase::DrawTextVertical(CGraphicsContext& aGc, const TCoeTextTypeAdaptor& aText, const CFont& aFont, 
       
   558 			const TRect& aTextRect, const TRect& aClipRect, TBool aUp) const
       
   559 	{
       
   560     const TInt lineSpacing = aFont.FontMaxHeight() +  LineGapInPixels();
       
   561 	const TInt textHeightInPixels = (aText.NumberOfLines() * lineSpacing) -  LineGapInPixels(); // Center the ascent
       
   562 	
       
   563 	// Calculate the text's "left point", i.e. the point on the baseline where the text starts
       
   564 	TPoint leftPoint =  Margins().InnerRect(aTextRect).iTl + TPoint(0,aFont.FontMaxAscent());
       
   565 	const TInt deltaHeight = aTextRect.Width() - Margins().SizeDelta().iHeight - textHeightInPixels;
       
   566 	if (deltaHeight > 0)
       
   567 		{
       
   568 		switch(Alignment().VAlignment())
       
   569 			{
       
   570 			case EVTop:
       
   571 				break;
       
   572 			case EVBottom:
       
   573 				leftPoint.iY +=  deltaHeight;
       
   574 				break;
       
   575 			case EVCenter:
       
   576 				leftPoint.iY +=  deltaHeight >> 1;
       
   577 				break;
       
   578 			}
       
   579 		}
       
   580 
       
   581 	// Set up the GC
       
   582 	aGc.UseFont(&aFont);
       
   583 	aGc.SetBrushStyle(CBitmapContext::ENullBrush);
       
   584 	aGc.SetPenStyle(CBitmapContext::ESolidPen);
       
   585 	aGc.SetPenColor(TextColor());
       
   586 	
       
   587 	// Compensate textRect for ClipRect
       
   588    	TRect textRect = aTextRect;
       
   589     if(!(aClipRect.IsEmpty()) && aClipRect != aTextRect)
       
   590     	{   	
       
   591     	textRect.Intersection(aClipRect);
       
   592     	}
       
   593    
       
   594 	// Use leftMargin and baseline to position each text line correctly, 
       
   595 	// taking margins, alignment, and line spacing into account
       
   596 	TInt baseline = leftPoint.iY - textRect.iTl.iY;
       
   597 	
       
   598 	// Draw the lines
       
   599 	const TInt lines = lineSpacing == 0 ? 1 : aText.NumberOfLines();
       
   600 	const TGulHAlignment actualHorizontalAlignment = ActualHorizontalAlignment(aText);
       
   601 	for (TInt i = 0; i < lines; ++i)
       
   602 		{
       
   603 		TInt width = 0;
       
   604 		TPtrC textLine = aText.LineOfText(i, width, aFont);
       
   605 		TInt margin = leftPoint.iX - textRect.iTl.iX;
       
   606 		 if (actualHorizontalAlignment != EHLeft)
       
   607 			{
       
   608 			const TInt wrapWidth = aTextRect.Height() -  Margins().SizeDelta().iWidth;
       
   609 			const TInt excess = wrapWidth - width;
       
   610 			margin += actualHorizontalAlignment != EHCenter ? excess : excess >> 1;	
       
   611 			}
       
   612 		aGc.DrawTextVertical(textLine, textRect, baseline, aUp, CGraphicsContext::ELeft, margin);
       
   613 		baseline += lineSpacing;
       
   614 		}
       
   615 	
       
   616 	aGc.DiscardFont();	
       
   617 	}
       
   618 
       
   619 // For future use	
       
   620 /** @internalComponent */
       
   621 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved3() { }
       
   622 /** @internalComponent */
       
   623 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved4() { }
       
   624 /** @internalComponent */
       
   625 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved5() { }
       
   626 /** @internalComponent */
       
   627 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved6() { }
       
   628 /** @internalComponent */
       
   629 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved7() { }
       
   630 /** @internalComponent */
       
   631 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved8() { }
       
   632 /** @internalComponent */
       
   633 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved9() { }
       
   634 /** @internalComponent */
       
   635 EXPORT_C void CCoeTextDrawerBase::CCoeTextDrawerBase_Reserved10() { }
       
   636  
       
   637 
       
   638 
       
   639 // 
       
   640 // class CCoePlainTextDrawer
       
   641 //
       
   642 
       
   643 /**
       
   644 Created a new plain text drawer on the heap. This shall typically be done in the
       
   645 CCoeControl::GetTextDrawer() method, or better, in the constructor of the owner
       
   646 of the text drawer.
       
   647 
       
   648 Do not call this method from within a CCoeControl::Draw() method. If all you want
       
   649 is access to a text drawer, call CCoeControl::TextDrawer().
       
   650 
       
   651 @param aTextColor The color that will be used to draw text.
       
   652 @return A new CCoePlainTextDrawer instance or null if the creation of a new instance failed.
       
   653 */
       
   654 EXPORT_C CCoePlainTextDrawer* CCoePlainTextDrawer::New(TRgb aTextColor)
       
   655 	{
       
   656 	CCoePlainTextDrawer* self = new  CCoePlainTextDrawer(aTextColor);
       
   657 
       
   658  	if(self && self->Construct() == KErrNone)
       
   659  		return self;	// Successful allocation
       
   660 	else 
       
   661 		{
       
   662 		delete self;
       
   663 		return NULL;	// Error in allocation
       
   664 		}
       
   665 	}
       
   666 
       
   667 /**
       
   668 Second-phase construction. This method is non-leaving as it will have been called indirectly 
       
   669 from a control's draw method which cannot leave.
       
   670 @return KErrNone if the function executed without errors, any other standard error code if the
       
   671 function failed.
       
   672 */	
       
   673 TInt CCoePlainTextDrawer::Construct()
       
   674 	{
       
   675 	return CCoeTextDrawerBase::Construct();	
       
   676 	//lint --e{1762} Suppress member function could be made const
       
   677 	}
       
   678 
       
   679 /**
       
   680 See CCoeTextDrawerBase::TextColor().
       
   681 
       
   682 @see CCoeTextDrawerBase
       
   683 */	
       
   684 EXPORT_C TRgb CCoePlainTextDrawer::TextColor() const
       
   685 	{
       
   686 	return iTextColor;
       
   687 	}
       
   688 
       
   689 /**
       
   690 See CCoeTextDrawerBase::SetTextColor().
       
   691 
       
   692 @see CCoeTextDrawerBase
       
   693 */	
       
   694 EXPORT_C void CCoePlainTextDrawer::SetTextColor(TRgb aTextColor)
       
   695 	{
       
   696 	iTextColor = aTextColor;
       
   697 	}
       
   698 	
       
   699 /**
       
   700 Constructor.
       
   701 */	
       
   702 CCoePlainTextDrawer::CCoePlainTextDrawer(TRgb aTextColor) : 
       
   703 	iTextColor(aTextColor)
       
   704 	{
       
   705 	}
       
   706 
       
   707 /**
       
   708 This function is defined by the MObjectProvider class. 
       
   709 It allows the actual type of text drawer to be identified.
       
   710 
       
   711 @param aId The type of the desired object.
       
   712 @return A pointer to an object.
       
   713 @see MObjectProvider
       
   714 */
       
   715 EXPORT_C TTypeUid::Ptr CCoePlainTextDrawer::MopSupplyObject(TTypeUid aId)
       
   716 	{
       
   717 	if (aId.iUid == ETypeId)
       
   718 		return aId.MakePtr(this);
       
   719 	else
       
   720 		return TTypeUid::Null();
       
   721 	}
       
   722 
       
   723 /**
       
   724 See CCoeTextDrawerBase::Reset().
       
   725 */
       
   726 void CCoePlainTextDrawer::Reset()
       
   727 	{
       
   728 	CCoeTextDrawerBase::Reset();
       
   729 	iTextColor = KRgbBlack;
       
   730 	}
       
   731 
       
   732 /**
       
   733 Draws the text provided as parameter.
       
   734 
       
   735 @param aGc The graphics context.
       
   736 @param aText The TCoeTextTypeAdaptor text object to draw. 
       
   737 @param aFont Font to be used for drawing the text.
       
   738 @param aTextRect The rectangle to draw the text in.
       
   739 @param aClipRect The clipping rectangle.
       
   740 
       
   741 @return void
       
   742 @see CCoeTextDrawerBase
       
   743 */
       
   744 void CCoePlainTextDrawer::DrawText(CGraphicsContext& aGc, const TCoeTextTypeAdaptor& aText, const CFont& aFont, 
       
   745 			const TRect& aTextRect, const TRect& aClipRect) const
       
   746 	{
       
   747 	const TInt lineSpacing = aFont.FontMaxHeight() +  LineGapInPixels();
       
   748 	const TInt textHeightInPixels = (aText.NumberOfLines() * lineSpacing) -  LineGapInPixels(); // Center the ascent
       
   749 	
       
   750 	// Calculate the text's "left point", i.e. the point on the baseline where the text starts
       
   751 	TPoint leftPoint =  Margins().InnerRect(aTextRect).iTl + TPoint(0,aFont.FontMaxAscent());
       
   752 	const TInt deltaHeight = Margins().InnerRect(aTextRect).Height() - textHeightInPixels;
       
   753 	if (deltaHeight > 0)
       
   754 		{
       
   755 		switch(Alignment().VAlignment())
       
   756 			{
       
   757 			case EVTop:
       
   758 				break;
       
   759 			case EVBottom:
       
   760 				leftPoint.iY += deltaHeight;
       
   761 				break;
       
   762 			case EVCenter:
       
   763 				leftPoint.iY += (deltaHeight >> 1);	// /2
       
   764 				break;
       
   765 			}
       
   766 		}
       
   767 
       
   768 	// Set up the GC
       
   769 	aGc.UseFont(&aFont);
       
   770 	aGc.SetBrushStyle(CBitmapContext::ENullBrush);
       
   771 	aGc.SetPenStyle(CBitmapContext::ESolidPen);
       
   772 	aGc.SetPenColor(iTextColor);		
       
   773 
       
   774 	// Compensate textRect for ClipRect
       
   775     TRect textRect = aTextRect;
       
   776     if(!(aClipRect.IsEmpty()))
       
   777     	textRect.Intersection(aClipRect);
       
   778     
       
   779 	// Use leftMargin and baseline to position each text line correctly, 
       
   780 	// taking margins, alignment, and line spacing into account
       
   781 	TInt baseline = leftPoint.iY - textRect.iTl.iY;
       
   782 	
       
   783 	const TGulHAlignment actualHorizontalAlignment = ActualHorizontalAlignment(aText);
       
   784 	
       
   785 	// Draw the lines
       
   786 	const TInt lines = lineSpacing == 0 ? 1 : aText.NumberOfLines();
       
   787 	for (TInt i = 0; i < lines; ++i)
       
   788 		{
       
   789 		TInt width = 0;
       
   790 		TPtrC textLine = aText.LineOfText(i, width, aFont);
       
   791 		TInt leftMargin = leftPoint.iX - textRect.iTl.iX;
       
   792 		if (actualHorizontalAlignment != EHLeft)
       
   793 			{
       
   794 			const TInt wrapWidth = aTextRect.Width() -  Margins().SizeDelta().iWidth;
       
   795 			const TInt excess = wrapWidth - width;
       
   796 			leftMargin += actualHorizontalAlignment != EHCenter ? excess : excess >> 1;
       
   797 			}
       
   798 			
       
   799 		aGc.DrawText(textLine, textRect, baseline, CGraphicsContext::ELeft, leftMargin);
       
   800 		baseline += lineSpacing;
       
   801 		}
       
   802 
       
   803 	aGc.DiscardFont();	
       
   804 	}
       
   805 
       
   806 //
       
   807 // TCoeTextTypeAdaptor
       
   808 //
       
   809 
       
   810 /**
       
   811 Constructor taking a plain descriptor as parameter. The directionality of the text separated with '\n'
       
   812 must always be left-to-right display order.
       
   813 @param aText The text wrapped by the TCoeTextTypeAdaptor.
       
   814 */
       
   815 EXPORT_C TCoeTextTypeAdaptor::TCoeTextTypeAdaptor(const TDesC& aText)	// text separated with '\n'
       
   816 	{
       
   817 	iTextType = ENewlineSeparated;
       
   818 	iText = static_cast<const void*>(&aText);
       
   819 	}
       
   820 
       
   821 /**
       
   822 Constructor taking a TBidiText object as parameter.
       
   823 @param aText The text wrapped by the TCoeTextTypeAdaptor.
       
   824 */	
       
   825 EXPORT_C TCoeTextTypeAdaptor::TCoeTextTypeAdaptor(const TBidiText& aText)	// TBidiText object
       
   826 	{
       
   827 	iTextType = EBidiText;
       
   828 	iText = &aText;
       
   829 	}
       
   830 
       
   831 const TText KCharacterLF = 0x0a;
       
   832 
       
   833 const TText* FindEndOfThisLine(const TText* aStart, const TText* aEnd)
       
   834 	{
       
   835 	while (aStart != aEnd && *aStart != KCharacterLF)
       
   836 		++aStart;
       
   837 
       
   838 	return aStart;	
       
   839 	}
       
   840 
       
   841 
       
   842 /**
       
   843 Calculates the number of lines in the text.
       
   844 @return TInt number of lines in the object
       
   845 */	
       
   846 EXPORT_C TInt TCoeTextTypeAdaptor::NumberOfLines() const
       
   847 	{
       
   848 	switch(iTextType)
       
   849 		{
       
   850 		case ENewlineSeparated:
       
   851 			{
       
   852 			const TText* startText = static_cast<const TDesC*>(iText)->Ptr();
       
   853 			const TInt length = static_cast<const TDesC*>(iText)->Length();
       
   854 			const TText* endText = startText + length; 
       
   855 			
       
   856 			TInt num = 0;
       
   857 			while (startText < endText)
       
   858 				{
       
   859 				startText = FindEndOfThisLine(startText, endText);
       
   860 				if (*startText == KCharacterLF && startText < endText)
       
   861 					{
       
   862 					++startText;
       
   863 					}
       
   864 				++num;
       
   865 				}
       
   866 			return num;
       
   867 			}
       
   868 		case EBidiText:
       
   869 			return static_cast<const TBidiText*>(iText)->NumberOfLinesInDisplayText();
       
   870 		default:
       
   871 			return 0;
       
   872 		}
       
   873 	}
       
   874 
       
   875 /**
       
   876 Extracts a line of text. The width (in pixels) of the line is returned in aWidthInPixels.
       
   877 @param  aLineNumber Zero-based line number.
       
   878 @param  aWidthInPixels The width of the line of text.
       
   879 @param  aFont The font that will be used to draw the text.
       
   880 @return TPtrC line of text
       
   881 */	
       
   882 EXPORT_C TPtrC TCoeTextTypeAdaptor::LineOfText(TInt aLineNumber, TInt& aWidthInPixels, const CFont& aFont) const
       
   883 	{
       
   884 	switch(iTextType)
       
   885 		{
       
   886 		case ENewlineSeparated:
       
   887 			{
       
   888 			const TText* startText = static_cast<const TDesC*>(iText)->Ptr();
       
   889 			const TInt length = static_cast<const TDesC*>(iText)->Length();
       
   890 			const TText* endText = startText + length; 
       
   891 
       
   892 			for (; aLineNumber != 0; --aLineNumber)
       
   893 				{
       
   894 				startText = FindEndOfThisLine(startText, endText);
       
   895 				if (*startText == KCharacterLF)
       
   896 					++startText;
       
   897 				}
       
   898 			const TText* endOfLine = FindEndOfThisLine(startText, endText);
       
   899 			TPtrC textInLineNumber(startText, endOfLine - startText);
       
   900 			// Calculate the width of the line according to the font used.
       
   901 			aWidthInPixels = aFont.TextWidthInPixels(textInLineNumber);
       
   902 			return textInLineNumber;
       
   903 			}
       
   904 		case EBidiText:
       
   905 			return static_cast<const TBidiText*>(iText)->LineOfDisplayText(aLineNumber, aWidthInPixels);
       
   906 		default:
       
   907 			return KNullDesC();
       
   908 		}
       
   909 	}
       
   910 
       
   911 /**
       
   912 This function checks the directionality of the text.
       
   913 @return ETrue if the text has right-to-left directionality, EFalse if it has left-to-right directionality.
       
   914 */
       
   915 EXPORT_C TBool TCoeTextTypeAdaptor::HasRightToLeftDirectionality() const
       
   916 	{
       
   917 	switch(iTextType)
       
   918 		{
       
   919 		case EBidiText:
       
   920 			return (static_cast<const TBidiText*>(iText)->Directionality() == TBidiText::ERightToLeft);
       
   921 		default:
       
   922 			return EFalse;
       
   923 		}
       
   924 	}