lafagnosticuifoundation/uigraphicsutils/gulsrc/GULBORDR.CPP
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 1997-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 <gdi.h>
       
    17 #include <gulbordr.h>
       
    18 #include <gulpanic.h>
       
    19 #include "GULSTD.H"
       
    20 #include "gullogicalborder.h"
       
    21 
       
    22 const TInt KTypeMask=0xFFFFFF00; 
       
    23 const TInt KAdjacentMask=0xF;
       
    24 
       
    25 const TInt KBorderTypeConversionMask=0x00FFFFFF;
       
    26 
       
    27 const TInt KBorderShift=0x8;
       
    28 const TInt KDepthBitPosition=0x4;
       
    29 const TInt KDepthShift=KBorderShift+KDepthBitPosition;
       
    30 
       
    31 //
       
    32 // Class MGulLogicalBorder
       
    33 //
       
    34 
       
    35 EXPORT_C void MGulLogicalBorder::MGulLogicalBorderReserved()
       
    36 	{
       
    37 	}
       
    38 
       
    39 //
       
    40 // Class GulTls
       
    41 //
       
    42 
       
    43 EXPORT_C void GulTls::SetLogicalBorder(MGulLogicalBorder* aLogicalBorder)
       
    44 	{
       
    45 	Dll::SetTls(REINTERPRET_CAST(TAny*,aLogicalBorder));
       
    46 	};
       
    47 
       
    48 EXPORT_C const MGulLogicalBorder* GulTls::LogicalBorder()
       
    49 	{
       
    50 	return REINTERPRET_CAST(const MGulLogicalBorder*,Dll::Tls());
       
    51 	}
       
    52 
       
    53 //
       
    54 // Class TGulBorder::TColors
       
    55 //
       
    56 
       
    57 EXPORT_C TGulBorder::TColors::TColors()
       
    58 	: iLine(KRgbBlack), iBack(KRgbWhite), iLight(KRgbWhite),
       
    59 	iMidlight(KRgbWhite), iMid(KRgbDarkGray), iDark(KRgbDarkGray), iInternalBack(KRgbWhite)
       
    60 /** Default constructor.
       
    61 
       
    62 Initialises the border colours to blacks, whites and greys. For details, see 
       
    63 the data members. */
       
    64 	{
       
    65 	}
       
    66 
       
    67 //
       
    68 // Class TGulBorder
       
    69 //
       
    70 
       
    71 EXPORT_C TGulBorder::TGulBorder()
       
    72 	: iType(0)
       
    73 /** Default constructor.
       
    74 
       
    75 The border type is initialised to zero (i.e. no border). */
       
    76 	{
       
    77 	}
       
    78 
       
    79 
       
    80 EXPORT_C TGulBorder::TGulBorder(TBorderType aType)
       
    81 	: iType(STATIC_CAST(TInt,aType)<<KBorderShift)
       
    82 /** Constructor with a border type.
       
    83 
       
    84 @param aType The border type. */
       
    85     {
       
    86 	TranslateLegacyTypes();
       
    87 	}
       
    88 
       
    89 
       
    90 EXPORT_C TGulBorder::TGulBorder(TBorderType aType,TGulAdjacent aAdjacent)
       
    91 	: iType((STATIC_CAST(TInt,aType)<<KBorderShift)|aAdjacent)
       
    92 /** Constructor with a border type and an adjacency.
       
    93 
       
    94 @param aType The border type.
       
    95 @param aAdjacent Border adjacency. No outline is drawn for border sides that 
       
    96 are adjacent. */
       
    97     {
       
    98 	TranslateLegacyTypes();
       
    99 	}
       
   100 
       
   101 EXPORT_C TGulBorder::TGulBorder(TInt aType)
       
   102 	: iType(aType<<KBorderShift)
       
   103 /** Constructor with a border type, specified as a TInt.
       
   104 
       
   105 @param aType The border type. Possible values are defined in the TBorderType 
       
   106 enumeration. */
       
   107     {
       
   108 	TranslateLegacyTypes();
       
   109 	}
       
   110 
       
   111 
       
   112 EXPORT_C TGulBorder::TGulBorder(TInt aType,TGulAdjacent aAdjacent)
       
   113 	: iType((aType<<KBorderShift)|aAdjacent)
       
   114 /** Constructor with a border type, specified as a TInt, and a border adjacency.
       
   115 
       
   116 @param aType The border type.
       
   117 @param aAdjacent Border adjacency. No outline is drawn for border sides that 
       
   118 are adjacent. */
       
   119     {
       
   120 	TranslateLegacyTypes();
       
   121 	}
       
   122 
       
   123 EXPORT_C void TGulBorder::SetType(TInt aType)
       
   124 /** Sets the border type.
       
   125 
       
   126 Descriptive borders use one of the values from the TBorderType enum. Logical 
       
   127 borders use one of the TLogicalType values. Custom border types can be created 
       
   128 by selecting one value from each of the enums T3DStyle and TConstructionStyle, 
       
   129 one or more values from each of the enums TOutlineStyle and TInlineStyle, 
       
   130 one or more values from the enums TThickness and TRounding and ORing all these 
       
   131 values together.
       
   132 
       
   133 @param aType The border type. */
       
   134     {
       
   135     iType&=(~KTypeMask);
       
   136     iType|=(aType<<KBorderShift);
       
   137 
       
   138 	TranslateLegacyTypes();
       
   139     }
       
   140 
       
   141 //
       
   142 // Translates legacy border types which now affect the adjacency as well as the border
       
   143 // primitive type.
       
   144 //
       
   145 void TGulBorder::TranslateLegacyTypes()
       
   146 	{
       
   147 	TInt internalType=InternalType();
       
   148 
       
   149 	if(internalType&EWithOverlap)
       
   150 		{
       
   151 		if(internalType&EHorizontal)
       
   152 			SetAdjacent(EGulAdjTop|EGulAdjBottom);
       
   153 		else
       
   154 			SetAdjacent(EGulAdjLeft|EGulAdjRight);
       
   155 	    iType|=(EWithOutline<<KBorderShift);
       
   156 		}
       
   157 	}
       
   158 
       
   159 
       
   160 EXPORT_C TInt TGulBorder::Type() const
       
   161 /** Gets the border type. 
       
   162 
       
   163 @return The border type. This is one of the values from the TBorderType (for 
       
   164 descriptive borders) or TLogicalType (for logical borders) enums. */
       
   165     {
       
   166     return (KBorderTypeConversionMask&((iType&KTypeMask)>>KBorderShift));
       
   167     }
       
   168 
       
   169 EXPORT_C void TGulBorder::SetAdjacent(TInt aAdjacent)
       
   170 /** Sets the border adjacency.
       
   171 
       
   172 No outline is drawn for border sides that are adjacent.
       
   173 
       
   174 @param aAdjacent The border adjacency. For possible values, see the TGulAdjacent 
       
   175 enum. */
       
   176     {
       
   177     iType&=(~KAdjacentMask);
       
   178     iType|=(KAdjacentMask & aAdjacent);
       
   179     }
       
   180 
       
   181 inline TInt TGulBorder::Depth() const
       
   182 	{
       
   183 	return (iType>>KDepthShift)&0x3;
       
   184 	}
       
   185 
       
   186 EXPORT_C TBool TGulBorder::HasBorder() const
       
   187 /** Tests whether a border is present.
       
   188 
       
   189 No border is present if its type is ENoBorder.
       
   190 
       
   191 @return True if a border is present, otherwise false. */
       
   192 	{
       
   193 	return (!(((iType&KTypeMask)>>KBorderShift)==ENoBorder));
       
   194 	}
       
   195 
       
   196 
       
   197 EXPORT_C TInt TGulBorder::Adjacent() const
       
   198 /** Gets the border adjacency.
       
   199 
       
   200 No outline is drawn for border sides that are adjacent.
       
   201 
       
   202 @return The border adjacency. For possible values, see the TGulAdjacent enum. */
       
   203 	{
       
   204 	return iType&KAdjacentMask;
       
   205 	}
       
   206 
       
   207 
       
   208 inline TBool TGulBorder::IsSunken() const
       
   209 	{
       
   210 	return (iType>>KBorderShift)&ESunken;
       
   211 	}
       
   212 
       
   213 //
       
   214 // Returns the innner rectangular area of the outline
       
   215 // Simply returns the outer rectangle if there is no outline 
       
   216 //
       
   217 TRect TGulBorder::OutlineInnerRect(const TRect& aOuterRect) const
       
   218     {
       
   219 	if (!(InternalType()&EWithOutline))
       
   220 		return aOuterRect;
       
   221 	
       
   222 	TRect inner=aOuterRect;
       
   223     TMargins margins=OutlineMargins();
       
   224     inner.iTl.iX+=margins.iLeft;
       
   225     inner.iTl.iY+=margins.iTop;
       
   226     inner.iBr.iX-=margins.iRight;
       
   227     inner.iBr.iY-=margins.iBottom;
       
   228     return inner;
       
   229     }
       
   230 
       
   231 //
       
   232 // Returns the number of rounding pixels for the start of the mid-tone colored part of the border.
       
   233 //
       
   234 TInt TGulBorder::BorderRounding() const
       
   235 	{
       
   236 	TInt rounding=Rounding();
       
   237 	if (InternalType()&EWithOutline)
       
   238 		rounding--;
       
   239 	return (rounding<0 ? 0 : rounding);
       
   240 	}
       
   241 
       
   242 //
       
   243 // Returns the number of rounding pixels at the inline.
       
   244 //
       
   245 TInt TGulBorder::InlineRounding() const
       
   246 	{
       
   247 	TInt rounding=BorderRounding();
       
   248 	rounding-=Thickness();
       
   249 	return (rounding<0 ? 0 : rounding);
       
   250 	}
       
   251 
       
   252 EXPORT_C TMargins TGulBorder::Margins() const
       
   253 /** Returns the border margins.
       
   254 
       
   255 The border margins are four integers that represent the widths in pixels of 
       
   256 the top, bottom, left and right hand sides of the border.
       
   257 
       
   258 If the border is a logical border, then calculating the margins is delegated 
       
   259 to its implementation of MGulLogicalBorder::Margins().
       
   260 
       
   261 Otherwise, the margins are calculated by adding together the single pixel 
       
   262 border outline, if present (this is zero for adjacent sides), the border thickness 
       
   263 (containing the mid-tone highlights and lowlights), and the single pixel interior 
       
   264 outline, if present.
       
   265 
       
   266 @return The border margins. */
       
   267     {
       
   268 	// Delegates the margin size determination to TLS instance of MGulLogicalBorder if logical border
       
   269 	if (InternalType()&ELogical)
       
   270 		{
       
   271 		const MGulLogicalBorder* logicalBorder=GulTls::LogicalBorder();
       
   272 		__ASSERT_DEBUG(logicalBorder,Panic(EEgulPanicNullTls));
       
   273 		return logicalBorder ? logicalBorder->Margins(*this) : TMargins();
       
   274 		}
       
   275 
       
   276     TMargins margins=OutlineMargins();
       
   277 	
       
   278 	TMargins borderMargins=BorderMargins();
       
   279 
       
   280 	margins.iTop+=borderMargins.iTop;
       
   281 	margins.iLeft+=borderMargins.iLeft;
       
   282 	margins.iRight+=borderMargins.iRight;
       
   283 	margins.iBottom+=borderMargins.iBottom;
       
   284 
       
   285 	TMargins inlineMargins=InlineMargins();
       
   286 
       
   287 	margins.iTop+=inlineMargins.iTop;
       
   288 	margins.iLeft+=inlineMargins.iLeft;
       
   289 	margins.iRight+=inlineMargins.iRight;
       
   290 	margins.iBottom+=inlineMargins.iBottom;
       
   291 
       
   292 	return margins;
       
   293     }
       
   294 
       
   295 //
       
   296 // Returns the margins for the single pixel outline only
       
   297 // Margins are zero if the border has no outline.
       
   298 // There is no margin on sides which are adjacent.
       
   299 //
       
   300 TMargins TGulBorder::OutlineMargins() const
       
   301     {
       
   302 	TMargins margins;
       
   303 
       
   304 	margins.iTop=margins.iLeft=0;
       
   305 	margins.iBottom=margins.iRight=0;
       
   306 
       
   307 	if (!(InternalType()&EWithOutline))
       
   308 		return margins;
       
   309 
       
   310 	if (!(iType&EGulAdjLeft))
       
   311 		margins.iLeft+=1;
       
   312 
       
   313 	if (!(iType&EGulAdjTop))
       
   314 		margins.iTop+=1;
       
   315 
       
   316 	if (!(iType&EGulAdjRight))
       
   317 		margins.iRight+=1;
       
   318 
       
   319 	if (!(iType&EGulAdjBottom))
       
   320 		margins.iBottom+=1;
       
   321 
       
   322     return margins;
       
   323 	}
       
   324 
       
   325 
       
   326 TMargins TGulBorder::BorderMargins() const
       
   327     {
       
   328     TMargins margins;
       
   329 
       
   330 	TInt topLeftMargin=0;
       
   331 	TInt bottomRightMargin=0;
       
   332 
       
   333 	if (InternalType()&EOneStep)
       
   334 		topLeftMargin=bottomRightMargin=Thickness();
       
   335 	else if (InternalType()&ETwoStep || InternalType()&EInvertedTwoStep)
       
   336 		{
       
   337 		if((InternalType()&ERaised && !(InternalType()&EInvertedTwoStep)) || (InternalType()&ESunken && (InternalType()&EInvertedTwoStep)))
       
   338 			{
       
   339 			topLeftMargin=1;
       
   340 			bottomRightMargin=Thickness()+1;
       
   341 			}
       
   342 		else
       
   343 			{
       
   344 			topLeftMargin=Thickness()+1;
       
   345 			bottomRightMargin=1;
       
   346 			}
       
   347 		}
       
   348 	else if (InternalType()&EThreeStep)
       
   349 		topLeftMargin=bottomRightMargin=Thickness()+1;
       
   350 
       
   351 	margins.iTop=topLeftMargin;
       
   352 	margins.iLeft=topLeftMargin;
       
   353 	margins.iBottom=bottomRightMargin;
       
   354 	margins.iRight=bottomRightMargin;
       
   355 
       
   356 	return margins;
       
   357     }
       
   358 
       
   359 TMargins TGulBorder::InlineMargins() const
       
   360     {
       
   361     TMargins margins;
       
   362 
       
   363 	TInt marginWidth = 0;
       
   364 
       
   365 	if (InternalType()&EWithInline)
       
   366 		marginWidth++;
       
   367 
       
   368 	margins.iTop=marginWidth;
       
   369 	margins.iLeft=marginWidth;
       
   370 	margins.iBottom=marginWidth;
       
   371 	margins.iRight=marginWidth;
       
   372 	
       
   373 	return margins;
       
   374     }
       
   375 
       
   376 EXPORT_C TSize TGulBorder::SizeDelta() const
       
   377 /** Returns the size difference between the inner and outer rectangles of the border.
       
   378 
       
   379 @return The size difference between the inner and outer rectangles. */
       
   380     {
       
   381     TMargins margins=Margins();
       
   382     return TSize(margins.iLeft+margins.iRight,margins.iTop+margins.iBottom);
       
   383     }
       
   384 
       
   385 EXPORT_C TRect TGulBorder::OuterRect(const TRect& aInnerRect) const
       
   386 /** Returns the rectangular area required to accommodate the inner rectangle aInnerRect
       
   387 and the border.
       
   388 
       
   389 @param aInnerRect The inner rectangular area.
       
   390 @return The enclosing rectangular area. */
       
   391     {
       
   392     TRect outer=aInnerRect;
       
   393     TMargins margins=Margins();
       
   394     outer.iTl.iX-=margins.iLeft;
       
   395     outer.iTl.iY-=margins.iTop;
       
   396     outer.iBr.iX+=margins.iRight;
       
   397     outer.iBr.iY+=margins.iBottom;
       
   398     return outer;
       
   399     }
       
   400 
       
   401 EXPORT_C TRect TGulBorder::InnerRect(const TRect& aOuterRect) const
       
   402 /** Returns the rectangular area enclosed by the border.
       
   403 
       
   404 @param aOuterRect The border's containing rectangle.
       
   405 @return The inner rectangle. */
       
   406     {
       
   407     TRect inner=aOuterRect;
       
   408     TMargins margins=Margins();
       
   409     inner.iTl.iX+=margins.iLeft;
       
   410     inner.iTl.iY+=margins.iTop;
       
   411     inner.iBr.iX-=margins.iRight;
       
   412     inner.iBr.iY-=margins.iBottom;
       
   413     return inner;
       
   414     }
       
   415 
       
   416 
       
   417 TRect TGulBorder::BorderInnerRect(const TRect& aOuterRect) const
       
   418     {
       
   419     TRect inner=aOuterRect;
       
   420     TMargins margins=BorderMargins();
       
   421     inner.iTl.iX+=margins.iLeft;
       
   422     inner.iTl.iY+=margins.iTop;
       
   423     inner.iBr.iX-=margins.iRight;
       
   424     inner.iBr.iY-=margins.iBottom;
       
   425     return inner;
       
   426     }
       
   427 
       
   428 EXPORT_C void TGulBorder::Draw(CGraphicsContext& aGc,const TRect& aRect) const
       
   429 /** Draws the border using a graphics context, inside a containing rectangle, and 
       
   430 using default values for the border colours. 
       
   431 
       
   432 For details of the default border colours, see class TColors.
       
   433 
       
   434 This function does nothing if the border type is ENone. If the border is a 
       
   435 logical border, drawing is delegated to its implementation of MGulLogicalBorder::Draw().
       
   436 
       
   437 @param aGc The graphics context to draw through.
       
   438 @param aRect The containing rectangle. This defines the border's outline, i.e. 
       
   439 the border is drawn inside this rectangle.
       
   440 @see MGulLogicalBorder::Draw() */
       
   441     {
       
   442 	TColors borderColors;
       
   443 	Draw(aGc,aRect,borderColors);
       
   444     }
       
   445 
       
   446 EXPORT_C void TGulBorder::Draw(CGraphicsContext& aGc,const TRect& aRect, const TColors& aBorderColors) const
       
   447 /** Draws the border using a graphics context, inside a containing rectangle, and 
       
   448 using the border colours specified.
       
   449 
       
   450 This function does nothing if the border type is ENone. If the border is a 
       
   451 logical border, drawing is delegated to its implementation of MGulLogicalBorder::Draw().
       
   452 
       
   453 @param aGc The graphics context to draw through.
       
   454 @param aRect The containing rectangle. This defines the border's outline, i.e. 
       
   455 the border is drawn inside this rectangle.
       
   456 @param aBorderColors The border colours.
       
   457 @see MGulLogicalBorder::Draw() */
       
   458     {
       
   459     if (!HasBorder())
       
   460         return;
       
   461 	
       
   462 	// Delegate drawing of logical border to TLS instance of MGulLogicalBorder if logical border
       
   463 	if (InternalType()&ELogical)
       
   464 		{
       
   465 		const MGulLogicalBorder* logicalBorder=GulTls::LogicalBorder();
       
   466 		__ASSERT_DEBUG(logicalBorder,Panic(EEgulPanicNullTls));
       
   467 		if(logicalBorder)
       
   468 			{
       
   469 			logicalBorder->Draw(*this,aGc,aRect,aBorderColors);
       
   470 			}
       
   471 		return;
       
   472 		}
       
   473 
       
   474 	TRect workingRect=aRect;
       
   475 	DrawOutline(aGc,workingRect,aBorderColors.iLine);
       
   476 
       
   477 	if (Thickness())
       
   478 		{
       
   479 		workingRect=OutlineInnerRect(workingRect);
       
   480 
       
   481 		if (InternalType()&EOneStep)
       
   482 			DrawOneStep(aGc,workingRect,aBorderColors.iMidlight,aBorderColors.iMid);
       
   483 		else if (InternalType()&ETwoStep)
       
   484 			DrawTwoStep(aGc,workingRect,aBorderColors.iLight,aBorderColors.iMidlight,aBorderColors.iMid,aBorderColors.iDark);
       
   485 		else if (InternalType()&EInvertedTwoStep)
       
   486 			DrawInvertedTwoStep(aGc,workingRect,aBorderColors.iLight,aBorderColors.iMidlight,aBorderColors.iMid,aBorderColors.iDark);
       
   487 		else if (InternalType()&EThreeStep)
       
   488 			DrawThreeStep(aGc,workingRect,aBorderColors.iBack,aBorderColors.iLight,aBorderColors.iMidlight,aBorderColors.iMid,aBorderColors.iDark);
       
   489 		}
       
   490 
       
   491 	workingRect=BorderInnerRect(workingRect);
       
   492 	DrawInline(aGc,workingRect,aBorderColors.iLine);
       
   493     }
       
   494 
       
   495 
       
   496 void TGulBorder::DrawInline(CGraphicsContext& aGc,const TRect& aRect,TRgb aColor) const
       
   497     {
       
   498 	if (!(InternalType()&EWithInline))
       
   499 		return;
       
   500 
       
   501 	TInt rounding=InlineRounding();
       
   502 
       
   503 	DrawTopLeft(aGc,aRect,aColor,rounding);
       
   504 	DrawBottomRight(aGc,aRect,aColor,rounding);
       
   505 	}
       
   506 
       
   507 //
       
   508 // Draws the optional single pixel outline
       
   509 // If there is no outline no drawing is done.
       
   510 //
       
   511 void TGulBorder::DrawOutline(CGraphicsContext& aGc,const TRect& aRect,TRgb aColor) const
       
   512     {
       
   513 	if (!(InternalType()&EWithOutline))
       
   514 		return;
       
   515 
       
   516 	// legacy border types color support
       
   517 	TRgb color;
       
   518 	const TInt internalType=InternalType();
       
   519 	if(internalType&EBlack)
       
   520 		color=KRgbBlack;
       
   521 	else if(internalType&EGray)
       
   522 		color=KRgbGray;
       
   523 	else
       
   524 		color=aColor;
       
   525 	//
       
   526 
       
   527 	aGc.SetPenColor(color);
       
   528 	if (internalType&EDottedOutline)
       
   529 		aGc.SetPenStyle(CGraphicsContext::EDottedPen);
       
   530 
       
   531 	TInt rounding=Rounding();
       
   532 
       
   533 	if (rounding)
       
   534 		{
       
   535 		DrawTopLeft(aGc,aRect,color,rounding);
       
   536 		DrawBottomRight(aGc,aRect,color,rounding);
       
   537 		}
       
   538 	else
       
   539 		DrawRectOutline(aGc,aRect);
       
   540 
       
   541 	if (internalType&EDottedOutline)
       
   542 		aGc.SetPenStyle(CGraphicsContext::ESolidPen);
       
   543 	}
       
   544 
       
   545 
       
   546 //
       
   547 // Draws the rectangular version of the outline
       
   548 // The outline is not drawn on sides which are adjacent
       
   549 //
       
   550 void TGulBorder::DrawRectOutline(CGraphicsContext& aGc,const TRect& aRect) const
       
   551     {
       
   552 	// left
       
   553 	if (!(iType&EGulAdjLeft))
       
   554 		aGc.DrawLine(TPoint(aRect.iTl.iX,aRect.iBr.iY-1),TPoint(aRect.iTl.iX,aRect.iTl.iY-1));
       
   555 
       
   556 	// top
       
   557 	if (!(iType&EGulAdjTop))
       
   558 		aGc.DrawLine(TPoint(aRect.iTl.iX,aRect.iTl.iY),TPoint(aRect.iBr.iX,aRect.iTl.iY));
       
   559 
       
   560 	// right
       
   561 	if (!(iType&EGulAdjRight))
       
   562 		aGc.DrawLine(TPoint(aRect.iBr.iX-1,aRect.iTl.iY),TPoint(aRect.iBr.iX-1,aRect.iBr.iY));
       
   563 	
       
   564 	// bottom
       
   565 	if (!(iType&EGulAdjBottom))
       
   566 		aGc.DrawLine(TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1),TPoint(aRect.iTl.iX-1,aRect.iBr.iY-1));
       
   567 	}
       
   568 
       
   569 //
       
   570 // Draws the one step border type.
       
   571 // This consists of repeated one pixel frames drawn in the mid-tone highlight and lowlight colors
       
   572 //	
       
   573 void TGulBorder::DrawOneStep(CGraphicsContext& aGc,const TRect& aRect,TRgb aMidlight,TRgb aMid) const
       
   574     {	
       
   575 	TRect workingRect = aRect;
       
   576 
       
   577 	TRgb topOneColor=aMidlight;
       
   578 	TRgb bottomOneColor=aMid;
       
   579 
       
   580 	if (InternalType()&ESunken)
       
   581 		{
       
   582 		topOneColor=aMid;
       
   583 		bottomOneColor=aMidlight;
       
   584 		}
       
   585 
       
   586 	if (InternalType()&EFlat)
       
   587 		topOneColor=aMid;
       
   588 
       
   589 	TInt rounding=BorderRounding();
       
   590 
       
   591 	for(int i=0;i<Thickness();i++)
       
   592 		{
       
   593 		DrawBottomRight(aGc,workingRect,bottomOneColor,rounding);
       
   594 		DrawTopLeft(aGc,workingRect,topOneColor,rounding);
       
   595 		rounding--;
       
   596 		workingRect.Shrink(1,1);
       
   597 		}
       
   598 	}
       
   599 
       
   600 //
       
   601 // Draws the two step border type.
       
   602 // The outer closed frame is drawn in highlihgt and lowlight colors
       
   603 // A repeating one pixel half-frame is then drawn in either the mid-tone highlight or lowlight color.
       
   604 //
       
   605 void TGulBorder::DrawTwoStep(CGraphicsContext& aGc,const TRect& aRect,TRgb aLight,TRgb aMidlight,TRgb aMid,TRgb aDark) const
       
   606     {	
       
   607 	TRect workingRect = aRect;
       
   608 	TBool drawTopLeftOnly=EFalse;
       
   609 
       
   610 	TRgb topOneColor=aMid;
       
   611 	TRgb bottomOneColor=aMid;
       
   612 	TRgb topTwoColor=aLight;
       
   613 	TRgb bottomTwoColor=aDark;
       
   614 
       
   615 	if (InternalType()&ESunken)
       
   616 		{
       
   617 		topTwoColor=aDark;
       
   618 		bottomTwoColor=aLight;
       
   619 		drawTopLeftOnly=ETrue;
       
   620 		}
       
   621 
       
   622 	if (InternalType()&EFlat)
       
   623 		{
       
   624 		topTwoColor=aMidlight;
       
   625 		bottomTwoColor=aMidlight;
       
   626 		drawTopLeftOnly=ETrue;
       
   627 		}
       
   628 	
       
   629 	TInt rounding=BorderRounding();
       
   630 
       
   631 	DrawBottomRight(aGc,workingRect,bottomTwoColor,rounding);
       
   632 	DrawTopLeft(aGc,workingRect,topTwoColor,rounding);
       
   633 	rounding--;
       
   634 	if (drawTopLeftOnly)
       
   635 		{
       
   636 		workingRect.iTl.iX+=1;
       
   637 		workingRect.iTl.iY+=1;
       
   638 		workingRect.iBr.iY-=1;
       
   639 		}
       
   640 	else
       
   641 		{
       
   642 		workingRect.iTl.iX+=1;
       
   643 		workingRect.iBr.iX-=1;
       
   644 		workingRect.iBr.iY-=1;
       
   645 		}
       
   646 
       
   647 	for(int i=0;i<Thickness();i++)
       
   648 		{
       
   649 		if (drawTopLeftOnly)
       
   650 			{
       
   651 			DrawTopLeft(aGc,workingRect,topOneColor,rounding);
       
   652 			rounding--;
       
   653 			workingRect.iTl.iX+=1;
       
   654 			workingRect.iTl.iY+=1;
       
   655 			}
       
   656 		else
       
   657 			{	
       
   658 			DrawBottomRight(aGc,workingRect,bottomOneColor,rounding);
       
   659 			rounding--;
       
   660 			workingRect.iBr.iX-=1;
       
   661 			workingRect.iBr.iY-=1;
       
   662 			}
       
   663 		}
       
   664 	}
       
   665 
       
   666 //
       
   667 // Draw the inverted two step border type.
       
   668 // As above the outer closed frame is drawn in highlihgt and lowlight colors
       
   669 // A repeating one pixel half-frame is then drawn in either the mid-tone highlight or lowlight color.
       
   670 // The difference is that the raised border show using top-left midlight etc.
       
   671 // Another small difference is that sunken has light, midlight colors swapped
       
   672 //
       
   673 void TGulBorder::DrawInvertedTwoStep(CGraphicsContext& aGc,const TRect& aRect,TRgb aLight,TRgb aMidlight,TRgb aMid,TRgb aDark) const
       
   674     {	
       
   675 	TRect workingRect = aRect;
       
   676 	TBool drawTopLeftOnly=ETrue;
       
   677 
       
   678 	TRgb topOneColor=aMidlight;
       
   679 	TRgb bottomOneColor=aMidlight;
       
   680 	TRgb topTwoColor=aLight;
       
   681 	TRgb bottomTwoColor=aDark;
       
   682 
       
   683 	if (InternalType()&ESunken)
       
   684 		{
       
   685 		topTwoColor=aDark;
       
   686 		bottomTwoColor=aMidlight;
       
   687 		bottomOneColor=aLight;
       
   688 		drawTopLeftOnly=EFalse;
       
   689 		}
       
   690 
       
   691 	if (InternalType()&EFlat)
       
   692 		{
       
   693 		topTwoColor=aMid;
       
   694 		bottomTwoColor=aMid;
       
   695 		drawTopLeftOnly=EFalse;
       
   696 		}
       
   697 	
       
   698 	TInt rounding=BorderRounding();
       
   699 
       
   700 	DrawBottomRight(aGc,workingRect,bottomTwoColor,rounding);
       
   701 	DrawTopLeft(aGc,workingRect,topTwoColor,rounding);
       
   702 	rounding--;
       
   703 	if (drawTopLeftOnly)
       
   704 		{
       
   705 		workingRect.iTl.iX+=1;
       
   706 		workingRect.iTl.iY+=1;
       
   707 		workingRect.iBr.iY-=1;
       
   708 		}
       
   709 	else
       
   710 		{
       
   711 		workingRect.iTl.iX+=1;
       
   712 		workingRect.iBr.iX-=1;
       
   713 		workingRect.iBr.iY-=1;
       
   714 		}
       
   715 
       
   716 	for(int i=0;i<Thickness();i++)
       
   717 		{
       
   718 		if (drawTopLeftOnly)
       
   719 			{
       
   720 			DrawTopLeft(aGc,workingRect,topOneColor,rounding);
       
   721 			rounding--;
       
   722 			workingRect.iTl.iX+=1;
       
   723 			workingRect.iTl.iY+=1;
       
   724 			}
       
   725 		else
       
   726 			{	
       
   727 			DrawBottomRight(aGc,workingRect,bottomOneColor,rounding);
       
   728 			rounding--;
       
   729 			workingRect.iBr.iX-=1;
       
   730 			workingRect.iBr.iY-=1;
       
   731 			}
       
   732 		}
       
   733 	}
       
   734 
       
   735 //
       
   736 // Draws the three step border type.
       
   737 // The outer frame is drawn in combined colors
       
   738 // A repeating one pixel frame is then drawn in the mid-tone highlight and lowlight colors.
       
   739 // The inner frame is drawn in combined colors
       
   740 //
       
   741 void TGulBorder::DrawThreeStep(CGraphicsContext& aGc,const TRect& aRect,TRgb aBack,TRgb aLight,TRgb aMidlight,TRgb aMid,TRgb aDark) const
       
   742     {
       
   743 	TRect workingRect = aRect;
       
   744 
       
   745 	TRgb topOneColor=aBack;
       
   746 	TRgb bottomOneColor=aMid;
       
   747 	TRgb topTwoColor=aLight;
       
   748 	TRgb bottomTwoColor=aDark;
       
   749 
       
   750 	if (InternalType()&ESunken)
       
   751 		{
       
   752 		topOneColor=aMid;
       
   753 		bottomOneColor=aBack;
       
   754 		topTwoColor=aDark;
       
   755 		bottomTwoColor=aLight;
       
   756 		}
       
   757 
       
   758 	if (InternalType()&EFlat)
       
   759 		{
       
   760 		topOneColor=aMid;
       
   761 		bottomOneColor=aMid;
       
   762 		topTwoColor=aMidlight;
       
   763 		bottomTwoColor=aMidlight;
       
   764 		}
       
   765 	
       
   766 	TInt rounding=BorderRounding();
       
   767 
       
   768 	DrawBottomRight(aGc,workingRect,bottomTwoColor,rounding);
       
   769 	DrawTopLeft(aGc,workingRect,topOneColor,rounding);
       
   770 	rounding--;
       
   771 	workingRect.Shrink(1,1);
       
   772 
       
   773 	for(int i=1;i<Thickness();i++)
       
   774 		{
       
   775 		DrawBottomRight(aGc,workingRect,bottomOneColor,rounding);
       
   776 		DrawTopLeft(aGc,workingRect,topOneColor,rounding);
       
   777 		rounding--;
       
   778 		workingRect.Shrink(1,1);
       
   779 		}
       
   780 
       
   781 	DrawBottomRight(aGc,workingRect,bottomOneColor,rounding);
       
   782 	DrawTopLeft(aGc,workingRect,topTwoColor,rounding);
       
   783 	}
       
   784 
       
   785 //
       
   786 // Draws the top left portion of the one pixel border frame
       
   787 //
       
   788 void TGulBorder::DrawTopLeft(CGraphicsContext& aGc,const TRect& aRect,TRgb aColor,const TInt aRounding) const
       
   789     {
       
   790 	TInt xOffset=0;
       
   791 	TInt yOffset=0;
       
   792 
       
   793 	if ((InternalType()&EFlat) || (InternalType()&ERaised))
       
   794 		xOffset=1;
       
   795 
       
   796 	if(InternalType()&ESunken)
       
   797 		yOffset=1;
       
   798 
       
   799 	if((InternalType()&EFlat) && (InternalType()&EThreeStep))
       
   800 		{
       
   801 		xOffset=1;
       
   802 		yOffset=1;
       
   803 		}
       
   804 
       
   805 	aGc.SetPenColor(aColor);
       
   806 
       
   807 	if (aRounding>0)
       
   808 		DrawRoundedTopLeft(aGc,aRect,aRounding);
       
   809 	else
       
   810 		{
       
   811 		// left
       
   812 		aGc.DrawLine(TPoint(aRect.iTl.iX,aRect.iTl.iY),TPoint(aRect.iTl.iX,aRect.iBr.iY-yOffset));
       
   813 		// top
       
   814 		aGc.DrawLine(TPoint(aRect.iTl.iX,aRect.iTl.iY),TPoint(aRect.iBr.iX-xOffset,aRect.iTl.iY));
       
   815 		}
       
   816 	}
       
   817 
       
   818 //
       
   819 // Draws a rounded off version top left portion of the one pixel border frame
       
   820 //
       
   821 void TGulBorder::DrawRoundedTopLeft(CGraphicsContext& aGc,const TRect& aRect,const TInt aRounding) const
       
   822     {
       
   823 	// left
       
   824 	aGc.DrawLine(TPoint(aRect.iTl.iX,aRect.iTl.iY+aRounding),TPoint(aRect.iTl.iX,aRect.iBr.iY-aRounding));
       
   825 	// top left corner
       
   826 	DrawRoundedCorner(aGc,TPoint(aRect.iTl.iX,aRect.iTl.iY+aRounding),aRounding,ETrue,ETrue);
       
   827 	// top
       
   828 	aGc.DrawLine(TPoint(aRect.iTl.iX+aRounding,aRect.iTl.iY),TPoint(aRect.iBr.iX-aRounding,aRect.iTl.iY));
       
   829 	}
       
   830 
       
   831 //
       
   832 // Draws the bottom right portion of the one pixel border frame
       
   833 //
       
   834 void TGulBorder::DrawBottomRight(CGraphicsContext& aGc,const TRect& aRect,TRgb aColor,const TInt aRounding) const
       
   835     {
       
   836 	TInt xOffset=0;
       
   837 	TInt yOffset=0;
       
   838 
       
   839 	if ((InternalType()&EFlat) || (InternalType()&ERaised))
       
   840 		xOffset=1;
       
   841 
       
   842 	if(InternalType()&ESunken)
       
   843 		yOffset=1;
       
   844 
       
   845 	if((InternalType()&EFlat) && (InternalType()&EThreeStep))
       
   846 		{
       
   847 		xOffset=1;
       
   848 		yOffset=1;
       
   849 		}
       
   850 
       
   851 	aGc.SetPenColor(aColor);
       
   852 
       
   853 	if (aRounding>0)
       
   854 		DrawRoundedBottomRight(aGc,aRect,aRounding);
       
   855 	else
       
   856 		{
       
   857 		// right
       
   858 		aGc.DrawLine(TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1),TPoint(aRect.iBr.iX-1,aRect.iTl.iY-1+yOffset));
       
   859 		// bottom
       
   860 		aGc.DrawLine(TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1),TPoint(aRect.iTl.iX-1+xOffset,aRect.iBr.iY-1));
       
   861 		}
       
   862 	}
       
   863 
       
   864 //
       
   865 // Draws a rounded off version of the bottom right portion of the one pixel border frame
       
   866 //
       
   867 void TGulBorder::DrawRoundedBottomRight(CGraphicsContext& aGc,const TRect& aRect,const TInt aRounding) const
       
   868     {
       
   869 	// top right corner
       
   870 	DrawRoundedCorner(aGc,TPoint(aRect.iBr.iX-1,aRect.iTl.iY+aRounding),aRounding,ETrue,EFalse);	
       
   871 	// right
       
   872 	aGc.DrawLine(TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1-aRounding),TPoint(aRect.iBr.iX-1,aRect.iTl.iY-1+aRounding));
       
   873 	// bottom right corner
       
   874 	DrawRoundedCorner(aGc,TPoint(aRect.iBr.iX-1,aRect.iBr.iY-1-aRounding),aRounding,EFalse,EFalse);
       
   875 	// bottom
       
   876 	aGc.DrawLine(TPoint(aRect.iBr.iX-1-aRounding,aRect.iBr.iY-1),TPoint(aRect.iTl.iX-1+aRounding,aRect.iBr.iY-1));
       
   877 	// bottom left corner
       
   878 	DrawRoundedCorner(aGc,TPoint(aRect.iTl.iX,aRect.iBr.iY-1-aRounding),aRounding,EFalse,ETrue);
       
   879 	}
       
   880 
       
   881 //
       
   882 // Implements the rounded corner drawing algorithm
       
   883 // Rounded corners are convex, nestable, symmetric, favour drawing in two pixel steps and favour filling outer pixels 
       
   884 // Corners are drawn from aStart, breaching a gap of size (aRoundedLength,aRoundedLength)
       
   885 // and use aUp and aRight to determine direction
       
   886 // Drawing is done vertically from the start and horizontaly from the end till they meet in the middle.
       
   887 //
       
   888 void TGulBorder::DrawRoundedCorner(CGraphicsContext& aGc,const TPoint& aStart,const TInt aRoundedLength, const TBool aUp, const TBool aRight) const
       
   889 	{
       
   890 	if(aRoundedLength<2)
       
   891 		return;
       
   892 
       
   893 	TPoint end=aStart;
       
   894 	end.iX += aRight ? aRoundedLength : -aRoundedLength;
       
   895 	end.iY += aUp ? -aRoundedLength : aRoundedLength;
       
   896 
       
   897 	// draw from start
       
   898 	aGc.MoveTo(aStart);
       
   899 	TInt steps=aRoundedLength/3;
       
   900 	TInt count=0;
       
   901 	while(count<steps)
       
   902 		{
       
   903 		aRight ? aGc.MoveBy(TPoint(1,0)) : aGc.MoveBy(TPoint(-1,0));
       
   904 		aUp ? aGc.MoveBy(TPoint(0,-1)) : aGc.MoveBy(TPoint(0,1));		
       
   905 		aUp ? aGc.DrawLineBy(TPoint(0,-2)) : aGc.DrawLineBy(TPoint(0,2));
       
   906 		aUp ? aGc.MoveBy(TPoint(0,1)) : aGc.MoveBy(TPoint(0,-1));
       
   907 		count++;
       
   908 		}
       
   909 
       
   910 	// draw from end
       
   911 	aGc.MoveTo(end);
       
   912 	count=0;
       
   913 	while(count<steps)
       
   914 		{
       
   915 		aUp ? aGc.MoveBy(TPoint(0,1)) : aGc.MoveBy(TPoint(0,-1));
       
   916 		aRight ? aGc.MoveBy(TPoint(-1,0)) : aGc.MoveBy(TPoint(1,0));
       
   917 		aRight ? aGc.DrawLineBy(TPoint(-2,0)) : aGc.DrawLineBy(TPoint(2,0));
       
   918 		aRight ? aGc.MoveBy(TPoint(1,0)) : aGc.MoveBy(TPoint(-1,0));
       
   919 		count++;
       
   920 		}
       
   921 	
       
   922 	// draw mid point if necessary
       
   923 	if(aRoundedLength%3==2)
       
   924 		{
       
   925 		aUp ? aGc.MoveBy(TPoint(0,1)) : aGc.MoveBy(TPoint(0,-1));
       
   926 		aRight ? aGc.MoveBy(TPoint(-1,0)) : aGc.MoveBy(TPoint(1,0));
       
   927 		aRight ? aGc.DrawLineBy(TPoint(-1,0)) : aGc.DrawLineBy(TPoint(1,0));
       
   928 		}
       
   929 	}
       
   930 
       
   931 //
       
   932 // Returns the thickness of the part of the border which is colored in the mid-tone
       
   933 // highlights and lowlights. In general, this is not the same as the size of the border
       
   934 // margins.
       
   935 EXPORT_C TInt TGulBorder::Thickness() const
       
   936 /**
       
   937 @publishedPartner
       
   938 @deprecated
       
   939 */
       
   940 	{
       
   941 	TInt thickness=0;
       
   942 
       
   943 	if (InternalType()&EAddOnePixel)
       
   944 		thickness++;
       
   945 
       
   946 	if (InternalType()&EAddTwoPixels)
       
   947 		thickness+=2;
       
   948 
       
   949 	if (InternalType()&EAddFourPixels)
       
   950 		thickness+=4;
       
   951 
       
   952 	return thickness;
       
   953 	}
       
   954 
       
   955 //
       
   956 // Returns the number of pixels which will be chipped of the corners of a border rectangle
       
   957 // to be joined by an rounding arc. The rounding is determined by the border type.
       
   958 //
       
   959 EXPORT_C TInt TGulBorder::Rounding() const
       
   960 /**
       
   961 @internalComponent
       
   962 @released
       
   963 */
       
   964 	{
       
   965 	TInt rounding=0;
       
   966 	
       
   967 	if (InternalType()&EAddOneRoundingPixel)
       
   968 		rounding++;
       
   969 
       
   970 	if (InternalType()&EAddTwoRoundingPixels)
       
   971 		rounding+=2;
       
   972 
       
   973 	if (InternalType()&EAddFourRoundingPixels)
       
   974 		rounding+=4;
       
   975 
       
   976 	return rounding;
       
   977 	}
       
   978 
       
   979 
       
   980 //
       
   981 // Returns the width of the smallest margin possible, given the rounding of the border rectangle.
       
   982 // This is a simple mapping for the rounding range 0-7 and the current drawing algorithm,
       
   983 //
       
   984 TInt TGulBorder::RoundingMargin(const TInt aRoundedLength) const
       
   985 	{
       
   986 	TInt roundingMargin=0;
       
   987 
       
   988 	if (aRoundedLength>4)
       
   989 		roundingMargin=2;
       
   990 	else if (aRoundedLength>1)
       
   991 		roundingMargin=1;
       
   992 
       
   993 	return roundingMargin;
       
   994 	}
       
   995 
       
   996 
       
   997 inline TInt TGulBorder::InternalType() const
       
   998 	{
       
   999 	return (iType>>KBorderShift);
       
  1000 	}
       
  1001 
       
  1002