--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/AvKon/src/AknBidiTextUtils.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,409 @@
+/*
+* Copyright (c) 2002 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: Text utilities e.g. truncating and wrapping to be used with
+* text that requires conversion from logical to visual form.
+* E.g. Arabic/Hebrew, Thai, Hindi. Logical text is given as input
+* to all methods. Output text is in visual form.
+*
+*/
+
+
+// INCLUDE FILES
+#include "AknBidiTextUtils.h"
+#include "aknenv.h"
+#include "AknUtils.h"
+#include "AknPanic.h"
+#include "AknTextWrapper.h"
+#include <e32std.h>
+#include <bidivisual.h>
+
+// CONSTANTS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndClipL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool AknBidiTextUtils::ConvertToVisualAndClipL(
+ TDes& aLogicalText,
+ const CFont& aFont,
+ TInt aMaxWidthInPixels,
+ TInt aMaxClippedWidthInPixels,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality,
+ TChar aClipChar )
+ {
+ HBufC* visualBuffer = HBufC::NewL(
+ aLogicalText.Length() + KAknBidiExtraSpacePerLine );
+ TPtr ptr = visualBuffer->Des();
+
+ TBool clipped = ConvertToVisualAndClip(
+ aLogicalText,
+ ptr,
+ aFont,
+ aMaxWidthInPixels,
+ aMaxClippedWidthInPixels,
+ aDirectionality,
+ aClipChar );
+
+ aLogicalText = *visualBuffer;
+ delete visualBuffer;
+ return clipped;
+ }
+
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndClip
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TBool AknBidiTextUtils::ConvertToVisualAndClip(
+ const TDesC& aLogicalText,
+ TDes& aVisualText,
+ const CFont& aFont,
+ TInt aMaxWidthInPixels,
+ TInt aMaxClippedWidthInPixels,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality,
+ TChar aClipChar )
+ {
+ TAknLocVariant variants[KAknMaxLocVariants];
+ TInt numVariants = TAknTextWrapper::GetLocVariants( aLogicalText, variants );
+
+ TBool clipped = ETrue;
+ TInt i = 0;
+
+ while ( i < numVariants && clipped )
+ {
+ TInt start = variants[i].iStart;
+ TInt length = variants[i].iEnd - start;
+
+ clipped = DoConvertToVisualAndClip(
+ aLogicalText.Mid( start, length ),
+ aVisualText,
+ aFont,
+ aMaxWidthInPixels,
+ aMaxClippedWidthInPixels,
+ aDirectionality,
+ aClipChar );
+
+ i++;
+ }
+
+ return clipped;
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::DoConvertToVisualAndClip
+// -----------------------------------------------------------------------------
+//
+TBool AknBidiTextUtils::DoConvertToVisualAndClip(
+ const TDesC& aLogicalText,
+ TDes& aVisualText,
+ const CFont& aFont,
+ TInt aMaxWidthInPixels,
+ TInt aMaxClippedWidthInPixels,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality,
+ TChar aClipChar )
+ {
+ /* TODO: Commented out temporarily.
+ __ASSERT_DEBUG( aVisualText.MaxLength() >=
+ aLogicalText.Length() + KAknBidiExtraSpacePerLine,
+ Panic( EAknPanicInvalidValue ) );
+ __ASSERT_DEBUG( aMaxWidthInPixels >= 0,
+ Panic( EAknPanicInvalidValue ) );
+ __ASSERT_DEBUG( aMaxClippedWidthInPixels >= 0,
+ Panic( EAknPanicInvalidValue ) );
+ */
+ TInt chars = aLogicalText.Length();
+
+ // TBidiLogicalToVisual crashes with length 0 text so we check that case here
+ if ( !chars )
+ {
+ aVisualText = KNullDesC; // null text
+ return EFalse;
+ }
+
+ TBool clipped = EFalse;
+ // Give 0xffff as parameter to TBidiLogicalToVisual if no clipping required.
+ TChar clipChar = 0xffff;
+
+ // TextCount() converts text to visual form and then checks it
+ if ( aFont.TextCount( aLogicalText, aMaxWidthInPixels ) < chars )
+ {
+ clipped = ETrue;
+
+ TInt clipCharWidth =
+ aClipChar == 0xffff ? 0 : aFont.CharWidthInPixels( aClipChar );
+
+ // Not enough space even for clip char alone - return empty descriptor.
+ if ( aMaxClippedWidthInPixels < clipCharWidth )
+ {
+ aVisualText.Zero();
+ return ETrue;
+ }
+
+ // Check how many characters fit in given space with truncation char.
+ // We need to give this information to TBidiLogicalToVisual.
+ chars = aFont.TextCount(
+ aLogicalText, aMaxClippedWidthInPixels - clipCharWidth );
+
+ // This is "avkon rule": should not insert ellipsis right after a space.
+ if ( chars > 1 &&
+ aLogicalText[chars - 1] == ' ' &&
+ aLogicalText[chars - 2] != ' ' )
+ {
+ chars--;
+ }
+
+ clipChar = aClipChar;
+ }
+
+ CAknEnv& env = *CAknEnv::Static();
+
+ // Ignore error - nothing we can do. If we are out of memory,
+ // this might cause incorrect text rendering in such lines,
+ // which require large run info array.
+ env.PrepareRunInfoArray( aLogicalText );
+
+ TInt count;
+ TBidirectionalState::TRunInfo* array = env.RunInfoArray( count );
+
+ TBidiLogicalToVisual converter =
+ aDirectionality == EImplicit ?
+ TBidiLogicalToVisual( aLogicalText, array, count ) :
+ TBidiLogicalToVisual( aLogicalText, aDirectionality == ERightToLeft, array, count );
+
+ converter.Reorder();
+ converter.GetVisualLine( aVisualText, 0, chars, clipChar );
+
+ return clipped;
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::PrepareRunInfoArray
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt AknBidiTextUtils::PrepareRunInfoArray( const TDesC& aLogicalText )
+ {
+ return CAknEnv::Static()->PrepareRunInfoArray( aLogicalText );
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndWrapToArrayL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
+ TDes& aStringToWrap,
+ const CArrayFix<TInt>& aLineWidthArray,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aWrappedArray,
+ TBool aInsertTruncationChar,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ // Ensure that there is the required free space in descriptor
+
+ __ASSERT_ALWAYS(
+ aStringToWrap.MaxLength() - aStringToWrap.Length() >=
+ aLineWidthArray.Count() * KAknBidiExtraSpacePerLine,
+ Panic( EAknPanicInvalidValue ) );
+
+ // Perform wrapping
+
+ TInt flags( TAknTextWrapper::EConvertToVisual );
+
+ if ( aInsertTruncationChar )
+ {
+ flags |= TAknTextWrapper::EClip;
+ }
+
+ TAknTextWrapper wrapper(
+ aStringToWrap,
+ &aLineWidthArray,
+ aFont,
+ aWrappedArray,
+ 0,
+ flags,
+ aDirectionality );
+
+ wrapper.WrapToArrayL();
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndWrapToArrayL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
+ const TDesC& aStringToWrap,
+ TInt aLineWidth,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aWrappedArray,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ TInt length = aStringToWrap.Length();
+ TPtr ptr( const_cast<TText*>( aStringToWrap.Ptr() ), length, length );
+
+ TAknTextWrapper wrapper(
+ ptr,
+ NULL,
+ aFont,
+ aWrappedArray,
+ aLineWidth,
+ TAknTextWrapper::EReserveVisualBuffer |
+ TAknTextWrapper::EConvertToVisual,
+ aDirectionality );
+
+ return wrapper.WrapToArrayL();
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndChopToArrayL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void AknBidiTextUtils::ConvertToVisualAndChopToArrayL(
+ TDes& aStringToChop,
+ const CArrayFix<TInt>& aLineWidthArray,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aChoppedArray,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ // Ensure that there is the required free space in descriptor
+
+ __ASSERT_ALWAYS(
+ aStringToChop.MaxLength() - aStringToChop.Length() >=
+ aLineWidthArray.Count() * KAknBidiExtraSpacePerLine,
+ Panic( EAknPanicInvalidValue ) );
+
+ // Perform chopping
+
+ TAknTextWrapper wrapper(
+ aStringToChop,
+ &aLineWidthArray,
+ aFont,
+ aChoppedArray,
+ 0,
+ TAknTextWrapper::EClip | TAknTextWrapper::EConvertToVisual,
+ aDirectionality );
+
+ wrapper.ChopToArrayAndClipL();
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndChopToArrayL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndChopToArrayL(
+ const TDesC& aStringToChop,
+ TInt aLineWidth,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aChoppedArray,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ TInt length = aStringToChop.Length();
+ TPtr ptr( const_cast<TText*>( aStringToChop.Ptr() ), length, length );
+
+ TAknTextWrapper wrapper(
+ ptr,
+ NULL,
+ aFont,
+ aChoppedArray,
+ aLineWidth,
+ TAknTextWrapper::EReserveVisualBuffer |
+ TAknTextWrapper::EConvertToVisual,
+ aDirectionality );
+
+ return wrapper.ChopToArrayAndClipL();
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndWrapToStringL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void AknBidiTextUtils::ConvertToVisualAndWrapToStringL(
+ const TDesC& aStringToWrap,
+ const CArrayFix<TInt>& aLineWidthArray,
+ const CFont& aFont,
+ TDes& aWrappedString,
+ TBool aInsertTruncationChar,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ // Ensure that there is the required free space in descriptor
+
+ __ASSERT_ALWAYS(
+ aWrappedString.MaxLength() - aStringToWrap.Length() >=
+ aLineWidthArray.Count() * (KAknBidiExtraSpacePerLine + 1),
+ Panic( EAknPanicInvalidValue ) );
+
+ // Perform wrapping
+
+ TInt flags( TAknTextWrapper::EConvertToVisual );
+
+ if ( aInsertTruncationChar )
+ {
+ flags |= TAknTextWrapper::EClip;
+ }
+
+ AknTextUtils::WrapToStringL(
+ aStringToWrap,
+ aLineWidthArray,
+ aFont,
+ aWrappedString,
+ flags,
+ aDirectionality );
+ }
+
+// -----------------------------------------------------------------------------
+// AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL(
+ const TDesC& aLogicalText,
+ const CArrayFix<TInt>& aLineWidthArray,
+ const CFont& aFont,
+ CArrayFix<TPtrC>& aWrappedArray,
+ AknBidiTextUtils::TParagraphDirectionality aDirectionality )
+ {
+ __ASSERT_DEBUG( aLineWidthArray.Count(), Panic( EAknPanicInvalidValue ) );
+
+ TInt length = aLogicalText.Length();
+ TPtr ptr( const_cast<TText*>( aLogicalText.Ptr() ), length, length );
+
+ TAknTextWrapper wrapper(
+ ptr,
+ &aLineWidthArray,
+ aFont,
+ aWrappedArray,
+ 0,
+ TAknTextWrapper::EReserveVisualBuffer |
+ TAknTextWrapper::EWrapAllText |
+ TAknTextWrapper::EConvertToVisual,
+ aDirectionality );
+
+ return wrapper.WrapToArrayL();
+ }
+
+EXPORT_C TInt AknBidiTextUtils::MeasureTextBoundsWidth(
+ const CFont& aFont,
+ const TDesC& aText,
+ CFont::TMeasureTextInput::TFlags aOrder)
+ {
+ TInt textAdvance;
+ CFont::TMeasureTextInput input;
+ input.iFlags = aOrder;
+ CFont::TMeasureTextOutput output;
+ textAdvance = aFont.MeasureText( aText, &input, &output );
+ TRect bounds = output.iBounds;
+ bounds.iTl.iX = Min(bounds.iTl.iX, 0);
+ bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance);
+ return bounds.Width();
+ }
+// End of File