--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fep/aknfep/src/AknFepInlineTextDecorator.cpp Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,229 @@
+/*
+* 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:
+*
+*/
+
+
+
+
+
+
+
+
+
+
+
+
+// CAknFepInlineTextDecorator class
+//
+#include <aknenv.h>
+
+#include "AknFepInlineTextDecorator.h"
+#include "AknFepManager.h"
+
+#ifdef _DEBUG
+#include "AknFepPanic.h"
+#endif
+
+void CAknFepInlineTextDecorator::DecorateInlineText(
+ const TDesC& aInlineText,
+ TDes& aDecoratedText,
+ TInt& aPositionOfInsertionPointInInlineText,
+ TChar aPreviousCharacter,
+ TBool aRTLParagraph,
+ TBool aInputDirectionIsRTL)
+ {
+ DecorateNeutralCharacters(aInlineText, aDecoratedText, aPositionOfInsertionPointInInlineText,
+ aPreviousCharacter, aRTLParagraph, aInputDirectionIsRTL);
+ }
+
+/**
+* This routine performs a consolidation of directional markers in the region around text being committed.
+* It returns EFalse if no change has been made to the buffer.
+*/
+TBool CAknFepInlineTextDecorator::ResolveDecoratedText(
+ TDes& aDecoratedTextPlusSurroundings,
+ TCursorSelection aDecoratedTextSpan)
+ {
+ TBool needsResolving(EFalse); // Return value
+
+ // Note that this is a copy of a part of the buffer and that aNewTextSpan is relative to this
+ // new buffer, not the whole text buffer.
+ // aNewTextSpan must fit within the descriptor; that is from 0 to length-1
+ // But remember that span is a span; indices refer to positions between characters. 0 is position just before 0
+ // 1 is a position between 0 and character 1.
+ __ASSERT_DEBUG(aDecoratedTextSpan.LowerPos() >= 0,
+ AknFepPanic(EAknFepPanicCharPosOutOfRange) );
+ __ASSERT_DEBUG(aDecoratedTextSpan.HigherPos() <= aDecoratedTextPlusSurroundings.Length(),
+ AknFepPanic(EAknFepPanicCharPosOutOfRange) );
+
+ // Examine the decorated text for real content
+ TBool cont = EFalse;
+ TInt ii = 0;
+ for (ii = aDecoratedTextSpan.LowerPos(); ii < aDecoratedTextSpan.HigherPos(); ii++)
+ {
+ if (!CharacterIsDirectionalMarker(aDecoratedTextPlusSurroundings[ii]))
+ cont = ETrue;
+ }
+ // if all we have entered are directional markers we want
+ // to keep them so do nothing and return
+ if (!cont)
+ return needsResolving; // Uses initialized value of return value. Please maintain.
+
+ ii = 0;
+ while (ii < aDecoratedTextPlusSurroundings.Length())
+ {
+ TChar prevCh = ENullChar;
+ if (ii > 0)
+ prevCh = aDecoratedTextPlusSurroundings[ii-1];
+ TChar ch = aDecoratedTextPlusSurroundings[ii];
+ TChar nextCh = ENullChar;
+ if (ii < aDecoratedTextPlusSurroundings.Length()-1)
+ nextCh = aDecoratedTextPlusSurroundings[ii+1];
+
+ if (CharacterIsDirectionalMarker(ch))
+ {
+ // Remove a marker if :
+ //
+ // 1. previous character is strong and has the same directionality
+ // 2. next character is a marker of the same type (remove both)
+ // 3. next character is strong and has the same directionality
+ //
+ if (CharactersHaveSameStrongDirection(ch, prevCh))
+ {
+ aDecoratedTextPlusSurroundings.Delete(ii, ESingleCharacter);
+ ii--;
+ needsResolving = ETrue;
+ }
+ else if (CharacterIsDirectionalMarker(nextCh) && CharactersHaveSameStrongDirection(ch, nextCh))
+ {
+ aDecoratedTextPlusSurroundings.Delete(ii, ETwoCharacters);
+ ii--;
+ needsResolving = ETrue;
+ }
+ else if (CharactersHaveSameStrongDirection(ch, nextCh))
+ {
+ aDecoratedTextPlusSurroundings.Delete(ii, ESingleCharacter);
+ ii--;
+ needsResolving = ETrue;
+ }
+ }
+ ii++;
+ }
+ return needsResolving;
+ }
+
+
+TBool CAknFepInlineTextDecorator::CharacterIsDirectionalMarker(TChar aChar)
+ {
+ return (aChar == ELeftToRightMark || aChar == ERightToLeftMark);
+ }
+
+TBool CAknFepInlineTextDecorator::CharacterIsStrongLeftToRight(TChar aChar)
+ {
+ return (aChar.GetBdCategory() == TChar::ELeftToRight ||
+ aChar == ELeftToRightMark);
+ }
+
+TBool CAknFepInlineTextDecorator::CharacterIsStrongRightToLeft(TChar aChar)
+ {
+ return ((aChar.GetBdCategory() == TChar::ERightToLeft) ||
+ (aChar.GetBdCategory() == TChar::ERightToLeftArabic) ||
+ aChar == ERightToLeftMark);
+ }
+
+TBool CAknFepInlineTextDecorator::CharactersHaveSameStrongDirection(TChar aCh1, TChar aCh2)
+ {
+ return ((CharacterIsStrongLeftToRight(aCh1) && CharacterIsStrongLeftToRight(aCh2)) ||
+ (CharacterIsStrongRightToLeft(aCh1) && CharacterIsStrongRightToLeft(aCh2)));
+ }
+
+TBool CAknFepInlineTextDecorator::CharacterIsWeaklyDirectional(TChar aChar)
+ {
+ return ((aChar.GetBdCategory() == TChar::EEuropeanNumber) ||
+ (aChar.GetBdCategory() == TChar::EEuropeanNumberSeparator) ||
+ (aChar.GetBdCategory() == TChar::EEuropeanNumberTerminator) ||
+ (aChar.GetBdCategory() == TChar::EArabicNumber) ||
+ (aChar.GetBdCategory() == TChar::ECommonNumberSeparator));
+ }
+
+TBool CAknFepInlineTextDecorator::CharacterIsSeparator(TChar aChar)
+ {
+ return ((aChar.GetBdCategory() == TChar::EParagraphSeparator) ||
+ (aChar.GetBdCategory() == TChar::ESegmentSeparator));
+ }
+
+TBool CAknFepInlineTextDecorator::CharacterIsNeutral(TChar aChar)
+ {
+ return ((aChar.GetBdCategory() == TChar::EWhitespace) ||
+ (aChar.GetBdCategory() == TChar::EOtherNeutral));
+ }
+
+void CAknFepInlineTextDecorator::DecorateNeutralCharacters(
+ const TDesC& aInlineText,
+ TDes& aDecoratedText,
+ TInt& aPositionOfInsertionPointInInlineText,
+ TChar aPreviousCharacter,
+ TBool aRTLParagraph,
+ TBool aInputDirectionIsRTL)
+ {
+
+ TChar curCh;
+ TChar prevCh = aPreviousCharacter;
+ TBuf<ESingleCharacter> insertBuf(ESingleCharacter);
+
+ for (TInt ii = 0; ii < aInlineText.Length(); ii++)
+ {
+ curCh = aInlineText[ii];
+ aDecoratedText.Append(curCh);
+
+ if (CharacterIsNeutral(curCh))
+ {
+ // mark the neutral character with appropriate direction markers if :
+ //
+ // 1. the input mode (lang) is opposed to the paragraph direction and
+ // previous character is not neutral
+ // 2. the input mode (lang) is opposed to the previous char direction
+ // (=> charcater is entered inside existing block)
+ //
+ // Note that we need to increment the insertion point by 2 if the
+ // markers are inserted before it
+ //
+ if ((aInputDirectionIsRTL && !aRTLParagraph && !CharacterIsNeutral(prevCh)) ||
+ (aInputDirectionIsRTL && CharacterIsStrongLeftToRight(prevCh)))
+ { // mark neutral with RLM
+ insertBuf[0]=ERightToLeftMark;
+ aDecoratedText.Insert(aDecoratedText.Length() -1, insertBuf);
+ aDecoratedText.Append(insertBuf);
+
+ if (aPositionOfInsertionPointInInlineText > ii)
+ aPositionOfInsertionPointInInlineText+=ETwoCharacters;
+ }
+
+ else if ((!aInputDirectionIsRTL && aRTLParagraph && !CharacterIsNeutral(prevCh)) ||
+ (!aInputDirectionIsRTL && CharacterIsStrongRightToLeft(prevCh)))
+ { // mark neutral with LRM
+ insertBuf[0]=ELeftToRightMark;
+ aDecoratedText.Insert(aDecoratedText.Length() -1, insertBuf);
+ aDecoratedText.Append(insertBuf);
+
+ if (aPositionOfInsertionPointInInlineText > ii)
+ aPositionOfInsertionPointInInlineText+=ETwoCharacters;
+ }
+ }
+ prevCh = curCh;
+ }
+ }
+