fontservices/textbase/tgdi/TBiDi.h
changeset 45 662fa7de7023
equal deleted inserted replaced
41:ea44a32a96bc 45:662fa7de7023
       
     1 // Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #ifndef __TBIDI_H__
       
    17 #define __TBIDI_H__
       
    18 
       
    19 #include "TGraphicsHarness.h"
       
    20 
       
    21 
       
    22 inline TBool IsSupplementary(TUint aChar)
       
    23 /**
       
    24 @param aChar The 32-bit code point value of a Unicode character.
       
    25 
       
    26 @return True, if aChar is supplementary character; false, otherwise.
       
    27 */
       
    28 	{
       
    29 	return (aChar > 0xFFFF);
       
    30 	}
       
    31 
       
    32 inline TBool IsHighSurrogate(TText16 aInt16)
       
    33 /**
       
    34 @return True, if aText16 is high surrogate; false, otherwise.
       
    35 */
       
    36 	{
       
    37 	return (aInt16 & 0xFC00) == 0xD800;
       
    38 	}
       
    39 
       
    40 inline TBool IsLowSurrogate(TText16 aInt16)
       
    41 /**
       
    42 @return True, if aText16 is low surrogate; false, otherwise.
       
    43 */
       
    44 	{
       
    45 	return (aInt16 & 0xFC00) == 0xDC00;
       
    46 	}
       
    47 
       
    48 inline TUint JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate)
       
    49 /**
       
    50 Combine a high surrogate and a low surrogate into a supplementary character.
       
    51 
       
    52 @return The 32-bit code point value of the generated Unicode supplementary
       
    53         character.
       
    54 */
       
    55 	{
       
    56 	return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
       
    57 	}
       
    58 
       
    59 inline TText16 GetHighSurrogate(TUint aChar)
       
    60 /**
       
    61 Retrieve the high surrogate of a supplementary character.
       
    62 
       
    63 @param aChar The 32-bit code point value of a Unicode character.
       
    64 
       
    65 @return High surrogate of aChar, if aChar is a supplementary character; 
       
    66         aChar itself, if aChar is not a supplementary character.
       
    67 */
       
    68 	{
       
    69 	return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10));
       
    70 	}
       
    71 
       
    72 inline TText16 GetLowSurrogate(TUint aChar)
       
    73 /**
       
    74 Retrieve the low surrogate of a supplementary character.
       
    75 
       
    76 @param aChar The 32-bit code point value of a Unicode character.
       
    77 
       
    78 @return Low surrogate of aChar, if aChar is a supplementary character; 
       
    79         zero, if aChar is not a supplementary character.
       
    80 */
       
    81 	{
       
    82 	return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF));
       
    83 	}
       
    84 
       
    85 void AppendCharacter(HBufC *aDes, TUint aChar);
       
    86 void AppendCharacter(TBuf<24> *aDes, TUint aChar);
       
    87 
       
    88 
       
    89 // Class to implement a wrapping iterator meant for extracting 16 bit characters
       
    90 // from a block of text
       
    91 // This class can handle surrogate pairs correctly.
       
    92 class TextIterator
       
    93 	{
       
    94 public:
       
    95 	TextIterator(const TText16* aData, const TInt aLength) : 
       
    96 	  iData(aData), iLength(aLength), iIndex(0), iWrapped(EFalse), iCombineSurrogatePairs(ETrue)
       
    97 		{
       
    98 		}	
       
    99 	TextIterator(const TText16* aData, const TInt aLength, const TInt aIndex) : 
       
   100 		iData(aData), iLength(aLength), iIndex(aIndex), iWrapped(EFalse), iCombineSurrogatePairs(ETrue)
       
   101 		{
       
   102 		}
       
   103 	TextIterator(const TText16* aData, const TInt aLength, const TInt aIndex, TBool aCombineSurrogatePairs) : 
       
   104 		iData(aData), iLength(aLength), iIndex(aIndex), iWrapped(EFalse), iCombineSurrogatePairs(aCombineSurrogatePairs)
       
   105 		{
       
   106 		}
       
   107 	// Next character from data - wrap pointer to keep within data.
       
   108 	// Get current char, then move the internal pointer forward to next char.
       
   109 	TUint NextChar()
       
   110 		{
       
   111 		TUint ch = Char();
       
   112 		if (iCombineSurrogatePairs && IsSupplementary(ch))
       
   113 			iIndex += 2;
       
   114 		else
       
   115 			iIndex += 1;
       
   116 		// wrap
       
   117 		if (iIndex >= iLength)
       
   118 			{
       
   119 			iIndex = 0;
       
   120 			iWrapped = ETrue;
       
   121 			}
       
   122 		return ch;
       
   123 		}
       
   124 	// Move the internal pointer backward, then return the char pointed by internal char.
       
   125 	// Panic if iIndex already = 0.
       
   126 	TUint PreviousChar()
       
   127 		{
       
   128 		ASSERT(iIndex > 0);
       
   129 		iIndex--;
       
   130 		if (iCombineSurrogatePairs && IsLowSurrogate(iData[iIndex]))
       
   131 			{
       
   132 			ASSERT(iIndex > 0);
       
   133 			iIndex--;
       
   134 			ASSERT(IsHighSurrogate(iData[iIndex]));
       
   135 			}
       
   136 		else if (iCombineSurrogatePairs && IsHighSurrogate(iData[iIndex]))
       
   137 			{
       
   138 			ASSERT(EFalse);
       
   139 			}
       
   140 		else
       
   141 			{
       
   142 			// do nothing
       
   143 			}
       
   144 		return Char();
       
   145 		}
       
   146 	//Reset the iterator to the original values
       
   147 	void Reset()
       
   148 		{
       
   149 		iIndex = 0;
       
   150 		iWrapped = EFalse;
       
   151 		}
       
   152 	void SetIndex(const TInt aIndex)
       
   153 		{
       
   154 		iIndex = aIndex;
       
   155 		iWrapped = EFalse;
       
   156 		}
       
   157 	//Has the iterator wrapped back to the start of the buffer at least once?
       
   158 	TBool Wrapped() const
       
   159 		{
       
   160 		return iWrapped;
       
   161 		}
       
   162 	//Where is the current buffer index?
       
   163 	TInt Index() const
       
   164 		{
       
   165 		return iIndex;
       
   166 		}
       
   167 	//Return pointer to data
       
   168 	const TText16* Ptr() const
       
   169 		{
       
   170 		return iData;
       
   171 		}
       
   172 	//Get length of data
       
   173 	TInt Length() const
       
   174 		{
       
   175 		return iLength;
       
   176 		}
       
   177 	//Get character at current index
       
   178 	TUint Char() const
       
   179 		{
       
   180 		TUint ch = 0xFFFF;
       
   181 		TText16 i16 = iData[iIndex];
       
   182 		if (iCombineSurrogatePairs && IsHighSurrogate(i16))
       
   183 			{
       
   184 			ASSERT(iIndex+1 < iLength);
       
   185 			TText16 low = iData[iIndex+1];
       
   186 			ch = JoinSurrogate(i16, low);
       
   187 			}
       
   188 		else if (iCombineSurrogatePairs && IsLowSurrogate(i16))
       
   189 			{
       
   190 			ASSERT(EFalse);
       
   191 			}
       
   192 		else
       
   193 			{
       
   194 			ch = i16;
       
   195 			}
       
   196 		return ch;
       
   197 		}
       
   198 	// Fill aBuffer with a char, fill at aIndex, guarded by aMaxIndex (excluded).
       
   199 	// After return, aIndex points to the next position, if aUpdate_aIndex=ETrue.
       
   200 	// aUpdate_aIndex: do you want to update the parameter aIndex?
       
   201 	// aUpdate_iIndex: do you want to update the member variable iIndex?
       
   202 	// aChar: [out] current char
       
   203 	TBool NextCharInto(TDes &aBuffer, TInt &aIndex, TInt aMaxIndex=-1, TBool aUpdate_aIndex=ETrue, TBool aUpdate_iIndex=ETrue, TUint *aChar=NULL)
       
   204 		{
       
   205 		if (aMaxIndex < 0)
       
   206 			aMaxIndex = aBuffer.Length();
       
   207 		if (aIndex >= aMaxIndex)
       
   208 			return EFalse;
       
   209 
       
   210 		TUint ch = Char();
       
   211 		if (iCombineSurrogatePairs && IsSupplementary(ch))
       
   212 			{
       
   213 			if (aIndex+1 >= aMaxIndex)
       
   214 				return EFalse;
       
   215 			aBuffer[aIndex] = GetHighSurrogate(ch);
       
   216 			aBuffer[aIndex+1] = GetLowSurrogate(ch);
       
   217 			if (aUpdate_aIndex)
       
   218 				aIndex += 2;
       
   219 			}
       
   220 		else
       
   221 			{
       
   222 			aBuffer[aIndex] = (TText16)ch;
       
   223 			if (aUpdate_aIndex)
       
   224 				aIndex++;
       
   225 			}
       
   226 		if (aChar)
       
   227 			*aChar = ch;
       
   228 		if (aUpdate_iIndex)
       
   229 			{
       
   230 			if (iCombineSurrogatePairs && IsSupplementary(ch))
       
   231 				iIndex += 2;
       
   232 			else
       
   233 				iIndex += 1;
       
   234 			if (iIndex >= iLength)
       
   235 				{
       
   236 				iIndex = 0;
       
   237 				iWrapped = ETrue;
       
   238 				}
       
   239 			}
       
   240 		return ETrue;
       
   241 		}
       
   242 	// Fill aBuffer from aIndex to aMaxIndex (excluded).
       
   243 	// aMaxIndex=-1 means fill to index=aBuffer.Length.
       
   244 	// After return, aIndex points to the next position, if aUpdate_aIndex=ETrue.
       
   245 	TBool FillInto(TDes &aBuffer, TInt &aIndex, TInt aMaxIndex=-1)
       
   246 		{
       
   247 		if (aMaxIndex == -1)
       
   248 			aMaxIndex = aBuffer.Length();
       
   249 		while (aIndex < aMaxIndex)
       
   250 			{
       
   251 			TBool b = NextCharInto(aBuffer, aIndex, aMaxIndex);
       
   252 			if (!b)
       
   253 				{
       
   254 				return ETrue;
       
   255 				}
       
   256 			}
       
   257 		return ETrue;
       
   258 		}
       
   259 
       
   260 private:
       
   261 	const TText16* iData;
       
   262 	TInt  iLength;
       
   263 	TInt  iIndex;
       
   264 	TBool iWrapped;
       
   265 	TBool iCombineSurrogatePairs;	// ETrue = combine surrogates; EFalse = take single surrogate as character
       
   266 	};
       
   267 
       
   268 class CTBiDiStep : public CTGraphicsStep
       
   269 	{
       
   270 public:
       
   271 	CTBiDiStep();
       
   272 protected:	
       
   273 	//from CTGraphicsStep
       
   274 	virtual CTGraphicsBase* CreateTestL();
       
   275 	};
       
   276 
       
   277 _LIT(KTBiDiStep,"TBiDi");
       
   278 
       
   279 
       
   280 #endif