graphicsdeviceinterface/gdi/sgdi/BidiVisual.cpp
changeset 183 6a1564a2f3e6
parent 168 2bd88482bfe5
child 194 18f84489a694
equal deleted inserted replaced
168:2bd88482bfe5 183:6a1564a2f3e6
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "BidiVisual.h"
       
    17 #include "BidiCopy.h"
       
    18 #include "BidiTextImp.h"
       
    19 #include "BidiCompact.h"
       
    20 
       
    21 extern void BidiPanic(TInt aError);
       
    22 
       
    23 /** Construct the class with a full paragraph of text and the run array to be used 
       
    24 to hold all the runs. 
       
    25 
       
    26 @param aText The text to be analyzed. This must not be de-allocated until 
       
    27 all operations on it through this class have been completed.
       
    28 @param aRightToLeft Paragraph directionality.
       
    29 @param aRunInfoArray The array to be used to hold the run information. This 
       
    30 must not be de-allocated until all operations on it through this class have 
       
    31 been completed. Ownership is not passed.
       
    32 @param aRunInfoLength The number of TRunInfo<\code> objects in aRunInfoArray. */
       
    33 EXPORT_C TBidiLogicalToVisual::TBidiLogicalToVisual(
       
    34 	const TDesC& aText,
       
    35 	TBool aRightToLeft,
       
    36 	TBidirectionalState::TRunInfo* aRunInfoArray,
       
    37 	TInt aRunInfoLength)
       
    38 	: iText(aText), iRightToLeft(aRightToLeft),
       
    39 	iRunInfoArray(aRunInfoArray), iRunInfoArrayLength(aRunInfoLength), iRuns(aRunInfoLength)
       
    40 	{
       
    41 	}
       
    42 
       
    43 /** Construct the class with a full paragraph of text and the run array to be used 
       
    44 to hold all the runs. Directionality is taken as the implicit directionality 
       
    45 of the text passed. 
       
    46 
       
    47 @param aText The text to be analyzed. This must not be de-allocated until 
       
    48 all operations on it through this class have been completed.
       
    49 @param aRunInfoArray The array to be used to hold the run information. This 
       
    50 must not be de-allocated until all operations on it through this class have 
       
    51 been completed. Ownership is not passed.
       
    52 @param aRunInfoLength The number of TRunInfo objects in aRunInfoArray. */
       
    53 EXPORT_C TBidiLogicalToVisual::TBidiLogicalToVisual(
       
    54 	const TDesC& aText,
       
    55 	TBidirectionalState::TRunInfo* aRunInfoArray,
       
    56 	TInt aRunInfoLength)
       
    57 	: iText(aText),
       
    58 	iRunInfoArray(aRunInfoArray), iRunInfoArrayLength(aRunInfoLength), iRuns(aRunInfoLength)
       
    59 	{
       
    60 	iRightToLeft = BidiCopy::ImplicitDirectionalityIsRightToLeft(
       
    61 		aText.Ptr(), aText.Length(), 0);
       
    62 	}
       
    63 
       
    64 /** Process the text. This must be called before any call to GetVisualLine. 
       
    65 
       
    66 @return The number of runs that were or would be required to reorder the complete 
       
    67 line. If this is less than the value passed into the constructor as aRunInfoLength, 
       
    68 the full text will not be able to be Reordered. */
       
    69 EXPORT_C TInt TBidiLogicalToVisual::Reorder()
       
    70 	{
       
    71 	TInt required = TBidirectionalState::GenerateBdRunArray(
       
    72 		iText.Ptr(), iText.Length(), iRunInfoArray, iRunInfoArrayLength);
       
    73 	iRuns = Min(required, iRunInfoArrayLength);
       
    74 	TBidirectionalState state;
       
    75 	state.ReorderLine(iRunInfoArray, iRuns, ETrue, ETrue, iRightToLeft,
       
    76 		TChar::EOtherNeutral, TChar::EOtherNeutral);
       
    77 	return required;
       
    78 	}
       
    79 
       
    80 /** Get a line of visually ordered text. 
       
    81 
       
    82 @param aLine Line of text in visual order. There must be aEnd - aStart + 4 
       
    83 characters available in the buffer. Only characters within the range aStart 
       
    84 to aEnd, plus perhaps a truncation character and up to two zero-width joiners 
       
    85 will be present in the string at the end.
       
    86 @param aStart The first character in the text that is to be on the line.
       
    87 @param aEnd One plus the last character in the test that is to be on the line.
       
    88 @param aTruncationChar The character to mark the end of the text, if appropriate, 
       
    89 or 0xFFFF if no truncation character is to be used. */ 
       
    90 EXPORT_C void TBidiLogicalToVisual::GetVisualLine(TDes& aLine,
       
    91 	TInt aStart, TInt aEnd, TChar aTruncationChar)
       
    92 	{
       
    93 	__ASSERT_ALWAYS(aEnd - aStart + KMinCharAvailable <= aLine.MaxLength(), BidiPanic(KErrArgument));
       
    94 
       
    95 	if(iText.Length() == 0)
       
    96 		{
       
    97 		aLine.Zero();
       
    98 		return;//We can't do anything with iText, if its length is 0.
       
    99 		}
       
   100 
       
   101 	TRunInfoCompact::TReorderingContext context;
       
   102 
       
   103 	const TText* input = &iText[0];
       
   104 	context.iStart = aStart;
       
   105 	context.iEnd = aEnd;
       
   106 	context.iTruncation = aTruncationChar;
       
   107 	context.iSource = input;
       
   108 	context.iJoinsAtStart = TRunInfoCompact::JoinBefore(input, aStart);
       
   109 	context.iJoinsAtEnd = aEnd < iText.Length() ? TRunInfoCompact::JoinBefore(input, aEnd) : EFalse;
       
   110 
       
   111 	aLine.FillZ(1);
       
   112 	TText* output = &aLine[0];
       
   113 	TText* outputStart = output;
       
   114 	TBidirectionalState::TRunInfo* endInfo = iRunInfoArray + iRuns;
       
   115 	for (TBidirectionalState::TRunInfo* currentInfo = iRunInfoArray;
       
   116 		currentInfo != endInfo; ++currentInfo)
       
   117 		{
       
   118 		TRunInfoCompact info(currentInfo->iStart,
       
   119 			currentInfo->iLength, currentInfo->iDirection);
       
   120 		output = info.Reorder(output, context);
       
   121 		}
       
   122 	aLine.SetLength(output - outputStart);
       
   123 	}