fontservices/textbase/sgdi/BidiText.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 <e32svr.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    17
#include "BidiTextImp.h"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    18
#include "BidiCopy.h"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    19
#include "BidiCompact.h"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    20
#include <bidi.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    21
#include <e32base.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    22
//#include <textbase.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    23
#include <gdi.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    24
#include <linebreak.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    25
662fa7de7023 201024_05
hgs
parents:
diff changeset
    26
_LIT(KBidiPanicCategory,"Bidi");
662fa7de7023 201024_05
hgs
parents:
diff changeset
    27
static const TInt KLineSeparator = 0x2028;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    28
static const TInt KParagraphSeparator = 0x2029;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    29
static const TInt KCodeCR = 0x000D;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    30
static const TInt KCodeLF = 0x000A;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    31
static const TInt KCodeEllipsis = 0x2026;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    32
662fa7de7023 201024_05
hgs
parents:
diff changeset
    33
void DeleteTRunInfo(void* aRunInfo)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    34
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    35
	delete[] reinterpret_cast<TBidirectionalState::TRunInfo*>(aRunInfo);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    36
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    37
662fa7de7023 201024_05
hgs
parents:
diff changeset
    38
void BidiPanic(TInt aError)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    39
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    40
	User::Panic(KBidiPanicCategory, aError);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    41
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    42
662fa7de7023 201024_05
hgs
parents:
diff changeset
    43
662fa7de7023 201024_05
hgs
parents:
diff changeset
    44
// One page-full of TRunInfos
662fa7de7023 201024_05
hgs
parents:
diff changeset
    45
const TInt KMaxRunInfoArraySize = 4*1024 / sizeof(TBidirectionalState::TRunInfo);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    46
const TInt KBidiTlsHandle = 0x101F633D;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    47
662fa7de7023 201024_05
hgs
parents:
diff changeset
    48
662fa7de7023 201024_05
hgs
parents:
diff changeset
    49
/*
662fa7de7023 201024_05
hgs
parents:
diff changeset
    50
* Ref-counted TLS for the shared run info array used by the SetText() method.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    51
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    52
NONSHARABLE_CLASS(CBidiTextTls) : public CObject
662fa7de7023 201024_05
hgs
parents:
diff changeset
    53
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    54
public:	
662fa7de7023 201024_05
hgs
parents:
diff changeset
    55
	static CBidiTextTls* NewL();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    56
	static CBidiTextTls* GetTls();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    57
	~CBidiTextTls();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    58
	inline TUint MaxArraySize();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    59
	inline TBidirectionalState::TRunInfo* RunArray();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    60
662fa7de7023 201024_05
hgs
parents:
diff changeset
    61
private:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    62
	CBidiTextTls();
662fa7de7023 201024_05
hgs
parents:
diff changeset
    63
	void ConstructL(TUint aMaxArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    64
662fa7de7023 201024_05
hgs
parents:
diff changeset
    65
private:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    66
	TBidirectionalState::TRunInfo* iRunInfoArray;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    67
	TUint iMaxArraySize;	
662fa7de7023 201024_05
hgs
parents:
diff changeset
    68
	};
662fa7de7023 201024_05
hgs
parents:
diff changeset
    69
662fa7de7023 201024_05
hgs
parents:
diff changeset
    70
662fa7de7023 201024_05
hgs
parents:
diff changeset
    71
662fa7de7023 201024_05
hgs
parents:
diff changeset
    72
CBidiTextTls::CBidiTextTls()
662fa7de7023 201024_05
hgs
parents:
diff changeset
    73
:	iRunInfoArray(NULL),
662fa7de7023 201024_05
hgs
parents:
diff changeset
    74
 	iMaxArraySize(0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    75
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    76
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    77
662fa7de7023 201024_05
hgs
parents:
diff changeset
    78
662fa7de7023 201024_05
hgs
parents:
diff changeset
    79
CBidiTextTls::~CBidiTextTls()
662fa7de7023 201024_05
hgs
parents:
diff changeset
    80
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    81
	UserSvr::DllFreeTls(KBidiTlsHandle);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    82
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
    83
	if (iRunInfoArray)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    84
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    85
		delete [] iRunInfoArray;	
662fa7de7023 201024_05
hgs
parents:
diff changeset
    86
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    87
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    88
662fa7de7023 201024_05
hgs
parents:
diff changeset
    89
662fa7de7023 201024_05
hgs
parents:
diff changeset
    90
TUint CBidiTextTls::MaxArraySize()
662fa7de7023 201024_05
hgs
parents:
diff changeset
    91
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    92
	return iMaxArraySize;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    93
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    94
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
    95
662fa7de7023 201024_05
hgs
parents:
diff changeset
    96
TBidirectionalState::TRunInfo* CBidiTextTls::RunArray()
662fa7de7023 201024_05
hgs
parents:
diff changeset
    97
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    98
	return iRunInfoArray;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    99
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   100
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   101
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   102
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   103
 * Helper function provided to simplify reading the TLS data and improve the
662fa7de7023 201024_05
hgs
parents:
diff changeset
   104
 * readability of the code 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   105
 */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   106
CBidiTextTls* CBidiTextTls::GetTls()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   107
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   108
	return reinterpret_cast<CBidiTextTls*>(UserSvr::DllTls(KBidiTlsHandle));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   109
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   110
662fa7de7023 201024_05
hgs
parents:
diff changeset
   111
662fa7de7023 201024_05
hgs
parents:
diff changeset
   112
CBidiTextTls* CBidiTextTls::NewL()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   113
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   114
	CBidiTextTls* self = new (ELeave) CBidiTextTls;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   115
	CleanupClosePushL(*self);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   116
	self->ConstructL(KMaxRunInfoArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   117
	CleanupStack::Pop(self);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   118
	return self;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   119
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   120
662fa7de7023 201024_05
hgs
parents:
diff changeset
   121
662fa7de7023 201024_05
hgs
parents:
diff changeset
   122
void CBidiTextTls::ConstructL(TUint aMaxArraySize)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   123
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   124
	iMaxArraySize = aMaxArraySize;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   125
	iRunInfoArray = new (ELeave) TBidirectionalState::TRunInfo[aMaxArraySize];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   126
	User::LeaveIfError(UserSvr::DllSetTls(KBidiTlsHandle, this));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   127
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   128
662fa7de7023 201024_05
hgs
parents:
diff changeset
   129
662fa7de7023 201024_05
hgs
parents:
diff changeset
   130
EXPORT_C RRunInfoArray::RRunInfoArray() 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   131
:	iTls(NULL)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   132
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   133
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   134
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   135
662fa7de7023 201024_05
hgs
parents:
diff changeset
   136
/** 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   137
Creates the run array if necessary and increases the reference count on it.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   138
RRunInfoArray::OpenL() must be called prior to calling TBidiText::SetText().
662fa7de7023 201024_05
hgs
parents:
diff changeset
   139
 */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   140
EXPORT_C void RRunInfoArray::OpenL()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   141
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   142
	if(!iTls)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   143
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   144
		iTls = CBidiTextTls::GetTls();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   145
		if(iTls)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   146
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   147
			iTls->Open();	// Increase ref count	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   148
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   149
		else	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   150
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   151
			iTls = CBidiTextTls::NewL();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   152
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   153
		}	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   154
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   155
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   156
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   157
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   158
Decreases the reference count on the run array. The run array will be deleted
662fa7de7023 201024_05
hgs
parents:
diff changeset
   159
if the reference count reaches zero. The client application must ensure that
662fa7de7023 201024_05
hgs
parents:
diff changeset
   160
there is a matching call to Close() for every call to OpenL() or memory will
662fa7de7023 201024_05
hgs
parents:
diff changeset
   161
be leaked.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   162
 */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   163
EXPORT_C void RRunInfoArray::Close()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   164
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   165
	if(iTls)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   166
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   167
		iTls->Close();	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   168
		iTls = NULL;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   169
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   170
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   171
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   172
662fa7de7023 201024_05
hgs
parents:
diff changeset
   173
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   174
@return Pointer to the run array buffer
662fa7de7023 201024_05
hgs
parents:
diff changeset
   175
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   176
 */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   177
TBidirectionalState::TRunInfo* RRunInfoArray::RunArray() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   178
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   179
	return iTls ? iTls->RunArray() : NULL;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   180
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   181
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   182
662fa7de7023 201024_05
hgs
parents:
diff changeset
   183
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   184
@return Number of bytes needed to hold the TBidiTextImp member variables, plus the 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   185
		text data allocated off the end of the TBidiTextImp object.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   186
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   187
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   188
TInt TBidiTextImp::RequiredBytes(TInt aLength, TInt aMaxLines, TInt aBdRunArraySize)		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   189
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   190
	// size of TBidiTextImp class
662fa7de7023 201024_05
hgs
parents:
diff changeset
   191
	TInt bytes = TBidiTextImp::AlignedSizeOf();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   192
	// size of text for logical and visual orderings.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   193
	// This includes aMaxLines - 1 line breaks with surrounding
662fa7de7023 201024_05
hgs
parents:
diff changeset
   194
	// zero-width joiners, and a truncation character (possibly
662fa7de7023 201024_05
hgs
parents:
diff changeset
   195
	// a surrogate pair) plus a zero-width joiner.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   196
	bytes += sizeof(TText) * (aLength * 2 + aMaxLines * 3);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   197
	// size of line length array
662fa7de7023 201024_05
hgs
parents:
diff changeset
   198
	bytes += sizeof(TInt16*) * aMaxLines;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   199
	// alignment
662fa7de7023 201024_05
hgs
parents:
diff changeset
   200
	bytes = (bytes + 3) & 0xFFFFFFFC;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   201
	// array of TRunInfoCompact
662fa7de7023 201024_05
hgs
parents:
diff changeset
   202
	bytes += sizeof(TRunInfoCompact) * aBdRunArraySize;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   203
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   204
	return bytes;
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
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   209
@return A TBidiTextImp object of sufficient size to hold the amount of text data specified
662fa7de7023 201024_05
hgs
parents:
diff changeset
   210
		by the the arguments.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   211
@param aLength The number of characters in the text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   212
@param aMaxLines The maximum number of lines 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   213
@param aBdRunArraySize The size of the bidi run array. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   214
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   215
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   216
TBidiTextImp* TBidiTextImp::NewL(TInt aLength, TInt aMaxLines, TInt aBdRunArraySize)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   217
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   218
	const TInt bytes = RequiredBytes(aLength, aMaxLines, aBdRunArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   219
	TInt8* mem = static_cast<TInt8*>(User::AllocL(bytes));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   220
	TBidiTextImp* me = reinterpret_cast<TBidiTextImp*>(mem);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   221
662fa7de7023 201024_05
hgs
parents:
diff changeset
   222
	me->iTextLengthAndFlags = aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   223
	me->iVisualOrderedTextLength = -1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   224
	me->iWrappingWidth = 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   225
	me->iBidiRunArrayLength = aBdRunArraySize;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   226
	me->iLines = static_cast<TUint8>(aMaxLines);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   227
	me->iTruncationCharPlane = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   228
	me->iTruncationChar16 = KCodeEllipsis;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   229
	me->SetAllocatedTextDataBytes(bytes - TBidiTextImp::AlignedSizeOf() - (sizeof(TRunInfoCompact) * aBdRunArraySize));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   230
	return me;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   231
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   232
662fa7de7023 201024_05
hgs
parents:
diff changeset
   233
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   234
@return Position of logically-ordered text portion of the heap cell.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   235
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   236
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   237
TText* TBidiTextImp::LogicalText()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   238
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   239
	return reinterpret_cast<TText*>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   240
		reinterpret_cast<TInt8*>(this)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   241
		+ TBidiTextImp::AlignedSizeOf());
662fa7de7023 201024_05
hgs
parents:
diff changeset
   242
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   243
662fa7de7023 201024_05
hgs
parents:
diff changeset
   244
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   245
@return Position of visually-ordered text portion of the heap cell.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   246
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   247
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   248
TText* TBidiTextImp::VisualText()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   249
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   250
	TInt bytes = TBidiTextImp::AlignedSizeOf();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   251
	bytes += sizeof(TText) * TextLength();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   252
	return reinterpret_cast<TText*>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   253
		reinterpret_cast<TInt8*>(this) + bytes);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   254
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   255
662fa7de7023 201024_05
hgs
parents:
diff changeset
   256
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   257
Returns a pointer to the array containing the width in pixels of each and every line.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   258
@return Position of the array of line widths portion of the heap cell.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   259
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   260
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   261
TInt16* TBidiTextImp::LineWidthArray()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   262
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   263
	TInt bytes = TBidiTextImp::AlignedSizeOf();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   264
	bytes += sizeof(TText) * (TextLength() * 2 + iLines + 2);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   265
	return reinterpret_cast<TInt16*>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   266
		reinterpret_cast<TInt8*>(this) + bytes);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   267
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   268
662fa7de7023 201024_05
hgs
parents:
diff changeset
   269
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   270
@return Position of the array of runs portion of the heap cell.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   271
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   272
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   273
TRunInfoCompact* TBidiTextImp::BidiRunArray()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   274
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   275
	TInt bytes = TBidiTextImp::AlignedSizeOf();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   276
	bytes += sizeof(TText) * (TextLength() * 2 + iLines + 2);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   277
	bytes += sizeof(TInt16*) * iLines;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   278
	bytes = (bytes + 3) & 0xFFFFFFFC;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   279
	return reinterpret_cast<TRunInfoCompact*>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   280
		reinterpret_cast<TInt8*>(this) + bytes);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   281
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   282
662fa7de7023 201024_05
hgs
parents:
diff changeset
   283
/** 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   284
Report if the current character is an explicit line break. Both
662fa7de7023 201024_05
hgs
parents:
diff changeset
   285
aText[0] and aText[1] must be part of the string.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   286
@return Size of line break.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   287
@internalComponent 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   288
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   289
TInt SizeLineBreak(const TText* aText, const TText* aTextEnd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   290
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   291
	if (aText == aTextEnd )
662fa7de7023 201024_05
hgs
parents:
diff changeset
   292
		return 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   293
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   294
	if (*aText == KLineSeparator || *aText == KParagraphSeparator
662fa7de7023 201024_05
hgs
parents:
diff changeset
   295
		|| *aText == KCodeLF)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   296
		return 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   297
	if (aText[0] == KCodeCR)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   298
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   299
		// first check for space before checking for LF
662fa7de7023 201024_05
hgs
parents:
diff changeset
   300
		if (aText+1 < aTextEnd )
662fa7de7023 201024_05
hgs
parents:
diff changeset
   301
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   302
			return aText[1] == KCodeLF? 2 : 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   303
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   304
		else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   305
			return 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   306
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   307
	return 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   308
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   309
662fa7de7023 201024_05
hgs
parents:
diff changeset
   310
/** 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   311
Find the next line break character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   312
@internalComponent 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   313
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   314
const TText* FindEndOfThisLine(const TText* aStart, const TText* aEnd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   315
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   316
	while (aStart != aEnd && *aStart != KLineSeparator
662fa7de7023 201024_05
hgs
parents:
diff changeset
   317
		&& *aStart != KParagraphSeparator && *aStart != KCodeLF
662fa7de7023 201024_05
hgs
parents:
diff changeset
   318
		&& *aStart != KCodeCR)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   319
		++aStart;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   320
	return aStart;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   321
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   322
662fa7de7023 201024_05
hgs
parents:
diff changeset
   323
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   324
Count number of lines in text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   325
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   326
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   327
TInt NumberOfLines(const TText* aStart, const TText* aEnd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   328
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   329
	TInt num = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   330
	while (aStart != aEnd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   331
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   332
		aStart = FindEndOfThisLine(aStart, aEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   333
		aStart += SizeLineBreak(aStart, aEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   334
		++num;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   335
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   336
	return num;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   337
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   338
662fa7de7023 201024_05
hgs
parents:
diff changeset
   339
/** Returns the directionality of a given language.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   340
@param aLanguage Language.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   341
@return The directionality of the given language. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   342
EXPORT_C TBidiText::TDirectionality TBidiText::ScriptDirectionality(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   343
	TLanguage aLanguage)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   344
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   345
	const TUint32 DirectionalityBitmap[] =
662fa7de7023 201024_05
hgs
parents:
diff changeset
   346
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   347
		0,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   348
		// Arabic, Farsi, Hebrew
662fa7de7023 201024_05
hgs
parents:
diff changeset
   349
		0x02040020,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   350
		// Urdu
662fa7de7023 201024_05
hgs
parents:
diff changeset
   351
		0x40000000
662fa7de7023 201024_05
hgs
parents:
diff changeset
   352
		};
662fa7de7023 201024_05
hgs
parents:
diff changeset
   353
	TUint index = aLanguage;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   354
	if (index < sizeof(DirectionalityBitmap) * 8)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   355
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   356
		index >>= 5;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   357
		TInt bit = aLanguage & 31;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   358
		return (DirectionalityBitmap[index] >> bit) & 1?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   359
			ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   360
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   361
	return ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   362
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   363
662fa7de7023 201024_05
hgs
parents:
diff changeset
   364
662fa7de7023 201024_05
hgs
parents:
diff changeset
   365
/** Reports the implicit directionality of a piece of text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   366
662fa7de7023 201024_05
hgs
parents:
diff changeset
   367
@param aText The text to be examined. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   368
@param aFound If non-null, returns ETrue if there were any strongly directional 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   369
characters and EFalse if there were none. If a piece of text is spread over 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   370
several descriptors, They need to be queried in sequence until one returns 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   371
ETrue in aFound. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   372
@return The directionality implicit in aText. 131 */ 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   373
EXPORT_C TBidiText::TDirectionality TBidiText::TextDirectionality(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   374
	const TDesC& aText, TBool* aFound)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   375
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   376
	return BidiCopy::ImplicitDirectionalityIsRightToLeft(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   377
		aText.Ptr(), aText.Length(), aFound)?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   378
		ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   379
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   380
662fa7de7023 201024_05
hgs
parents:
diff changeset
   381
/** Creates a bidirectional text object with directionality determined by
662fa7de7023 201024_05
hgs
parents:
diff changeset
   382
aDirectionality. Use this for text that has come from user input.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   383
662fa7de7023 201024_05
hgs
parents:
diff changeset
   384
@param aText The text in logical order.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   385
@param aMaxLines
662fa7de7023 201024_05
hgs
parents:
diff changeset
   386
	The maximum number of lines that this text will need to be split into. Must
662fa7de7023 201024_05
hgs
parents:
diff changeset
   387
	be at least 1, but should not be too large, as each potential line takes an
662fa7de7023 201024_05
hgs
parents:
diff changeset
   388
	extra 8 bytes of memory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   389
@param aDirectionality Direction to use.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   390
@return The newly constructed object.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   391
 */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   392
EXPORT_C TBidiText* TBidiText::NewL(const TDesC& aText, TInt aMaxLines,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   393
	TBidiText::TDirectionality aDirectionality)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   394
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   395
	__ASSERT_ALWAYS(0 < aMaxLines, BidiPanic(EBidiPanic_InvalidMaxline));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   396
	const TText* text = aText.Ptr();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   397
	const TInt length = aText.Length();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   398
	TInt linesInOriginalText = NumberOfLines(text, text + length);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   399
	if (aMaxLines < linesInOriginalText)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   400
		aMaxLines = linesInOriginalText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   401
662fa7de7023 201024_05
hgs
parents:
diff changeset
   402
	const TInt arraySize = TBidirectionalState::GenerateBdRunArray(text, length, 0, 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   403
	TBidirectionalState::TRunInfo* runInfoArray = new(ELeave) TBidirectionalState::TRunInfo[arraySize];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   404
	TCleanupItem ci(DeleteTRunInfo, runInfoArray);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   405
	CleanupStack::PushL(ci);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   406
	TBidirectionalState::GenerateBdRunArray(text, length, runInfoArray, arraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   407
	TBidirectionalState state;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   408
	state.ReorderLine(runInfoArray, arraySize, ETrue, ETrue, aDirectionality,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   409
		TChar::EOtherNeutral, TChar::EOtherNeutral);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   410
	TInt compactArraySize = TRunInfoCompact::Convert(0, aText, runInfoArray, arraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   411
662fa7de7023 201024_05
hgs
parents:
diff changeset
   412
	// size of TBidiTextImp class
662fa7de7023 201024_05
hgs
parents:
diff changeset
   413
	TBidiTextImp* me = TBidiTextImp::NewL(length, aMaxLines, compactArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   414
	me->SetRightToLeftDirectionality(aDirectionality != ELeftToRight);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   415
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   416
	TRunInfoCompact::Convert(me->BidiRunArray(), aText, runInfoArray, arraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   417
	CleanupStack::PopAndDestroy(runInfoArray);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   418
662fa7de7023 201024_05
hgs
parents:
diff changeset
   419
	Mem::Copy(me->LogicalText(), text, length * sizeof(TText));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   420
	return me;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   421
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   422
662fa7de7023 201024_05
hgs
parents:
diff changeset
   423
/** Creates a bidirectional text object with directionality determined by the text 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   424
itself. Use this for text that has been obtained from a resource file. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   425
662fa7de7023 201024_05
hgs
parents:
diff changeset
   426
@param aText The text in logical order.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   427
@param aMaxLines The maximum number of lines that this text will need to be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   428
split into. Must be at least 1, but should not be too large, as each potential 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   429
line takes an extra 8 bytes of memory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   430
@return The newly constructed object. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   431
EXPORT_C TBidiText* TBidiText::NewL(const TDesC& aText, TInt aMaxLines)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   432
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   433
	return NewL(aText, aMaxLines, TextDirectionality(aText));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   434
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   435
662fa7de7023 201024_05
hgs
parents:
diff changeset
   436
662fa7de7023 201024_05
hgs
parents:
diff changeset
   437
/** Creates a bidirectional text object with enough room for up to aReservedMaxLength
662fa7de7023 201024_05
hgs
parents:
diff changeset
   438
number of characters. The number of characters that will actually fit (when calling 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   439
SetText()) might be slightly less than aReservedMaxLength, as each change between a 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   440
left-to-right and a right-to-left sub-string (and the other way around) needs about
662fa7de7023 201024_05
hgs
parents:
diff changeset
   441
two characters worth of memory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   442
662fa7de7023 201024_05
hgs
parents:
diff changeset
   443
@param aReservedMaxLength The maximum number of characters.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   444
@param aMaxLines The maximum number of lines that this text will need to be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   445
split into. Must be at least 1, but should not be too large, as each potential 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   446
line takes an extra 8 bytes of memory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   447
@return The newly constructed object. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   448
EXPORT_C TBidiText* TBidiText::NewL(TInt aReservedMaxLength, TInt aMaxLines)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   449
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   450
	__ASSERT_ALWAYS(0 < aReservedMaxLength, BidiPanic(EBidiPanic_InvalidReservedMaxLength));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   451
	__ASSERT_ALWAYS(0 < aMaxLines,          BidiPanic(EBidiPanic_InvalidMaxline));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   452
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   453
	const TInt compactArraySize = 1;	// Always at least one needed
662fa7de7023 201024_05
hgs
parents:
diff changeset
   454
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   455
	TBidiTextImp* me = TBidiTextImp::NewL(aReservedMaxLength, aMaxLines, compactArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   456
	me->SetTextLength(0);	// no text yet, just reserved memory
662fa7de7023 201024_05
hgs
parents:
diff changeset
   457
	return me;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   458
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   459
662fa7de7023 201024_05
hgs
parents:
diff changeset
   460
/** Sets the text of the bidirectional text object with directionality determined 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   461
by the text itself. Use this for text that has been obtained from a resource file. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   462
662fa7de7023 201024_05
hgs
parents:
diff changeset
   463
@param aText The text in logical order.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   464
@return The number of characters that didn't fit in the available buffer.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   465
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   466
EXPORT_C TInt TBidiText::SetText(const TDesC& aText, RRunInfoArray& aRunInfoArray)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   467
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   468
	return SetText(aText, TextDirectionality(aText), aRunInfoArray);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   469
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   470
662fa7de7023 201024_05
hgs
parents:
diff changeset
   471
662fa7de7023 201024_05
hgs
parents:
diff changeset
   472
/** Sets the text of the bidirectional text with directionality determined by
662fa7de7023 201024_05
hgs
parents:
diff changeset
   473
aDirectionality. Use this for text that has come from user input.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   474
662fa7de7023 201024_05
hgs
parents:
diff changeset
   475
@param aText The text in logical order.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   476
@param aDirectionality Direction to use.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   477
@return The number of characters that didn't fit in the available buffer.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   478
@panic Bidi EBidiPanic_RunArrayNull The call to RRunInfoArray::OpenL() has not
662fa7de7023 201024_05
hgs
parents:
diff changeset
   479
been made prior to this call to TBidiText::SetText()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   480
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   481
EXPORT_C TInt TBidiText::SetText(const TDesC& aText,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   482
								 TDirectionality aDirectionality, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   483
								 RRunInfoArray& aRunInfoArray)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   484
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   485
	TBidirectionalState::TRunInfo* const runArray = aRunInfoArray.RunArray();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   486
	__ASSERT_ALWAYS(runArray, BidiPanic(EBidiPanic_RunArrayNull));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   487
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   488
	TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   489
	const TInt maxLines = me->iLines;	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   490
	const TText* text = aText.Ptr();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   491
	TInt length = aText.Length();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   492
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   493
	TInt requiredArraySize = TBidirectionalState::GenerateBdRunArray(text, length, 0, 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   494
	const TInt actualArraySize = aRunInfoArray.iTls->MaxArraySize();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   495
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   496
	if (requiredArraySize > actualArraySize)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   497
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   498
		// Handle the case where we do not have enough space in the run array
662fa7de7023 201024_05
hgs
parents:
diff changeset
   499
		// to cope with the input text. The text will be truncated to ensure
662fa7de7023 201024_05
hgs
parents:
diff changeset
   500
		// we don't overrun the buffer and the number of excess characters 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   501
		// returned as a negative number.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   502
		requiredArraySize = actualArraySize;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   503
		TBidirectionalState::GenerateBdRunArray(text, length, runArray, requiredArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   504
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   505
		length = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   506
		for (TInt index = 0; index < requiredArraySize; index++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   507
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   508
			length += runArray[index].iLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   509
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   510
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   511
	else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   512
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   513
		TBidirectionalState::GenerateBdRunArray(text, length, runArray, requiredArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   514
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   515
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   516
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   517
662fa7de7023 201024_05
hgs
parents:
diff changeset
   518
	TBidirectionalState state;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   519
	state.ReorderLine(runArray, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   520
					  requiredArraySize, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   521
					  ETrue, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   522
					  ETrue, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   523
					  aDirectionality, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   524
					  TChar::EOtherNeutral, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   525
					  TChar::EOtherNeutral);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   526
	const TInt compactArraySize = TRunInfoCompact::Convert(0, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   527
														   aText, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   528
														   runArray, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   529
														   requiredArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   530
662fa7de7023 201024_05
hgs
parents:
diff changeset
   531
	// Calculate number of bytes needed to keep text data
662fa7de7023 201024_05
hgs
parents:
diff changeset
   532
	TInt requiredBytes = sizeof(TText) * (length * 2 + maxLines * 3); // size of text for logical & visual orderings.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   533
	requiredBytes += sizeof(TInt16*) * maxLines;					  // size of line length array
662fa7de7023 201024_05
hgs
parents:
diff changeset
   534
	requiredBytes = (requiredBytes + 3) & 0xFFFFFFFC;				  // alignment
662fa7de7023 201024_05
hgs
parents:
diff changeset
   535
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   536
	TInt textLength = length;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   537
	const TInt excessData = Max(0, requiredBytes - me->AllocatedTextDataBytes());
662fa7de7023 201024_05
hgs
parents:
diff changeset
   538
	TInt excessChars = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   539
	if(excessData)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   540
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   541
		// Calculate how much text data that can be fitted into the available bytes, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   542
		// given the bytes needed for run array data
662fa7de7023 201024_05
hgs
parents:
diff changeset
   543
		excessChars = excessData / (sizeof(TText) * 2);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   544
		textLength -= excessChars;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   545
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   546
	else if (aText.Length() > length)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   547
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   548
		excessChars = aText.Length() - length;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   549
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   550
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   551
	me->SetTextLength(textLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   552
	me->SetRightToLeftDirectionality(aDirectionality != ELeftToRight);			
662fa7de7023 201024_05
hgs
parents:
diff changeset
   553
	me->iVisualOrderedTextLength = -1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   554
	me->iBidiRunArrayLength = static_cast<TUint16>(compactArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   555
662fa7de7023 201024_05
hgs
parents:
diff changeset
   556
	TRunInfoCompact::Convert(me->BidiRunArray(), aText, runArray, requiredArraySize);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   557
	Mem::Copy(me->LogicalText(), text, textLength * sizeof(TText));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   558
662fa7de7023 201024_05
hgs
parents:
diff changeset
   559
	return excessChars;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   560
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   561
662fa7de7023 201024_05
hgs
parents:
diff changeset
   562
/** Sets the character that will be added at the end of the text if the whole text 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   563
cannot fit into the space specified. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   564
662fa7de7023 201024_05
hgs
parents:
diff changeset
   565
@param aTruncateWith The truncation char. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   566
EXPORT_C void TBidiText::SetTruncationChar(TChar aTruncateWith)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   567
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   568
	TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   569
	me->iTruncationCharPlane = static_cast<TUint8>(aTruncateWith >> 16);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   570
	me->iTruncationChar16 = static_cast<TUint16>(aTruncateWith);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   571
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   572
662fa7de7023 201024_05
hgs
parents:
diff changeset
   573
TInt RemoveTrailingSpaces(const MLineBreaker* aBreaker,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   574
	const TText* aInput, TInt aMinPos, TInt aEndPos)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   575
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   576
	// Ignore space characters at the end of the line.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   577
	// Don't bother to ignore spaces made of surrogate pairs:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   578
	// more processing than it's worth.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   579
	TUint dummy1, dummy2;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   580
	while (aEndPos != aMinPos && MLineBreaker::ESpLineBreakClass
662fa7de7023 201024_05
hgs
parents:
diff changeset
   581
		== aBreaker->LineBreakClass(aInput[aEndPos - 1], dummy1, dummy2))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   582
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   583
		--aEndPos;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   584
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   585
	return aEndPos;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   586
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   587
662fa7de7023 201024_05
hgs
parents:
diff changeset
   588
/** Prepares the visually-ordered text according to the wrapping width and font
662fa7de7023 201024_05
hgs
parents:
diff changeset
   589
specified. Text cannot be drawn until this has been done.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   590
@param aWrappingWidth
662fa7de7023 201024_05
hgs
parents:
diff changeset
   591
	The maximum width of the text in pixels. Note that this distance should be
662fa7de7023 201024_05
hgs
parents:
diff changeset
   592
	slightly less than the available width to allow for characters such as "W"
662fa7de7023 201024_05
hgs
parents:
diff changeset
   593
	which can have side-bearings that leak into the margins.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   594
@param aFont The font that will provide the character metrics.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   595
@param aBreaker
662fa7de7023 201024_05
hgs
parents:
diff changeset
   596
	An object for breaking the lines. May be NULL for default behaviour.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   597
@param aMaxLines
662fa7de7023 201024_05
hgs
parents:
diff changeset
   598
	Number of lines to restrict wrapping to. The truncation character will be
662fa7de7023 201024_05
hgs
parents:
diff changeset
   599
	used if the text is too long for this number of lines. The number of lines
662fa7de7023 201024_05
hgs
parents:
diff changeset
   600
	wrapped to may not be greater than the figure passed to NewL.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   601
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   602
EXPORT_C void TBidiText::WrapText(TInt aWrappingWidth, const CFont& aFont,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   603
	const MLineBreaker* aBreaker, TInt aMaxLines)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   604
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   605
	TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   606
	me->iWrappingWidth = aWrappingWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   607
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   608
	TInt16* lineWidths = me->LineWidthArray();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   609
	TText* output = me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   610
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   611
	TInt numLines = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   612
	DoWrapText(aWrappingWidth, aFont, aBreaker, aMaxLines, output, numLines, lineWidths);	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   613
	me->iVisualOrderedTextLength = output - me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   614
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   615
662fa7de7023 201024_05
hgs
parents:
diff changeset
   616
/** Calculate the minimum size needed to draw the current text, given the specified
662fa7de7023 201024_05
hgs
parents:
diff changeset
   617
wrapping width, font, and line gap. Calling this method will not rewrap the object's
662fa7de7023 201024_05
hgs
parents:
diff changeset
   618
text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   619
662fa7de7023 201024_05
hgs
parents:
diff changeset
   620
@param aWrappingWidth
662fa7de7023 201024_05
hgs
parents:
diff changeset
   621
	The maximum width of the text in pixels. Note that this distance should be
662fa7de7023 201024_05
hgs
parents:
diff changeset
   622
	slightly less than the available width to allow for characters such as "W"
662fa7de7023 201024_05
hgs
parents:
diff changeset
   623
	which can have side-bearings that leak into the margins.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   624
@param aFont The font that will provide the character metrics.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   625
@param aLineGap The number of empty pixels between two lines of text. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   626
	Note that this is not the same as the baseline spacing, which is the font 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   627
	height plus the line gap.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   628
@param aMaxLines
662fa7de7023 201024_05
hgs
parents:
diff changeset
   629
	Number of lines to restrict wrapping to. The truncation character will be
662fa7de7023 201024_05
hgs
parents:
diff changeset
   630
	used if the text is too long for this number of lines. The number of lines
662fa7de7023 201024_05
hgs
parents:
diff changeset
   631
	wrapped to may be greater than the figure passed to NewL, and that figure
662fa7de7023 201024_05
hgs
parents:
diff changeset
   632
	will be used if the number of lines is specified as -1. If 0 (zero) is specified
662fa7de7023 201024_05
hgs
parents:
diff changeset
   633
	no limit is applied.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   634
@param aBreaker
662fa7de7023 201024_05
hgs
parents:
diff changeset
   635
	An object for breaking the lines. May be NULL for default behaviour.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   636
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   637
EXPORT_C TSize TBidiText::MinimumSize(TInt aWrappingWidth, const CFont& aFont, TInt aLineGap, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   638
									TInt aMaxLines, const MLineBreaker* aBreaker) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   639
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   640
	__ASSERT_ALWAYS(0  <= aWrappingWidth, BidiPanic(EBidiPanic_InvalidWrappingWidth));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   641
	__ASSERT_ALWAYS(0  <=  aLineGap,       BidiPanic(EBidiPanic_InvalidLineGap));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   642
	__ASSERT_ALWAYS(-1 <= aMaxLines,      BidiPanic(EBidiPanic_InvalidMaxline));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   643
662fa7de7023 201024_05
hgs
parents:
diff changeset
   644
	TInt numLines = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   645
	TText* output = NULL;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   646
	const TInt minWidth = DoWrapText(aWrappingWidth, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   647
									 aFont, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   648
									 aBreaker, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   649
									 (aMaxLines = 0 ? KMaxTInt : aMaxLines), 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   650
									 output, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   651
									 numLines, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   652
									 NULL);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   653
	const TInt minHeight = (aFont.FontMaxHeight() + aLineGap) * numLines - aLineGap; 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   654
	return TSize(minWidth, minHeight);	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   655
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   656
662fa7de7023 201024_05
hgs
parents:
diff changeset
   657
662fa7de7023 201024_05
hgs
parents:
diff changeset
   658
TInt TBidiText::DoWrapText(TInt aWrappingWidth, const CFont& aFont, const MLineBreaker* aBreaker, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   659
	TInt aMaxLines, TText*& aOutputText, TInt& aNumLines, TInt16* aLineWidthArray) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   660
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   661
	MLineBreaker defaultBreaker;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   662
	if (!aBreaker)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   663
		aBreaker = &defaultBreaker;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   664
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   665
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   666
	if (me->iLines < aMaxLines)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   667
		aMaxLines = me->iLines;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   668
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   669
	const TRunInfoCompact* runArray = me->BidiRunArray();	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   670
	const TRunInfoCompact* runArrayEnd = runArray + me->iBidiRunArrayLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   671
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   672
	const TText* input = me->LogicalText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   673
	const TInt inputLength = me->TextLength();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   674
	TPtrC textDes(input, inputLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   675
	const TText* output = me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   676
662fa7de7023 201024_05
hgs
parents:
diff changeset
   677
	TRunInfoCompact::TReorderingContext context;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   678
	context.iSource = input;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   679
	context.iTruncation = 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   680
	context.iJoinsAtEnd = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   681
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   682
	TInt start = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   683
	CFont::TMeasureTextInput measureInput;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   684
	measureInput.iMaxAdvance = aWrappingWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   685
	measureInput.iEndInputChar = FindEndOfThisLine(input, input + inputLength) - input;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   686
	CFont::TMeasureTextOutput measureOutput;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   687
	TBool truncated;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   688
662fa7de7023 201024_05
hgs
parents:
diff changeset
   689
	TInt widestLineWidth = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   690
	TBool bLastLine = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   691
	for (aNumLines = 0; aNumLines != aMaxLines && start < inputLength; ++aNumLines)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   692
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   693
		truncated=EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   694
		context.iJoinsAtStart = context.iJoinsAtEnd;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   695
		if(aNumLines != 0 && aOutputText)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   696
			*(aOutputText++) = KLineSeparator;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   697
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   698
		measureInput.iStartInputChar = start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   699
		TInt advance = aFont.MeasureText(textDes, &measureInput, &measureOutput);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   700
		TInt breakPos = measureOutput.iChars;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   701
		TInt endOfLine = breakPos;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   702
		// truncationCharWidth is the width of any truncation character on this
662fa7de7023 201024_05
hgs
parents:
diff changeset
   703
		// line only.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   704
		TInt truncationCharWidth = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   705
		if (endOfLine == measureInput.iEndInputChar)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   706
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   707
			//handle the dangling lines here
662fa7de7023 201024_05
hgs
parents:
diff changeset
   708
			TInt sizeLineBreak = SizeLineBreak(input + endOfLine, input + inputLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   709
			if((measureInput.iEndInputChar < inputLength - sizeLineBreak) && (aNumLines == aMaxLines - 1))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   710
				bLastLine = ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   711
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   712
		else if (aNumLines == aMaxLines - 1)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   713
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   714
			bLastLine = ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   715
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   716
		else 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   717
			{ // Not last line, so find a legal line break.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   718
			aBreaker->GetLineBreak(textDes, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   719
								   start + 1, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   720
								   measureOutput.iChars, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   721
								   EFalse, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   722
								   0, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   723
								   breakPos, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   724
								   endOfLine);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   725
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   726
662fa7de7023 201024_05
hgs
parents:
diff changeset
   727
		if (bLastLine)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   728
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   729
			// Last line, so re-measure leaving enough room for
662fa7de7023 201024_05
hgs
parents:
diff changeset
   730
			// truncation character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   731
			context.iTruncation = me->TruncationChar();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   732
			truncationCharWidth = aFont.CharWidthInPixels(context.iTruncation);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   733
			measureInput.iMaxAdvance = aWrappingWidth - truncationCharWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   734
			advance = aFont.MeasureText(textDes, &measureInput, &measureOutput) + truncationCharWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   735
			breakPos = RemoveTrailingSpaces(aBreaker, input, start, measureOutput.iChars);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   736
			truncated=ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   737
			bLastLine = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   738
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   739
662fa7de7023 201024_05
hgs
parents:
diff changeset
   740
		// if the break position has changed, we need to remeasure
662fa7de7023 201024_05
hgs
parents:
diff changeset
   741
		if (breakPos != measureOutput.iChars)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   742
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   743
			const TInt oldEnd = measureInput.iEndInputChar;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   744
			measureInput.iEndInputChar = breakPos;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   745
			advance = aFont.MeasureText(textDes, &measureInput, &measureOutput) + truncationCharWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   746
			measureInput.iEndInputChar = oldEnd;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   747
			truncated=ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   748
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   749
662fa7de7023 201024_05
hgs
parents:
diff changeset
   750
		//width may be greater than advance
662fa7de7023 201024_05
hgs
parents:
diff changeset
   751
		advance = Max(advance,measureOutput.iBounds.Width());
662fa7de7023 201024_05
hgs
parents:
diff changeset
   752
662fa7de7023 201024_05
hgs
parents:
diff changeset
   753
		if(widestLineWidth < advance)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   754
			widestLineWidth = advance;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   755
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   756
		if(aLineWidthArray)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   757
			*(aLineWidthArray++) = static_cast<TInt16>(advance);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   758
662fa7de7023 201024_05
hgs
parents:
diff changeset
   759
		context.iStart = start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   760
		context.iEnd = breakPos;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   761
		if (truncated)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   762
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   763
			context.iJoinsAtEnd = breakPos < inputLength?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   764
				TRunInfoCompact::JoinBefore(input, breakPos) : EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   765
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   766
		else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   767
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   768
			context.iJoinsAtEnd = endOfLine < inputLength?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   769
				TRunInfoCompact::JoinBefore(input, endOfLine) : EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   770
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   771
		if (aOutputText)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   772
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   773
			for (const TRunInfoCompact* p = runArray; p != runArrayEnd; ++p)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   774
				aOutputText = p->Reorder(aOutputText, context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   775
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   776
		// Set 'start' to the beginning of the next line...
662fa7de7023 201024_05
hgs
parents:
diff changeset
   777
		start = endOfLine;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   778
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   779
		// ...move it past any line break...
662fa7de7023 201024_05
hgs
parents:
diff changeset
   780
		const TInt sizeOfLineBreak = SizeLineBreak(input + start, input + inputLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   781
		if (sizeOfLineBreak != 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   782
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   783
			start += sizeOfLineBreak;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   784
			// ...and find the end of this next line.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   785
			const TText* endLine = FindEndOfThisLine(input + start, input + inputLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   786
			measureInput.iEndInputChar = endLine - input;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   787
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   788
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   789
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   790
	return widestLineWidth;	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   791
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   792
662fa7de7023 201024_05
hgs
parents:
diff changeset
   793
662fa7de7023 201024_05
hgs
parents:
diff changeset
   794
/** Prepares the visually-ordered text according to the wrapping width and font 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   795
specified. Text cannot be drawn until this has been done. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   796
662fa7de7023 201024_05
hgs
parents:
diff changeset
   797
@param aWrappingWidth The maximum width of the text in pixels. Note that this 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   798
distance should be slightly less than the available width to allow for characters 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   799
such as "W" which can have side-bearings that leak into the margins.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   800
@param aFont The font that will provide the character metrics.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   801
@param aBreaker An object for breaking the lines. May be NULL for default behaviour. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   802
EXPORT_C void TBidiText::WrapText(TInt aWrappingWidth, const CFont& aFont,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   803
	const MLineBreaker* aBreaker)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   804
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   805
	WrapText(aWrappingWidth, aFont, aBreaker, KMaxTInt);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   806
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   807
662fa7de7023 201024_05
hgs
parents:
diff changeset
   808
/** Returns the original logically-ordered text supplied in the constructor. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   809
@return The original logically-ordered text supplied in the constructor. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   810
EXPORT_C TPtrC TBidiText::Text() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   811
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   812
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   813
	const TText* text = me->LogicalText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   814
	return TPtrC(text, me->TextLength());
662fa7de7023 201024_05
hgs
parents:
diff changeset
   815
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   816
662fa7de7023 201024_05
hgs
parents:
diff changeset
   817
/** Returns the text as prepared for display, provided that WrapText has been called. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   818
If WrapText has not been called, a panic will result. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   819
662fa7de7023 201024_05
hgs
parents:
diff changeset
   820
@return The text as prepared for display */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   821
EXPORT_C TPtrC TBidiText::DisplayText() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   822
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   823
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   824
	__ASSERT_ALWAYS(me->iVisualOrderedTextLength >= 0, BidiPanic(EBidiPanic_InvalidVisualOrderedTextLength));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   825
	const TText* text = me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   826
	return TPtrC(text, me->iVisualOrderedTextLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   827
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   828
662fa7de7023 201024_05
hgs
parents:
diff changeset
   829
/** Returns the wrapping width previously supplied to WrapText. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   830
662fa7de7023 201024_05
hgs
parents:
diff changeset
   831
@return The wrapping. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   832
EXPORT_C TInt TBidiText::WrappingWidth() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   833
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   834
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   835
	return me->iWrappingWidth;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   836
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   837
662fa7de7023 201024_05
hgs
parents:
diff changeset
   838
/** Returns the directionality of the text. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   839
662fa7de7023 201024_05
hgs
parents:
diff changeset
   840
@return The directionality. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   841
EXPORT_C TBidiText::TDirectionality TBidiText::Directionality() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   842
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   843
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   844
	return me->HasRightToLeftDirectionality() ? ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   845
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   846
662fa7de7023 201024_05
hgs
parents:
diff changeset
   847
/** Returns the truncation character used. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   848
662fa7de7023 201024_05
hgs
parents:
diff changeset
   849
@return The truncation character. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   850
EXPORT_C TChar TBidiText::TruncationChar() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   851
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   852
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   853
	return me->TruncationChar();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   854
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   855
662fa7de7023 201024_05
hgs
parents:
diff changeset
   856
/** Reports the number of lines in the text to be drawn.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   857
662fa7de7023 201024_05
hgs
parents:
diff changeset
   858
WrapText must have been called already.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   859
@return
662fa7de7023 201024_05
hgs
parents:
diff changeset
   860
	The number of lines in the text which would be drawn by DrawText.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   861
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   862
EXPORT_C TInt TBidiText::NumberOfLinesInDisplayText() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   863
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   864
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   865
	if (me->iVisualOrderedTextLength <0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   866
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   867
		return 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   868
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   869
	const TText* text = me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   870
	const TText* textEnd = text + me->iVisualOrderedTextLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   871
	return NumberOfLines(text, textEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   872
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   873
662fa7de7023 201024_05
hgs
parents:
diff changeset
   874
/** Returns the text as prepared for display, provided that WrapText has been called. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   875
If WrapText has not been called, a panic will result. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   876
@param aLine Line number to retrieve.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   877
@param aWidth Returns the width in pixels of the line retrieved.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   878
@return The text as prepared for display. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   879
EXPORT_C TPtrC TBidiText::LineOfDisplayText(TInt aLine, TInt& aWidthInPixels) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   880
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   881
	const TBidiTextImp* me = TBidiTextImp::Imp(this);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   882
	__ASSERT_ALWAYS(me->iVisualOrderedTextLength >= 0, BidiPanic(EBidiPanic_InvalidVisualOrderedTextLength));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   883
	__ASSERT_ALWAYS(0 <= aLine && aLine < me->iLines, BidiPanic(EBidiPanic_InvalidLineNumber));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   884
	aWidthInPixels = me->LineWidthArray()[aLine];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   885
	const TText* text = me->VisualText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   886
	const TText* textEnd = text + me->iVisualOrderedTextLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   887
	for (; aLine != 0; --aLine)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   888
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   889
		text = FindEndOfThisLine(text, textEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   890
		text += SizeLineBreak(text, textEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   891
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   892
	const TText* endOfLine = FindEndOfThisLine(text, textEnd);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   893
	return TPtrC(text, endOfLine - text);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   894
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   895
662fa7de7023 201024_05
hgs
parents:
diff changeset
   896
/** Draws all of the text. WrapText must have been called already. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   897
662fa7de7023 201024_05
hgs
parents:
diff changeset
   898
@param aGc The graphics context to draw the text to. The graphics context's 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   899
font is assumed to have been set to the same font that was passed to the previous 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   900
call to WrapText.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   901
@param aLeft The left extreme of the baseline. Note that this should not be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   902
at the very edge of the available space, or characters such as "W" with left 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   903
side bearings may be truncated.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   904
@param aBaseLineSpacing The spacing between each line. If 0, only the first 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   905
line is drawn.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   906
@param aAlignment How to position the text horizontally. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   907
EXPORT_C void TBidiText::DrawText(CGraphicsContext& aGc, const TPoint& aLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   908
	TInt aBaseLineSpacing, CGraphicsContext::TTextAlign aAlignment) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   909
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   910
	TPoint origin;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   911
	origin.iY = aLeft.iY;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   912
	TInt lines = aBaseLineSpacing == 0? 1 : NumberOfLinesInDisplayText();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   913
	TInt wrappingWidth = WrappingWidth();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   914
	for (TInt i = 0; i != lines; ++i)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   915
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   916
		TInt width;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   917
		TPtrC textLine = LineOfDisplayText(i, width);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   918
		origin.iX = aLeft.iX;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   919
		if (aAlignment != CGraphicsContext::ELeft)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   920
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   921
			TInt excess = wrappingWidth - width;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   922
			origin.iX += aAlignment != CGraphicsContext::ECenter?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   923
				excess : excess >> 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   924
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   925
		aGc.DrawText(textLine, origin);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   926
		origin.iY += aBaseLineSpacing;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   927
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   928
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   929
662fa7de7023 201024_05
hgs
parents:
diff changeset
   930
/** Draws all of the text. Alignment is taken from the directionality of the text. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   931
WrapText must have been called already. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   932
662fa7de7023 201024_05
hgs
parents:
diff changeset
   933
@param aGc The graphics context to draw the text to. The graphics context's 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   934
font is assumed to have been set to the same font that was passed to the previous 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   935
call to WrapText.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   936
@param aLeft The left extreme of the baseline. Note that this should not be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   937
at the very edge of the available space, or characters such as "W" with left 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   938
side bearings may be truncated.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   939
@param aBaseLineSpacing The spacing between each line. If 0, only the first 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   940
line is drawn. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   941
EXPORT_C void TBidiText::DrawText(CGraphicsContext& aGc, const TPoint& aLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   942
	TInt aBaseLineSpacing) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   943
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   944
	DrawText(aGc, aLeft, aBaseLineSpacing,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   945
		Directionality() == ELeftToRight?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   946
		CGraphicsContext::ELeft : CGraphicsContext::ERight);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   947
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   948
662fa7de7023 201024_05
hgs
parents:
diff changeset
   949
/** Draws the first line of the text. WrapText must have been called already. Alignment 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   950
is taken from the directionality of the text. 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   951
662fa7de7023 201024_05
hgs
parents:
diff changeset
   952
@param aGc The graphics context to draw the text to. The graphics context's 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   953
font is assumed to have been set to the same font that was passed to the previous 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   954
call to WrapText.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   955
@param aLeft The left extreme of the baseline. Note that this should not be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   956
at the very edge of the available space, or characters such as "W" with left 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   957
side bearings may be truncated. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   958
EXPORT_C void TBidiText::DrawText(CGraphicsContext& aGc, const TPoint& aLeft) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
   959
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   960
	DrawText(aGc, aLeft, 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   961
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   962