www.pudn.com > mmi.rar > BIDIProcessDataTypes.c
/*****************************************************************************
* Copyright Statement:
* --------------------
* This software is protected by Copyright and the information contained
* herein is confidential. The software may not be copied and the information
* contained herein may not be used or disclosed except with the written
* permission of MediaTek Inc. (C) 2005
*
* BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
* NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
* SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
* BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
* LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
* WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
* LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
* RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
* THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/
/*****************************************************************************
*
* Filename:
* ---------
* bidiprocessdatatypes.c
*
* Project:
* --------
* Maui_Software
*
* Description:
* ------------
* bidirectional algorithm engine
*
*
* Author:
* -------
* -------
*
*============================================================================
* HISTORY
* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*------------------------------------------------------------------------------
* removed!
*
*------------------------------------------------------------------------------
* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
*============================================================================
*****************************************************************************/
/*
* Copyright Notice
* ?2002 - 2003, Pixtel Communications, Inc., 1489 43rd Ave. W.,
* Vancouver, B.C. V6M 4K8 Canada. All Rights Reserved.
* (It is illegal to remove this copyright notice from this software or any
* portion of it)
*/
/**************************************************************
FILENAME : BIDIProcessDataTypes.c
PURPOSE : Main functions of Rule L1 to L4 of BIDI Algorithm
REMARKS : nil
AUTHOR : Vijay/Bilal
DATE : Aug-23-2004
**************************************************************/
#include "BidiDef.h"
#include "BidiProt.h"
/* START TARUN PMT 20041015 */
extern U8 input_types[]; /* source array for storing the direction codes of the input string */
extern U8 input_levels[]; /* This global contains all the embedding levels */
extern U8 dest_levels[]; /* destitnation array for processed levels */
extern U8 dest_types[]; /* Destination array for storing the direction codes of the input string */
/* END TARUN PMT */
/****************************************************************************
Returns BIDI_L or BIDI_R depends on the embedding level & take embeddings levels as parametre
Returns BIDI_R if level is odd
Returns BIDI_L if level is Even
*****************************************************************************/
#define TOKEN_FOR_LEVEL(x) ((x & 1)? BIDI_R:BIDI_L)
/**************************************************************
Rule:X9
Removes the explicit codes & calculates length of the remaining text & assigns it to textLength.
it modifies the global data structure textLength
It also removes any BN(ParaGraph) delimiter
******************************************************************/
/*****************************************************************************
* FUNCTION
* delete_explicit_direction_codes
* DESCRIPTION
*
* PARAMETERS
* inputTypes [?]
* inputLen [IN]
* all_embeddings_level [?]
* destLevels [?]
* destTypes [?]
* RETURNS
*
*****************************************************************************/
U16 delete_explicit_direction_codes(
U8 *inputTypes,
U16 inputLen,
U8 *all_embeddings_level,
U8 *destLevels,
U8 *destTypes)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 iCount = 0, jCount = 0;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
while (iCount < inputLen)
{
U16 code;
//START Changed by Yogesh 20041224
//START TARUN PMT 20041015
code = inputTypes[iCount];
//code=input_types[iCount];
//END TARUN PMT
if (!((code == RLE) || (code == LRE) || (code == RLO) || (code == LRO) || (code == PDF) || (code == BN)))
{ /* checking for the presence of RLE,RLO,LRE,LRO,PDF,BN */
/* dest_levels[jCount]=dest_levels[iCount]; */
destLevels[jCount] = destLevels[iCount];
all_embeddings_level[jCount] = all_embeddings_level[iCount];
/* dest_types[jCount]=dest_types[iCount]; */
destTypes[jCount] = destTypes[iCount];
/* END Changed by Yogesh 20041224 */
jCount++;
}
iCount++;
}
return jCount; /* Returns length of the textLength when RLE,RLO,PDF,LRE,BN,LRE are removed */
}
/*********************End of Rule X9*****************************************/
/********************************************************************************
Rule:X10
Calculates the sor(start of run),eor(end of the run) & number of the run levels.
it works with one level at a time. All w1-w7 rules are coded here.
**********************************************************************************/
/*****************************************************************************
* FUNCTION
* get_run_level
* DESCRIPTION
*
* PARAMETERS
* inputLen [IN]
* paragraphEmbeddingLevel [IN]
* destLevels [?]
* destTypes [?]
* RETURNS
* void
*****************************************************************************/
void get_run_level(U16 inputLen, U8 paragraphEmbeddingLevel, U8 *destLevels, U8 *destTypes)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U8 lastLevel, calLevel, currentLevel;
U8 calType, lastType;
U16 begin = 0, range;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
lastLevel = paragraphEmbeddingLevel; /* At start we put to equal paraGraphembeddingLevel */
while (begin < inputLen) /* checking for length */
{
//START Changed by Yogesh 20041224
//currentLevel=dest_levels[begin];
currentLevel = destLevels[begin];
lastType = TOKEN_FOR_LEVEL(GETMAX(currentLevel, lastLevel)); /* calculation of sor */
range = begin + 1; /* number of characters at the same level */
// for(;begin= begin; jCount--)
{
U16 temp = dest_types[jCount];
if ((temp == BIDI_R) || (temp == BIDI_L) || (temp == AL) || (temp == sor))
{
if (temp == AL)
{
//START Changed by Yogesh 20041228
//dest_types[jCount]=AL;
dest_types[iCount] = BIDI_L;
/* END Changed by Yogesh 20041228 */
}
break;
}
}
}
}
/***************************************************************************
Rule W3
Replace all ALs to BIDI_R.
*******************************************************************************/
for (iCount = begin; iCount < range; iCount++)
{
if (dest_types[iCount] == AL)
{
dest_types[iCount] = BIDI_R;
}
}
/***************************************************************************
Rule W4
Change ES(Eurpoian seperator) to EN between two EN,s.
CS(common seperator) between two numbers of the same type changes to that type.
First & last token will not play part in Rule
*******************************************************************************/
for (jCount = begin + 1; jCount < range - 1; jCount++)
{
if (dest_types[jCount] == CS || dest_types[jCount] == ES)
{
U8 lastToken = dest_types[jCount - 1];
U8 nextToken = dest_types[jCount + 1];
if ((dest_types[jCount] == ES || dest_types[jCount] == CS) && lastToken == EN && nextToken == EN)
{
dest_types[jCount] = EN;
}
else if (dest_types[jCount] == CS && lastToken == nextToken && lastToken == AN)
{
dest_types[jCount] = lastToken;
}
}
}
/***************************************************************************
Rule W5
Change sequence of ET(Eurpoian Terminator) adjacent to EN to all EN,s.
*******************************************************************************/
for (iCount = begin; iCount < range; ++iCount)
{
if (dest_types[iCount] == ET) /* get end of sequence */
{
U8 temp;
//START Changed by Yogesh 20041224
// U8 validToken[]={ET};
U8 validToken[1] = {ET};
U16 carryStart = iCount;
//Changed by Yogesh on Bilal suggestion 20040904
// U16 varRunRate = get_run_rate(dest_types,carryStart, range, validToken,4);
U16 varRunRate = get_run_rate(dest_types, carryStart, range, validToken, 1);
/* END Changed by Yogesh 20041224 */
if (carryStart == begin) /* check values at ends of sequence */
{
temp = sor;
}
else
{
temp = dest_types[carryStart - 1];
}
if (temp != EN)
{
if (varRunRate == range)
{
temp = eor;
}
else
{
temp = dest_types[varRunRate];
}
}
if (temp == EN)
{
setTokens(dest_types, carryStart, varRunRate, EN);
}
iCount = varRunRate;
}
}
/*********************************************************************************************
RuleW6:change remaining teriminators into neutrals
*********************************************************************************************/
iCount = begin;
while (iCount < range)
{
U8 temp = dest_types[iCount];
if (temp == CS || temp == ET || temp == ES)
{
dest_types[iCount] = ON;
}
/* Changed by Yogesh on Bilal suggestion 20040830 */
iCount++;
}
/***************************************************************************
Rule W7
Find the EN & go back till u find AL,BIDI_R,BIDI_L,sor,if u find BIDI_L change EN to AL
*******************************************************************************/
for (iCount = begin; iCount < range; iCount++)
{
U8 tempToken = dest_types[iCount];
if (tempToken == EN)
{
for (jCount = iCount - 1; jCount >= begin; jCount--)
{
U8 temp = dest_types[jCount];
if ((temp == BIDI_R) || (temp == BIDI_L) || (temp == AL) || (temp == sor))
{
if (temp == BIDI_L)
{
/* dest_types[jCount]=BIDI_L; START Yogesh 20041101 */
dest_types[iCount] = BIDI_L; /* START Yogesh 20041101 */
}
break;
}
}
}
}
}
/**********************************************************************************************
used to find a particular sequence & returns immediate next index following token
***********************************************************************************************/
/*****************************************************************************
* FUNCTION
* get_run_rate
* DESCRIPTION
*
* PARAMETERS
* dest_types [?]
* base [IN]
* rate [IN]
* correctType [?]
* length [IN]
* RETURNS
*
*****************************************************************************/
U16 get_run_rate(U8 *dest_types, U16 base, U16 rate, U8 *correctType, U16 length) /* return the base if match is not found */
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 iCount;
pBOOL bFlag = FALSE;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
--base; /* check with vijay */
while (++base < rate)
{
U8 temp = dest_types[base];
bFlag = FALSE;
for (iCount = 0; iCount < length; ++iCount)
{
if (temp == correctType[iCount])
{
bFlag = TRUE;
break;
}
}
if (bFlag)
{
continue;
}
/* can't find a match in correctType */
return base;
}
return rate;
}
/****************************************************************************************************
set new Token types
****************************************************************************************************/
/*****************************************************************************
* FUNCTION
* setTokens
* DESCRIPTION
*
* PARAMETERS
* dest_types [?]
* begin [IN]
* range [IN]
* newType [IN]
* RETURNS
* void
*****************************************************************************/
void setTokens(U8 *dest_types, U16 begin, U16 range, U8 newType) /* check */
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
while (begin < range)
{
dest_types[begin] = newType;
begin++;
}
}
/*************************************************************************************************
Rule N1 & N2
Processes the Neutral Types
**************************************************************************************************/
/*****************************************************************************
* FUNCTION
* processNeutralTokens
* DESCRIPTION
*
* PARAMETERS
* begin [IN]
* range [IN]
* currentLevel [IN]
* sor [IN]
* eor [IN]
* dest_types [?]
* RETURNS
* void
*****************************************************************************/
void processNeutralTokens(U16 begin, U16 range, U16 currentLevel, U8 sor, U8 eor, U8 *dest_types)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U16 i;
// on entry, only these tokens are checked in destTokenTypes
//Changed by Yogesh on Bilal suggestion 20040904
//U16 validToken[]= {BIDI_L, BIDI_R, EN, AN, BIDI_B, S, WS, ON};
U8 validToken[] = {BIDI_B, S, WS, ON};
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (i = begin; i < range; ++i)
{
U16 temp = dest_types[i];
if (temp == WS || temp == ON || temp == BIDI_B || temp == S)
{
/* find bounds of run of neutrals */
U8 leadingToken;
U8 trailingToken;
U8 validatedToken;
U16 runBegin = i;
/* Changed by Yogesh on Bilal suggestion 20040904 */
U16 runRange = get_run_rate(dest_types, runBegin, range, validToken, 4);
/* determine effective types at ends of run */
if (runBegin == begin)
{
leadingToken = sor;
}
else
{
leadingToken = dest_types[runBegin - 1];
if (leadingToken == BIDI_L || leadingToken == BIDI_R)
{
/* match found for the strong type */
}
else if (leadingToken == AN)
{
leadingToken = BIDI_R;
}
else if (leadingToken == EN)
{
/* last clause */
leadingToken = BIDI_R;
}
}
if (runRange == range)
{
trailingToken = eor;
}
else
{
trailingToken = dest_types[runRange];
if (trailingToken == BIDI_L || trailingToken == BIDI_R)
{
/* Match found here */
}
else if (trailingToken == AN)
{
trailingToken = BIDI_R;
}
else if (trailingToken == EN)
{
trailingToken = BIDI_R;
}
}
if (leadingToken == trailingToken)
{
/* Rule N1. */
validatedToken = leadingToken;
}
else
{
/* Rule N2. */
validatedToken = TOKEN_FOR_LEVEL(currentLevel);
}
setTokens(dest_types, runBegin, runRange, validatedToken);
/* skip over run of (former) neutrals */
i = runRange;
}
}
}
/**************************************************************************************************************
Rule:I1 & I2
Resolves the implicit levels
**************************************************************************************************************/
/*****************************************************************************
* FUNCTION
* processImplicitLevels
* DESCRIPTION
*
* PARAMETERS
* begin [IN]
* range [IN]
* currentLevel [IN]
* sor [IN]
* eor [IN]
* dest_levels [?]
* dest_types [?]
* RETURNS
* void
*****************************************************************************/
void processImplicitLevels(U16 begin, U16 range, U16 currentLevel, U8 sor, U8 eor, U8 *dest_levels, U8 *dest_types)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 iCount;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if ((currentLevel & 1) == 0)
{ /* even level */
for (iCount = begin; iCount < range; ++iCount)
{
U8 temp = dest_types[iCount];
if (temp == BIDI_L)
{
/* no change */
}
else if (temp == BIDI_R)
{
dest_levels[iCount] += 1;
}
else if (temp == AN || temp == EN)
{
dest_levels[iCount] += 2;
}
}
}
else
{ /* odd level */
for (iCount = begin; iCount < range; ++iCount)
{
U8 temp = dest_types[iCount];
if (temp == BIDI_R)
{
/* no change */
}
else if (temp == BIDI_L || temp == AN || temp == EN)
{
dest_levels[iCount] += 1;
}
}
}
}
/**************************************************************************************************************
Resinserting the explicit levels
returns the textLength
***************************************************************************************************************/
/*****************************************************************************
* FUNCTION
* insert_explicit_direction_codes
* DESCRIPTION
*
* PARAMETERS
* inputTypes [?]
* inputLen [IN]
* paragraphEmbeddingLevel [IN]
* all_embeddings_level [?]
* dest_levels [?]
* dest_types [?]
* RETURNS
*
*****************************************************************************/
U16 insert_explicit_direction_codes(
U8 *inputTypes,
U16 inputLen,
U8 paragraphEmbeddingLevel,
U8 *all_embeddings_level,
U8 *dest_levels,
U8 *dest_types)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S16 iCount;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (iCount = inputLen; --iCount >= 0;)
{
S16 kCount;
U8 temp = inputTypes[iCount];
kCount = inputLen;
if (temp == LRE || temp == RLE || temp == LRO || temp == RLO || temp == PDF || temp == BN)
{
all_embeddings_level[iCount] = 0;
dest_types[iCount] = temp;
dest_levels[iCount] = 0xff;
}
else
{
--kCount;
all_embeddings_level[iCount] = all_embeddings_level[kCount];
dest_types[iCount] = dest_types[kCount];
dest_levels[iCount] = dest_levels[kCount];
}
}
// now propagate forward the levels information (could have
// propagated backward, the main thing is not to introduce a level
// break where one doesn't already exist).
if (dest_levels[0] == -1)
{
dest_levels[0] = paragraphEmbeddingLevel;
}
for (iCount = 1; iCount < inputLen; ++iCount)
{
if (dest_levels[iCount] == -1)
{
dest_levels[iCount] = dest_levels[iCount - 1];
}
}
// Embedding information is for informational purposes only
// so need not be adjusted.
return inputLen;
}