fontservices/textbase/sgdi/BidiCopy.cpp
author hgs
Mon, 12 Jul 2010 14:38:26 +0800
changeset 45 662fa7de7023
permissions -rw-r--r--
201024_05
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45
662fa7de7023 201024_05
hgs
parents:
diff changeset
     1
// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
662fa7de7023 201024_05
hgs
parents:
diff changeset
     2
// All rights reserved.
662fa7de7023 201024_05
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
662fa7de7023 201024_05
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
662fa7de7023 201024_05
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
662fa7de7023 201024_05
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
662fa7de7023 201024_05
hgs
parents:
diff changeset
     7
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
     8
// Initial Contributors:
662fa7de7023 201024_05
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    10
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    11
// Contributors:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    12
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    13
// Description:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    14
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    15
662fa7de7023 201024_05
hgs
parents:
diff changeset
    16
#include "BidiCopy.h"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    17
#include <e32std.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    18
#include "mglyphs.inl"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    19
662fa7de7023 201024_05
hgs
parents:
diff changeset
    20
TInt BidiCopy::Mirror(TInt a)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    21
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    22
Find the mirror image of a character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    23
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
    24
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    25
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    26
	TInt current = MirrorStart(a);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    27
	unsigned long v = mGlyphArray[current];
662fa7de7023 201024_05
hgs
parents:
diff changeset
    28
	TInt key = v >> 16;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    29
	// 1st easy-out: no steps at all for any at this key
662fa7de7023 201024_05
hgs
parents:
diff changeset
    30
	if (key == 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    31
		return a;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    32
	// 2nd easy-out: no steps at all but we have found it
662fa7de7023 201024_05
hgs
parents:
diff changeset
    33
	if (key == a)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    34
		return v & 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    35
	TInt step = MirrorStep(a);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    36
	do	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    37
		current += step;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    38
		current &= (KMirrorTableSize-1);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    39
		key = mGlyphArray[current] >> 16;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    40
		if (key == a)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    41
			return mGlyphArray[current] & 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    42
		} while (key != 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    43
	return a;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    44
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    45
662fa7de7023 201024_05
hgs
parents:
diff changeset
    46
void BidiCopy::ReverseCodes(TText* aText, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    47
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    48
Reverse the contents of aText[0..aLength], so that aText[0] holds the
662fa7de7023 201024_05
hgs
parents:
diff changeset
    49
value previously found in aText[aLength - 1], aText[1] holds the value
662fa7de7023 201024_05
hgs
parents:
diff changeset
    50
previously held in aText[aLength - 2] and so on.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    51
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
    52
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    53
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    54
	TText *text = aText;	// backup
662fa7de7023 201024_05
hgs
parents:
diff changeset
    55
662fa7de7023 201024_05
hgs
parents:
diff changeset
    56
	// reverse int16 by int16 (note: high surrogate + low surrogate will be reverse to low surrogate + high surrogate)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    57
	TText* end = aText + aLength - 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    58
	while (aText < end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    59
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    60
		TText t = *aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    61
		*aText = *end;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    62
		*end = t;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    63
		++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    64
		--end;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    65
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    66
662fa7de7023 201024_05
hgs
parents:
diff changeset
    67
	CorrectSurrogatePairs(text, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    68
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    69
662fa7de7023 201024_05
hgs
parents:
diff changeset
    70
void BidiCopy::DeleteUnreversedSurrogates(TText* aText, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    71
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    72
Replaces all surrogates with 0xFFFF that are not paired up the wrong
662fa7de7023 201024_05
hgs
parents:
diff changeset
    73
way round.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    74
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
    75
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    76
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    77
	if (aLength < 1)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    78
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    79
	TText* end = aText + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    80
	while (aText < end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    81
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    82
		if ((aText[0] & 0xF800) == 0xD800)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    83
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    84
			if ((aText[0] & 0xFC00) == 0xD800
662fa7de7023 201024_05
hgs
parents:
diff changeset
    85
				&& aText + 1 != end
662fa7de7023 201024_05
hgs
parents:
diff changeset
    86
				&& (aText[1] & 0xFC00) == 0xDC00)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    87
				++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    88
			else
662fa7de7023 201024_05
hgs
parents:
diff changeset
    89
				aText[0] = 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    90
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    91
		++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    92
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    93
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    94
662fa7de7023 201024_05
hgs
parents:
diff changeset
    95
void BidiCopy::CorrectSurrogatePairs(TText* aText, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    96
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    97
Corrects all reversed surrogate pairs. Assumes that no unpaired
662fa7de7023 201024_05
hgs
parents:
diff changeset
    98
surrogates are present.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    99
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   100
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   101
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   102
	TText* end = aText + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   103
	while (aText < end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   104
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   105
		if ((aText[0] & 0xF800) == 0xD800)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   106
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   107
			// Surrogate pair discovered.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   108
			// Do we need to swap it?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   109
			ASSERT(aText + 1 < end);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   110
			ASSERT((aText[1] & 0xF800) == 0xD800);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   111
			if ((aText[0] & 0xFC00) == 0xDC00)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   112
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   113
				ASSERT((aText[1] & 0xFC00) == 0xD800);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   114
				TText t = aText[0];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   115
				aText[0] = aText[1];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   116
				aText[1] = t;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   117
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   118
			++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   119
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   120
		++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   121
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   122
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   123
662fa7de7023 201024_05
hgs
parents:
diff changeset
   124
void BidiCopy::CorrectGroups(TText* aText, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   125
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   126
Correct all reversed groups (non-combiner followed by combining
662fa7de7023 201024_05
hgs
parents:
diff changeset
   127
characters). Surrogate pairs may be reversed by this operation.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   128
Assumes that no unpaired surrogates are present.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   129
Leading and trailing 0xFFFFs are left alone.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   130
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   131
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   132
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   133
	TText *end = aText + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   134
	// Ignore leading 0xFFFFs. This helps Tagma's
662fa7de7023 201024_05
hgs
parents:
diff changeset
   135
	// RTmTextCache::GetDisplayedText with its sentinels.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   136
	while (aText < end && *aText == 0xFFFF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   137
		++aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   138
	TText* groupStart = aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   139
	while (aText < end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   140
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   141
		TText* next = aText + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   142
		TInt c = aText[0];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   143
		if ((c & 0xFC00) == 0xD800)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   144
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   145
			ASSERT(aText + 1 < end);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   146
			ASSERT((aText[1] & 0xFC00) == 0xDC00);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   147
			c = (c << 10) + (aText[1] & 0x3FF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   148
				+ (0x10000 - 0xD800*0x400);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   149
			++next;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   150
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   151
		// ignore non-characters
662fa7de7023 201024_05
hgs
parents:
diff changeset
   152
		if ((c & 0xFFFE) != 0xFFFE)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   153
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   154
			// non-marks represent the end of groups that may need to
662fa7de7023 201024_05
hgs
parents:
diff changeset
   155
			// be reversed
662fa7de7023 201024_05
hgs
parents:
diff changeset
   156
			TChar ch = c;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   157
			if ((ch.GetCategory() & 0xFFFFFFF0) != TChar::EMarkGroup)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   158
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   159
				if (aText != groupStart)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   160
					ReverseCodes(groupStart, aText - groupStart + 1);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   161
				groupStart = next;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   162
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   163
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   164
		aText = next;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   165
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   166
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   167
662fa7de7023 201024_05
hgs
parents:
diff changeset
   168
void BidiCopy::SubstituteMirrorImages(TText* aText, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   169
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   170
Reverse all mirror image characters. Will not change characters
662fa7de7023 201024_05
hgs
parents:
diff changeset
   171
in the basic multilingual plane for surrogate pairs. Assumes
662fa7de7023 201024_05
hgs
parents:
diff changeset
   172
that no unpaired surrogates are present.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   173
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   174
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   175
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   176
	TText *end = aText + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   177
	while (aText < end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   178
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   179
		TText* next = aText + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   180
		TInt c = aText[0];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   181
		if ((c & 0xFC00) == 0xD800)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   182
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   183
			ASSERT(aText + 1 < end);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   184
			ASSERT((aText[1] & 0xFC00) == 0xDC00);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   185
			c = (c << 10) + (aText[1] & 0x3FF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   186
				+ (0x10000 - 0xD800*0x400);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   187
			++next;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   188
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   189
		TInt m = Mirror(c);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   190
		if (m != c)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   191
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   192
			if (m <= 0xFFFF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   193
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   194
				aText[0] = static_cast<TText>(m);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   195
				if (0xFFFF < c)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   196
					aText[1] = 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   197
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   198
			else if (0xFFFF < c)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   199
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   200
				aText[0] = static_cast<TText>((c >> 10) + 0xD760);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   201
				aText[1] = static_cast<TText>((c & 0x3FF) + 0xDC00);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   202
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   203
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   204
		aText = next;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   205
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   206
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   207
662fa7de7023 201024_05
hgs
parents:
diff changeset
   208
TText* BidiCopy::CopyMirror(TText* aDestination, const TText* aSource, TInt length)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   209
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   210
Copy some text, substituting mirrored characters.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   211
662fa7de7023 201024_05
hgs
parents:
diff changeset
   212
@return aDestination + number of TText codes output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   213
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   214
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   215
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   216
	for (; length; --length, ++aDestination, ++aSource)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   217
		*aDestination = static_cast<TText>(Mirror(*aSource));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   218
	return aDestination;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   219
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   220
662fa7de7023 201024_05
hgs
parents:
diff changeset
   221
TText* BidiCopy::OutputTChar(TText* aDestination, TInt aToOutput)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   222
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   223
Write out the input character as UTF16.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   224
662fa7de7023 201024_05
hgs
parents:
diff changeset
   225
@return aDestination + number of TText codes output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   226
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   227
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   228
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   229
	if (aToOutput > 0xFFFF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   230
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   231
		TInt c = aToOutput;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   232
		aDestination[0] = static_cast<TText>((c >> 10) + 0xD760);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   233
		aDestination[1] = static_cast<TText>((c & 0x3FF) + 0xDC00);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   234
		return aDestination + 2;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   235
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   236
	*aDestination = static_cast<TText>(aToOutput);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   237
	return aDestination + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   238
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   239
662fa7de7023 201024_05
hgs
parents:
diff changeset
   240
TText* BidiCopy::CopyBackwards(TText* aDestination,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   241
	const TText* aSource, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   242
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   243
Copy the text backwards without substituting mirrored characters,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   244
checking for surrogate pairs or combining characters.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   245
662fa7de7023 201024_05
hgs
parents:
diff changeset
   246
@return aDestination + number of TText codes output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   247
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   248
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   249
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   250
	TText *end = aDestination + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   251
	while (aDestination != end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   252
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   253
		*--end = *aSource++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   254
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   255
	return aDestination + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   256
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   257
662fa7de7023 201024_05
hgs
parents:
diff changeset
   258
TText* BidiCopy::CopyBackwardsWithMirroring(TText* aDestination,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   259
	const TText* aSource, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   260
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   261
Copy the text backwards to the output without checking for surrogate
662fa7de7023 201024_05
hgs
parents:
diff changeset
   262
pairs or combining characters, substituting mirrored characters.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   263
662fa7de7023 201024_05
hgs
parents:
diff changeset
   264
@return aDestination + number of TText codes output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   265
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   266
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   267
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   268
	TText *end = aDestination + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   269
	while (aDestination != end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   270
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   271
		*--end = static_cast<TText>(Mirror(*aSource++));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   272
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   273
	return aDestination + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   274
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   275
662fa7de7023 201024_05
hgs
parents:
diff changeset
   276
TText* BidiCopy::CopyGroupsBackwards(TText* aDestination,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   277
	const TText* aSource, TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   278
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   279
Copy the text backwards, substituting mirrored characters and correctly
662fa7de7023 201024_05
hgs
parents:
diff changeset
   280
handling all surrogate pairs and combining characters.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   281
662fa7de7023 201024_05
hgs
parents:
diff changeset
   282
@return aDestination + number of TText codes output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   283
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   284
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   285
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   286
	TText* retval = CopyBackwards(aDestination, aSource, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   287
	DeleteUnreversedSurrogates(aDestination, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   288
	SubstituteMirrorImages(aDestination, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   289
	CorrectGroups(aDestination, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   290
	CorrectSurrogatePairs(aDestination, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   291
	return retval;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   292
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   293
662fa7de7023 201024_05
hgs
parents:
diff changeset
   294
TBool BidiCopy::ImplicitDirectionalityIsRightToLeft(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   295
	const TText* aText, TInt aLength, TBool* aFound)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   296
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   297
Find out if the implicit directionality of a piece of text is right to
662fa7de7023 201024_05
hgs
parents:
diff changeset
   298
left.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   299
662fa7de7023 201024_05
hgs
parents:
diff changeset
   300
@param aText Text to be examined, or the first portion of text to be examined.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   301
@param aLength Length of the text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   302
@param aFound If non-null, returns ETrue if the directionality could be
662fa7de7023 201024_05
hgs
parents:
diff changeset
   303
determined from aText. If not, and there is more text beyond, the function 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   304
should be called with the next portion of text until aFound returns ETrue 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   305
or there is no more text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   306
@return	ETrue if the directionality is right to left. If the directionality
662fa7de7023 201024_05
hgs
parents:
diff changeset
   307
cannot be determined solely from this text, EFalse is returned.	This is the 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   308
implicit directionality of text that is composed entirely of neutrals.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   309
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   310
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   311
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   312
	if (aFound)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   313
		*aFound = ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   314
	const TText* end = aText + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   315
	TInt lastUtf16 = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   316
	while (aText != end)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   317
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   318
		TInt code = *aText++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   319
		if ((code & 0xFFFFFC00) == 0xD800
662fa7de7023 201024_05
hgs
parents:
diff changeset
   320
			&& (lastUtf16 & 0xFFFFFC00) == 0xDC00)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   321
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   322
			code = (code << 10) + (lastUtf16 & 0x3FF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   323
				+ (0x10000 - 0xD800*0x400);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   324
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   325
		lastUtf16 = code;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   326
		TChar c = code;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   327
		switch(c.GetBdCategory())
662fa7de7023 201024_05
hgs
parents:
diff changeset
   328
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   329
		case TChar::ELeftToRight:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   330
			return EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   331
		case TChar::ERightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   332
		case TChar::ERightToLeftArabic:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   333
			return ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   334
		default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   335
			break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   336
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   337
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   338
	if (aFound)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   339
		*aFound = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   340
	return EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   341
	}