--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknPhoneNumberTextUtils.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* This utility class allows the client to wrap phone numbers (previously
+* number grouped) on to lines of display. A facility to measure text from the
+* end is provided for simple cases.
+*
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32std.h>
+
+#include "AknPhoneNumberTextUtils.h"
+#include "AknUtils.h"
+#include "AknPanic.h"
+
+// CONSTANTS
+
+const TInt KLineArrayGranularity(2);
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+void ReverseDescriptor( TDes& aPtr )
+ {
+ TInt count = aPtr.Length();
+ TInt halfCount = count/2; // rounded down
+ TInt target(count-1);
+ for ( TInt index = 0; index < halfCount; index++, target-- )
+ {
+ TText temp = aPtr[target];
+ aPtr[target] = aPtr[index];
+ aPtr[index] = temp;
+ }
+ }
+
+EXPORT_C TBool AknPhoneNumberTextUtils::WrapPhoneNumberToArrayL(
+ const TDesC& aPhoneNumberToWrap,
+ TInt aLineWidthInPixels,
+ TInt aMaxLines,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aWrappedArray )
+ {
+ TBool retVal( EFalse ); // Not truncated
+
+ HBufC* reversedText = aPhoneNumberToWrap.AllocLC();
+ TPtr revPtr = reversedText->Des();
+
+ ReverseDescriptor( revPtr );
+
+ CArrayFix<TInt>* lineWidthArray = new (ELeave) CArrayFixFlat<TInt>(KLineArrayGranularity);
+ CleanupStack::PushL( lineWidthArray );
+
+ lineWidthArray->AppendL( aLineWidthInPixels, aMaxLines );
+
+ // Perform the wrap on the reversed text
+ AknTextUtils::WrapToArrayL( revPtr, *lineWidthArray, aFont, aWrappedArray );
+
+ // Now rearrange the TPtrCs to point to the original array
+ TInt totalLen = reversedText->Length();
+ TInt count = aWrappedArray.Count();
+ TInt usedLen = 0; // Accumulates the length actually used
+ for ( TInt index = 0; index < count; index++)
+ {
+ TPtrC& currentPtr = aWrappedArray.At(index);
+ // The TPtrCs have to be moved. The reversing is taken into effect, but not purely reversed
+ // because their otherwise they would have negative lengths. That is, {a,b} does not go to
+ // { final - a, final - b }, but rather to {final - b, final - a}; they are flipped, to get
+ // their start points before the end points
+ //
+ // Now, representing the start position by pos, and the end by pos+len-1 we have the TPtrC at
+ // {pos, pos+len-1} inclusive, in reversed array.
+ // The TPtrC must be modified to point to {total_len-1 - (pos+len-1), total_len-1 - pos}
+ // in the unreversed array:
+ TInt len = currentPtr.Length();
+ usedLen += len;
+ TInt pos = currentPtr.Ptr() - reversedText->Ptr(); // pointer arithmetic
+ TInt newPos = totalLen - pos - len;
+ // If the TPtr is zero length then it must get special treatment, as the normal
+ // calculations give an end point before the start point! i.e. {pos, pos-1}
+ // We handle this by NOT flipping in this case.
+ // { pos, pos-1 } -> {totalLen-1-pos, totalLen-1 - (pos-1)}
+ // Note that a zero length wrapped line is completely possible amoung a bunch of other
+ // lines with characters on them, as the line lengths may be of wildly different lengths.
+ if ( len == 0 )
+ newPos--;
+ currentPtr.Set( aPhoneNumberToWrap.Mid(newPos, len) );
+ }
+
+ // If the accumulated length is less than that in the entire input descriptor, then text does not fit
+ if ( usedLen < totalLen )
+ retVal = ETrue;
+
+ CleanupStack::PopAndDestroy(2); // lineWidthArray first, and then reversedText
+ return retVal;
+ }
+
+EXPORT_C void AknPhoneNumberTextUtils::ClipLineOnLeft(
+ TPtrC& aLine, TDes& aOriginalBuffer, TInt aWidth, const CFont& aFont )
+ {
+ // Main work of this routine is to make a TPtr of the input TPtrC, then we can clip using existing
+ // utils.
+
+ // But first check if the line points to the provided modifiable buffer
+ TText* linePtr = (TText*)aLine.Ptr();
+ TInt lineLen = aLine.Length();
+ TText* pastEndOfLine = linePtr + lineLen; // pointer arithmetic
+
+ TText* modBufPtr = (TText*)aOriginalBuffer.Ptr();
+ TInt len = aOriginalBuffer.Length(); // length actually with text in it (not maxlength)
+ TText* pastEndOfModBufPtr = modBufPtr + len; // pointer arithmetic
+
+ // This Panics if the input aLine is not encompassed within the modifiable buffer ->Programmer error
+ __ASSERT_ALWAYS( (modBufPtr <= linePtr && pastEndOfLine <= pastEndOfModBufPtr ), Panic( EAknPanicInconsistentDescriptors ) );
+
+ // Set the TPtr now to extend from the start of the original buffer to the end of the input aLine
+ TInt enlargedLength = (pastEndOfLine - modBufPtr);// Pointer arithmetic;
+ TPtr ptr( modBufPtr, enlargedLength, enlargedLength );
+
+ // Should have a safe modifiable buffer now.
+ AknTextUtils::ClipToFit( ptr, aFont, aWidth, AknTextUtils::EClipFromBeginning );
+ aLine.Set( ptr );
+ }
+
+EXPORT_C TInt AknPhoneNumberTextUtils::CharsThatFitOnRight(
+ const TDesC& aText,
+ TInt aLineWidth,
+ const CFont& aFont )
+ {
+ // Current candidate text for fitting text
+ TPtrC currentText(aText);
+
+ // These two variables are converged by this algorithm until they differ by one
+ // Set max chars to be total length + 1, for the sake of the algorithm
+ TInt minCharsFromRightThatDoNotFit( aText.Length() + 1 );
+ TInt maxCharsFromRightThatFit(0); // must start at 0
+
+ // some incidentally used lengths
+ TInt currentLength(0); // arbitrary init value
+ TInt charsThatFitOnLeft(0); // arbitrary init value
+ TInt newLength(0); // arbitrary init value
+
+ while ( (minCharsFromRightThatDoNotFit - maxCharsFromRightThatFit) != 1 )
+ {
+ // At the top of the loop, all state is held by currentText itself, and the two
+ // maxCharsXXX variables.
+ currentLength = currentText.Length();
+ charsThatFitOnLeft = aFont.TextCount( currentText, aLineWidth);
+
+ if ( charsThatFitOnLeft == currentLength ) // Does this text fit ?
+ {
+ maxCharsFromRightThatFit = Max( maxCharsFromRightThatFit, charsThatFitOnLeft );
+
+ // If this text cannot be made any bigger, and still fit, then bail out
+ if ( (maxCharsFromRightThatFit + 1) >= minCharsFromRightThatDoNotFit )
+ {
+ // We can exit the loop now. Just fall out and the while test will handle it.
+ break;
+ }
+ else // if this string did fit, and it might have been too small, try making it bigger
+ {
+ // we know this is still be < minCharsFromRightThatDoNotFit
+ newLength = maxCharsFromRightThatFit + 1;
+ }
+ }
+ else // currentText does not fit. Repeat loop
+ {
+ // we know that this many characters did not fit on the line
+ minCharsFromRightThatDoNotFit = Min( minCharsFromRightThatDoNotFit, currentLength );
+
+ // Try using the number that fit on the left as the number we will fit on the right.
+ newLength = charsThatFitOnLeft;
+ }
+
+ currentText.Set(aText.Right(newLength));
+ }
+
+ return maxCharsFromRightThatFit;
+ }
+
+// End of File