uifw/AvKon/src/AknBidiTextUtils.cpp
changeset 0 2f259fa3e83a
--- /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