sl@0: // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #ifndef __TBIDI_H__ sl@0: #define __TBIDI_H__ sl@0: sl@0: #include "TGraphicsHarness.h" sl@0: sl@0: sl@0: inline TBool IsSupplementary(TUint aChar) sl@0: /** sl@0: @param aChar The 32-bit code point value of a Unicode character. sl@0: sl@0: @return True, if aChar is supplementary character; false, otherwise. sl@0: */ sl@0: { sl@0: return (aChar > 0xFFFF); sl@0: } sl@0: sl@0: inline TBool IsHighSurrogate(TText16 aInt16) sl@0: /** sl@0: @return True, if aText16 is high surrogate; false, otherwise. sl@0: */ sl@0: { sl@0: return (aInt16 & 0xFC00) == 0xD800; sl@0: } sl@0: sl@0: inline TBool IsLowSurrogate(TText16 aInt16) sl@0: /** sl@0: @return True, if aText16 is low surrogate; false, otherwise. sl@0: */ sl@0: { sl@0: return (aInt16 & 0xFC00) == 0xDC00; sl@0: } sl@0: sl@0: inline TUint JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate) sl@0: /** sl@0: Combine a high surrogate and a low surrogate into a supplementary character. sl@0: sl@0: @return The 32-bit code point value of the generated Unicode supplementary sl@0: character. sl@0: */ sl@0: { sl@0: return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate; sl@0: } sl@0: sl@0: inline TText16 GetHighSurrogate(TUint aChar) sl@0: /** sl@0: Retrieve the high surrogate of a supplementary character. sl@0: sl@0: @param aChar The 32-bit code point value of a Unicode character. sl@0: sl@0: @return High surrogate of aChar, if aChar is a supplementary character; sl@0: aChar itself, if aChar is not a supplementary character. sl@0: */ sl@0: { sl@0: return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10)); sl@0: } sl@0: sl@0: inline TText16 GetLowSurrogate(TUint aChar) sl@0: /** sl@0: Retrieve the low surrogate of a supplementary character. sl@0: sl@0: @param aChar The 32-bit code point value of a Unicode character. sl@0: sl@0: @return Low surrogate of aChar, if aChar is a supplementary character; sl@0: zero, if aChar is not a supplementary character. sl@0: */ sl@0: { sl@0: return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF)); sl@0: } sl@0: sl@0: void AppendCharacter(HBufC *aDes, TUint aChar); sl@0: void AppendCharacter(TBuf<24> *aDes, TUint aChar); sl@0: sl@0: sl@0: // Class to implement a wrapping iterator meant for extracting 16 bit characters sl@0: // from a block of text sl@0: // This class can handle surrogate pairs correctly. sl@0: class TextIterator sl@0: { sl@0: public: sl@0: TextIterator(const TText16* aData, const TInt aLength) : sl@0: iData(aData), iLength(aLength), iIndex(0), iWrapped(EFalse), iCombineSurrogatePairs(ETrue) sl@0: { sl@0: } sl@0: TextIterator(const TText16* aData, const TInt aLength, const TInt aIndex) : sl@0: iData(aData), iLength(aLength), iIndex(aIndex), iWrapped(EFalse), iCombineSurrogatePairs(ETrue) sl@0: { sl@0: } sl@0: TextIterator(const TText16* aData, const TInt aLength, const TInt aIndex, TBool aCombineSurrogatePairs) : sl@0: iData(aData), iLength(aLength), iIndex(aIndex), iWrapped(EFalse), iCombineSurrogatePairs(aCombineSurrogatePairs) sl@0: { sl@0: } sl@0: // Next character from data - wrap pointer to keep within data. sl@0: // Get current char, then move the internal pointer forward to next char. sl@0: TUint NextChar() sl@0: { sl@0: TUint ch = Char(); sl@0: if (iCombineSurrogatePairs && IsSupplementary(ch)) sl@0: iIndex += 2; sl@0: else sl@0: iIndex += 1; sl@0: // wrap sl@0: if (iIndex >= iLength) sl@0: { sl@0: iIndex = 0; sl@0: iWrapped = ETrue; sl@0: } sl@0: return ch; sl@0: } sl@0: // Move the internal pointer backward, then return the char pointed by internal char. sl@0: // Panic if iIndex already = 0. sl@0: TUint PreviousChar() sl@0: { sl@0: ASSERT(iIndex > 0); sl@0: iIndex--; sl@0: if (iCombineSurrogatePairs && IsLowSurrogate(iData[iIndex])) sl@0: { sl@0: ASSERT(iIndex > 0); sl@0: iIndex--; sl@0: ASSERT(IsHighSurrogate(iData[iIndex])); sl@0: } sl@0: else if (iCombineSurrogatePairs && IsHighSurrogate(iData[iIndex])) sl@0: { sl@0: ASSERT(EFalse); sl@0: } sl@0: else sl@0: { sl@0: // do nothing sl@0: } sl@0: return Char(); sl@0: } sl@0: //Reset the iterator to the original values sl@0: void Reset() sl@0: { sl@0: iIndex = 0; sl@0: iWrapped = EFalse; sl@0: } sl@0: void SetIndex(const TInt aIndex) sl@0: { sl@0: iIndex = aIndex; sl@0: iWrapped = EFalse; sl@0: } sl@0: //Has the iterator wrapped back to the start of the buffer at least once? sl@0: TBool Wrapped() const sl@0: { sl@0: return iWrapped; sl@0: } sl@0: //Where is the current buffer index? sl@0: TInt Index() const sl@0: { sl@0: return iIndex; sl@0: } sl@0: //Return pointer to data sl@0: const TText16* Ptr() const sl@0: { sl@0: return iData; sl@0: } sl@0: //Get length of data sl@0: TInt Length() const sl@0: { sl@0: return iLength; sl@0: } sl@0: //Get character at current index sl@0: TUint Char() const sl@0: { sl@0: TUint ch = 0xFFFF; sl@0: TText16 i16 = iData[iIndex]; sl@0: if (iCombineSurrogatePairs && IsHighSurrogate(i16)) sl@0: { sl@0: ASSERT(iIndex+1 < iLength); sl@0: TText16 low = iData[iIndex+1]; sl@0: ch = JoinSurrogate(i16, low); sl@0: } sl@0: else if (iCombineSurrogatePairs && IsLowSurrogate(i16)) sl@0: { sl@0: ASSERT(EFalse); sl@0: } sl@0: else sl@0: { sl@0: ch = i16; sl@0: } sl@0: return ch; sl@0: } sl@0: // Fill aBuffer with a char, fill at aIndex, guarded by aMaxIndex (excluded). sl@0: // After return, aIndex points to the next position, if aUpdate_aIndex=ETrue. sl@0: // aUpdate_aIndex: do you want to update the parameter aIndex? sl@0: // aUpdate_iIndex: do you want to update the member variable iIndex? sl@0: // aChar: [out] current char sl@0: TBool NextCharInto(TDes &aBuffer, TInt &aIndex, TInt aMaxIndex=-1, TBool aUpdate_aIndex=ETrue, TBool aUpdate_iIndex=ETrue, TUint *aChar=NULL) sl@0: { sl@0: if (aMaxIndex < 0) sl@0: aMaxIndex = aBuffer.Length(); sl@0: if (aIndex >= aMaxIndex) sl@0: return EFalse; sl@0: sl@0: TUint ch = Char(); sl@0: if (iCombineSurrogatePairs && IsSupplementary(ch)) sl@0: { sl@0: if (aIndex+1 >= aMaxIndex) sl@0: return EFalse; sl@0: aBuffer[aIndex] = GetHighSurrogate(ch); sl@0: aBuffer[aIndex+1] = GetLowSurrogate(ch); sl@0: if (aUpdate_aIndex) sl@0: aIndex += 2; sl@0: } sl@0: else sl@0: { sl@0: aBuffer[aIndex] = (TText16)ch; sl@0: if (aUpdate_aIndex) sl@0: aIndex++; sl@0: } sl@0: if (aChar) sl@0: *aChar = ch; sl@0: if (aUpdate_iIndex) sl@0: { sl@0: if (iCombineSurrogatePairs && IsSupplementary(ch)) sl@0: iIndex += 2; sl@0: else sl@0: iIndex += 1; sl@0: if (iIndex >= iLength) sl@0: { sl@0: iIndex = 0; sl@0: iWrapped = ETrue; sl@0: } sl@0: } sl@0: return ETrue; sl@0: } sl@0: // Fill aBuffer from aIndex to aMaxIndex (excluded). sl@0: // aMaxIndex=-1 means fill to index=aBuffer.Length. sl@0: // After return, aIndex points to the next position, if aUpdate_aIndex=ETrue. sl@0: TBool FillInto(TDes &aBuffer, TInt &aIndex, TInt aMaxIndex=-1) sl@0: { sl@0: if (aMaxIndex == -1) sl@0: aMaxIndex = aBuffer.Length(); sl@0: while (aIndex < aMaxIndex) sl@0: { sl@0: TBool b = NextCharInto(aBuffer, aIndex, aMaxIndex); sl@0: if (!b) sl@0: { sl@0: return ETrue; sl@0: } sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: private: sl@0: const TText16* iData; sl@0: TInt iLength; sl@0: TInt iIndex; sl@0: TBool iWrapped; sl@0: TBool iCombineSurrogatePairs; // ETrue = combine surrogates; EFalse = take single surrogate as character sl@0: }; sl@0: sl@0: class CTBiDiStep : public CTGraphicsStep sl@0: { sl@0: public: sl@0: CTBiDiStep(); sl@0: protected: sl@0: //from CTGraphicsStep sl@0: virtual CTGraphicsBase* CreateTestL(); sl@0: }; sl@0: sl@0: _LIT(KTBiDiStep,"TBiDi"); sl@0: sl@0: sl@0: #endif