uifw/AvKon/src/AknBidiTextUtils.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Text utilities e.g. truncating and wrapping to be used with
       
    15 *                text that requires conversion from logical to visual form.
       
    16 *                E.g. Arabic/Hebrew, Thai, Hindi. Logical text is given as input
       
    17 *                to all methods. Output text is in visual form.
       
    18 *
       
    19 */
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include "AknBidiTextUtils.h"
       
    24 #include "aknenv.h"
       
    25 #include "AknUtils.h"
       
    26 #include "AknPanic.h"
       
    27 #include "AknTextWrapper.h"
       
    28 #include <e32std.h>
       
    29 #include <bidivisual.h>
       
    30 
       
    31 // CONSTANTS
       
    32 
       
    33 // ============================ MEMBER FUNCTIONS ===============================
       
    34 
       
    35 // -----------------------------------------------------------------------------
       
    36 // AknBidiTextUtils::ConvertToVisualAndClipL
       
    37 // -----------------------------------------------------------------------------
       
    38 //
       
    39 EXPORT_C TBool AknBidiTextUtils::ConvertToVisualAndClipL(
       
    40     TDes& aLogicalText,
       
    41     const CFont& aFont,
       
    42     TInt aMaxWidthInPixels,
       
    43     TInt aMaxClippedWidthInPixels,
       
    44     AknBidiTextUtils::TParagraphDirectionality aDirectionality,
       
    45     TChar aClipChar )
       
    46     {
       
    47     HBufC* visualBuffer = HBufC::NewL(
       
    48         aLogicalText.Length() + KAknBidiExtraSpacePerLine );
       
    49     TPtr ptr = visualBuffer->Des();
       
    50 
       
    51     TBool clipped = ConvertToVisualAndClip(
       
    52         aLogicalText,
       
    53         ptr,
       
    54         aFont,
       
    55         aMaxWidthInPixels,
       
    56         aMaxClippedWidthInPixels,
       
    57         aDirectionality,
       
    58         aClipChar );
       
    59 
       
    60     aLogicalText = *visualBuffer;
       
    61     delete visualBuffer;
       
    62     return clipped;
       
    63     }
       
    64 
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // AknBidiTextUtils::ConvertToVisualAndClip
       
    68 // -----------------------------------------------------------------------------
       
    69 //
       
    70 EXPORT_C TBool AknBidiTextUtils::ConvertToVisualAndClip(
       
    71     const TDesC& aLogicalText,
       
    72     TDes& aVisualText,
       
    73     const CFont& aFont,
       
    74     TInt aMaxWidthInPixels,
       
    75     TInt aMaxClippedWidthInPixels,
       
    76     AknBidiTextUtils::TParagraphDirectionality aDirectionality,
       
    77     TChar aClipChar )
       
    78     {
       
    79     TAknLocVariant variants[KAknMaxLocVariants];
       
    80     TInt numVariants = TAknTextWrapper::GetLocVariants( aLogicalText, variants );
       
    81 
       
    82     TBool clipped = ETrue;
       
    83     TInt i = 0;
       
    84 
       
    85     while ( i < numVariants && clipped )
       
    86         {
       
    87         TInt start = variants[i].iStart;
       
    88         TInt length = variants[i].iEnd - start;
       
    89         
       
    90         clipped = DoConvertToVisualAndClip(
       
    91             aLogicalText.Mid( start, length ),
       
    92             aVisualText,
       
    93             aFont,
       
    94             aMaxWidthInPixels,
       
    95             aMaxClippedWidthInPixels,
       
    96             aDirectionality,
       
    97             aClipChar );
       
    98 
       
    99         i++;
       
   100         }
       
   101 
       
   102     return clipped;
       
   103     }
       
   104 
       
   105 // -----------------------------------------------------------------------------
       
   106 // AknBidiTextUtils::DoConvertToVisualAndClip
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 TBool AknBidiTextUtils::DoConvertToVisualAndClip(
       
   110     const TDesC& aLogicalText,
       
   111     TDes& aVisualText,
       
   112     const CFont& aFont,
       
   113     TInt aMaxWidthInPixels,
       
   114     TInt aMaxClippedWidthInPixels,
       
   115     AknBidiTextUtils::TParagraphDirectionality aDirectionality,
       
   116     TChar aClipChar )
       
   117     {
       
   118     /* TODO: Commented out temporarily.
       
   119     __ASSERT_DEBUG( aVisualText.MaxLength() >= 
       
   120         aLogicalText.Length() + KAknBidiExtraSpacePerLine,
       
   121         Panic( EAknPanicInvalidValue ) );
       
   122     __ASSERT_DEBUG( aMaxWidthInPixels >= 0, 
       
   123         Panic( EAknPanicInvalidValue ) );
       
   124     __ASSERT_DEBUG( aMaxClippedWidthInPixels >= 0,
       
   125         Panic( EAknPanicInvalidValue ) );
       
   126     */
       
   127     TInt chars = aLogicalText.Length();
       
   128 
       
   129     // TBidiLogicalToVisual crashes with length 0 text so we check that case here
       
   130     if ( !chars )
       
   131         {
       
   132         aVisualText = KNullDesC; // null text 
       
   133         return EFalse;
       
   134         }
       
   135 
       
   136     TBool clipped = EFalse;
       
   137     // Give 0xffff as parameter to TBidiLogicalToVisual if no clipping required.
       
   138     TChar clipChar = 0xffff;
       
   139 
       
   140     // TextCount() converts text to visual form and then checks it
       
   141     if ( aFont.TextCount( aLogicalText, aMaxWidthInPixels ) < chars )
       
   142         {
       
   143         clipped = ETrue;
       
   144 
       
   145         TInt clipCharWidth = 
       
   146             aClipChar == 0xffff ? 0 : aFont.CharWidthInPixels( aClipChar );
       
   147 
       
   148         // Not enough space even for clip char alone - return empty descriptor.
       
   149         if ( aMaxClippedWidthInPixels < clipCharWidth )
       
   150             {
       
   151             aVisualText.Zero();
       
   152             return ETrue;
       
   153             }
       
   154 
       
   155         // Check how many characters fit in given space with truncation char.
       
   156         // We need to give this information to TBidiLogicalToVisual.
       
   157         chars = aFont.TextCount( 
       
   158             aLogicalText, aMaxClippedWidthInPixels - clipCharWidth );
       
   159 
       
   160         // This is "avkon rule": should not insert ellipsis right after a space.
       
   161         if ( chars > 1 && 
       
   162              aLogicalText[chars - 1] == ' ' &&
       
   163              aLogicalText[chars - 2] != ' ' )
       
   164             {
       
   165             chars--;
       
   166             }
       
   167 
       
   168         clipChar = aClipChar;
       
   169         }
       
   170         
       
   171     CAknEnv& env = *CAknEnv::Static();
       
   172 
       
   173     // Ignore error - nothing we can do. If we are out of memory,
       
   174     // this might cause incorrect text rendering in such lines,
       
   175     // which require large run info array.
       
   176     env.PrepareRunInfoArray( aLogicalText );
       
   177 
       
   178     TInt count;
       
   179     TBidirectionalState::TRunInfo* array = env.RunInfoArray( count );
       
   180 
       
   181     TBidiLogicalToVisual converter =
       
   182         aDirectionality == EImplicit ? 
       
   183         TBidiLogicalToVisual( aLogicalText, array, count ) :
       
   184         TBidiLogicalToVisual( aLogicalText, aDirectionality == ERightToLeft, array, count );
       
   185 
       
   186     converter.Reorder();
       
   187     converter.GetVisualLine( aVisualText, 0, chars, clipChar );
       
   188 
       
   189     return clipped;
       
   190     }
       
   191 
       
   192 // -----------------------------------------------------------------------------
       
   193 // AknBidiTextUtils::PrepareRunInfoArray
       
   194 // -----------------------------------------------------------------------------
       
   195 //
       
   196 EXPORT_C TInt AknBidiTextUtils::PrepareRunInfoArray( const TDesC& aLogicalText )
       
   197     {
       
   198     return CAknEnv::Static()->PrepareRunInfoArray( aLogicalText );
       
   199     }
       
   200 
       
   201 // -----------------------------------------------------------------------------
       
   202 // AknBidiTextUtils::ConvertToVisualAndWrapToArrayL
       
   203 // -----------------------------------------------------------------------------
       
   204 //
       
   205 EXPORT_C void AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
       
   206     TDes& aStringToWrap,
       
   207     const CArrayFix<TInt>& aLineWidthArray,
       
   208     const CFont& aFont,
       
   209     CArrayFix<TPtrC>& aWrappedArray,
       
   210     TBool aInsertTruncationChar,
       
   211     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   212     {
       
   213     // Ensure that there is the required free space in descriptor
       
   214 
       
   215     __ASSERT_ALWAYS( 
       
   216         aStringToWrap.MaxLength() - aStringToWrap.Length() >=
       
   217         aLineWidthArray.Count() * KAknBidiExtraSpacePerLine,
       
   218         Panic( EAknPanicInvalidValue ) );
       
   219 
       
   220     // Perform wrapping
       
   221 
       
   222     TInt flags( TAknTextWrapper::EConvertToVisual );
       
   223 
       
   224     if ( aInsertTruncationChar )
       
   225         {
       
   226         flags |= TAknTextWrapper::EClip;
       
   227         }
       
   228 
       
   229     TAknTextWrapper wrapper(
       
   230         aStringToWrap,
       
   231         &aLineWidthArray,
       
   232         aFont,
       
   233         aWrappedArray,
       
   234         0,
       
   235         flags,
       
   236         aDirectionality );
       
   237 
       
   238     wrapper.WrapToArrayL();
       
   239     }
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // AknBidiTextUtils::ConvertToVisualAndWrapToArrayL
       
   243 // -----------------------------------------------------------------------------
       
   244 //
       
   245 EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
       
   246     const TDesC& aStringToWrap,
       
   247     TInt aLineWidth,
       
   248     const CFont& aFont,
       
   249     CArrayFix<TPtrC>& aWrappedArray,
       
   250     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   251     {
       
   252     TInt length = aStringToWrap.Length();
       
   253     TPtr ptr( const_cast<TText*>( aStringToWrap.Ptr() ), length, length );
       
   254 
       
   255     TAknTextWrapper wrapper(
       
   256         ptr,
       
   257         NULL,
       
   258         aFont,
       
   259         aWrappedArray,
       
   260         aLineWidth,
       
   261         TAknTextWrapper::EReserveVisualBuffer |
       
   262         TAknTextWrapper::EConvertToVisual,
       
   263         aDirectionality );
       
   264 
       
   265     return wrapper.WrapToArrayL();
       
   266     }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // AknBidiTextUtils::ConvertToVisualAndChopToArrayL
       
   270 // -----------------------------------------------------------------------------
       
   271 //
       
   272 EXPORT_C void AknBidiTextUtils::ConvertToVisualAndChopToArrayL(
       
   273     TDes& aStringToChop,             
       
   274     const CArrayFix<TInt>& aLineWidthArray, 
       
   275     const CFont& aFont,                    
       
   276     CArrayFix<TPtrC>& aChoppedArray,
       
   277     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   278     {
       
   279     // Ensure that there is the required free space in descriptor
       
   280 
       
   281     __ASSERT_ALWAYS( 
       
   282         aStringToChop.MaxLength() - aStringToChop.Length() >=
       
   283         aLineWidthArray.Count() * KAknBidiExtraSpacePerLine,
       
   284         Panic( EAknPanicInvalidValue ) );
       
   285 
       
   286     // Perform chopping
       
   287 
       
   288     TAknTextWrapper wrapper(
       
   289         aStringToChop,
       
   290         &aLineWidthArray,
       
   291         aFont,
       
   292         aChoppedArray,
       
   293         0,
       
   294         TAknTextWrapper::EClip | TAknTextWrapper::EConvertToVisual,
       
   295         aDirectionality );
       
   296 
       
   297     wrapper.ChopToArrayAndClipL();
       
   298     }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // AknBidiTextUtils::ConvertToVisualAndChopToArrayL
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndChopToArrayL(
       
   305     const TDesC& aStringToChop,
       
   306     TInt aLineWidth,
       
   307     const CFont& aFont,
       
   308     CArrayFix<TPtrC>& aChoppedArray,
       
   309     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   310     {
       
   311     TInt length = aStringToChop.Length();
       
   312     TPtr ptr( const_cast<TText*>( aStringToChop.Ptr() ), length, length );
       
   313 
       
   314     TAknTextWrapper wrapper(
       
   315         ptr,
       
   316         NULL,
       
   317         aFont,
       
   318         aChoppedArray,
       
   319         aLineWidth,
       
   320         TAknTextWrapper::EReserveVisualBuffer | 
       
   321         TAknTextWrapper::EConvertToVisual,
       
   322         aDirectionality );
       
   323 
       
   324     return wrapper.ChopToArrayAndClipL();
       
   325     }
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // AknBidiTextUtils::ConvertToVisualAndWrapToStringL
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 EXPORT_C void AknBidiTextUtils::ConvertToVisualAndWrapToStringL(
       
   332     const TDesC& aStringToWrap,
       
   333     const CArrayFix<TInt>& aLineWidthArray,
       
   334     const CFont& aFont,
       
   335     TDes& aWrappedString,
       
   336     TBool aInsertTruncationChar,
       
   337     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   338     {
       
   339     // Ensure that there is the required free space in descriptor
       
   340 
       
   341     __ASSERT_ALWAYS( 
       
   342         aWrappedString.MaxLength() - aStringToWrap.Length() >=
       
   343         aLineWidthArray.Count() * (KAknBidiExtraSpacePerLine + 1),
       
   344         Panic( EAknPanicInvalidValue ) );
       
   345 
       
   346     // Perform wrapping
       
   347 
       
   348     TInt flags( TAknTextWrapper::EConvertToVisual );
       
   349 
       
   350     if ( aInsertTruncationChar )
       
   351         {
       
   352         flags |= TAknTextWrapper::EClip;
       
   353         }
       
   354 
       
   355     AknTextUtils::WrapToStringL(
       
   356         aStringToWrap,
       
   357         aLineWidthArray, 
       
   358         aFont, 
       
   359         aWrappedString,
       
   360         flags,
       
   361         aDirectionality );
       
   362     }
       
   363 
       
   364 // -----------------------------------------------------------------------------
       
   365 // AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 EXPORT_C HBufC* AknBidiTextUtils::ConvertToVisualAndWrapToArrayWholeTextL( 
       
   369     const TDesC& aLogicalText,
       
   370     const CArrayFix<TInt>& aLineWidthArray,
       
   371     const CFont& aFont,
       
   372     CArrayFix<TPtrC>& aWrappedArray,
       
   373     AknBidiTextUtils::TParagraphDirectionality aDirectionality )
       
   374     {
       
   375     __ASSERT_DEBUG( aLineWidthArray.Count(), Panic( EAknPanicInvalidValue ) );
       
   376 
       
   377     TInt length = aLogicalText.Length();
       
   378     TPtr ptr( const_cast<TText*>( aLogicalText.Ptr() ), length, length );
       
   379 
       
   380     TAknTextWrapper wrapper(
       
   381         ptr,
       
   382         &aLineWidthArray,
       
   383         aFont,
       
   384         aWrappedArray,
       
   385         0,
       
   386         TAknTextWrapper::EReserveVisualBuffer |
       
   387         TAknTextWrapper::EWrapAllText |
       
   388         TAknTextWrapper::EConvertToVisual,
       
   389         aDirectionality );
       
   390 
       
   391     return wrapper.WrapToArrayL();
       
   392     }
       
   393 
       
   394 EXPORT_C TInt AknBidiTextUtils::MeasureTextBoundsWidth(
       
   395     const CFont& aFont,
       
   396     const TDesC& aText,
       
   397     CFont::TMeasureTextInput::TFlags aOrder)
       
   398     {
       
   399     TInt textAdvance;
       
   400     CFont::TMeasureTextInput input; 
       
   401     input.iFlags = aOrder;
       
   402     CFont::TMeasureTextOutput output; 
       
   403     textAdvance = aFont.MeasureText( aText, &input, &output );
       
   404 	TRect bounds = output.iBounds;
       
   405 	bounds.iTl.iX = Min(bounds.iTl.iX, 0);
       
   406 	bounds.iBr.iX = Max(bounds.iBr.iX, textAdvance);    
       
   407     return bounds.Width();
       
   408     }
       
   409 //  End of File