nsresult Conv_FE_06_WithReverse(const nsString& aSrc, nsString& aDst) { PRUnichar *aSrcUnichars = (PRUnichar *)aSrc.get(); PRBool foundArabic = PR_FALSE; PRUint32 i, endArabic, beginArabic, size; beginArabic = 0; size = aSrc.Length(); aDst.Truncate(); for (endArabic=0;endArabic<size;endArabic++) { if (aSrcUnichars[endArabic] == 0x0000) break; // no need to convert char after the NULL while( (IS_FE_CHAR(aSrcUnichars[endArabic]))|| (IS_ARABIC_CHAR(aSrcUnichars[endArabic]))|| (IS_ARABIC_DIGIT(aSrcUnichars[endArabic]))|| (aSrcUnichars[endArabic]==0x0020)) { if(! foundArabic ) { beginArabic=endArabic; foundArabic= PR_TRUE; } endArabic++; } if(foundArabic) { endArabic--; for (i=endArabic; i>=beginArabic; i--) { if(IS_FE_CHAR(aSrcUnichars[i])) { //ahmed for the bug of lamalf aDst += PresentationToOriginal(aSrcUnichars[i], 0); if (PresentationToOriginal(aSrcUnichars[i], 1)) { // Two characters, we have to resize the buffer :( aDst += PresentationToOriginal(aSrcUnichars[i], 1); } // if expands to 2 char } else { // do we need to check the following if ? if((IS_ARABIC_CHAR(aSrcUnichars[i]))|| (IS_ARABIC_DIGIT(aSrcUnichars[i]))|| (aSrcUnichars[i]==0x0020)) aDst += aSrcUnichars[i]; } } } else { aDst += aSrcUnichars[endArabic]; } foundArabic=PR_FALSE; }// for : loop the buffer return NS_OK; }
nsresult HandleNumbers(PRUnichar* aBuffer, PRUint32 aSize, PRUint32 aNumFlag) { PRUint32 i; // IBMBIDI_NUMERAL_NOMINAL * // IBMBIDI_NUMERAL_REGULAR // IBMBIDI_NUMERAL_HINDICONTEXT // IBMBIDI_NUMERAL_ARABIC // IBMBIDI_NUMERAL_HINDI switch (aNumFlag) { case IBMBIDI_NUMERAL_HINDI: for (i=0;i<aSize;i++) aBuffer[i] = NUM_TO_HINDI(aBuffer[i]); break; case IBMBIDI_NUMERAL_ARABIC: for (i=0;i<aSize;i++) aBuffer[i] = NUM_TO_ARABIC(aBuffer[i]); break; case IBMBIDI_NUMERAL_REGULAR: case IBMBIDI_NUMERAL_HINDICONTEXT: // for clipboard handling //XXX do we really want to convert numerals when copying text? for (i=1;i<aSize;i++) { if (IS_ARABIC_CHAR(aBuffer[i-1])) aBuffer[i] = NUM_TO_HINDI(aBuffer[i]); else aBuffer[i] = NUM_TO_ARABIC(aBuffer[i]); } case IBMBIDI_NUMERAL_NOMINAL: default: break; } return NS_OK; }
PRUnichar* nsTextFrameUtils::TransformText(const PRUnichar* aText, PRUint32 aLength, PRUnichar* aOutput, CompressionMode aCompression, PRUint8* aIncomingFlags, gfxSkipCharsBuilder* aSkipChars, PRUint32* aAnalysisFlags) { PRUint32 flags = 0; PRUnichar* outputStart = aOutput; PRBool lastCharArabic = PR_FALSE; if (aCompression == COMPRESS_NONE) { // Skip discardables. PRUint32 i; for (i = 0; i < aLength; ++i) { PRUnichar ch = *aText++; if (IsDiscardable(ch, &flags)) { aSkipChars->SkipChar(); } else { aSkipChars->KeepChar(); if (ch == '\t') { flags |= TEXT_HAS_TAB; } else if (ch != ' ' && ch != '\n') { // we already know it's not a tab from the previous check lastCharArabic = IS_ARABIC_CHAR(ch); } *aOutput++ = ch; } } if (lastCharArabic) { *aIncomingFlags |= INCOMING_ARABICCHAR; } else { *aIncomingFlags &= ~INCOMING_ARABICCHAR; } *aIncomingFlags &= ~INCOMING_WHITESPACE; } else { PRBool inWhitespace = (*aIncomingFlags & INCOMING_WHITESPACE) != 0; PRUint32 i; for (i = 0; i < aLength; ++i) { PRUnichar ch = *aText++; PRBool nowInWhitespace; if (ch == ' ' && (i + 1 >= aLength || !IsSpaceCombiningSequenceTail(aText, aLength - (i + 1)))) { nowInWhitespace = PR_TRUE; } else if (ch == '\n' && aCompression == COMPRESS_WHITESPACE_NEWLINE) { if (i > 0 && IS_CJ_CHAR(aText[-1]) && i + 1 < aLength && IS_CJ_CHAR(aText[1])) { // Discard newlines between CJK chars. // XXX this really requires more context to get right! aSkipChars->SkipChar(); continue; } nowInWhitespace = PR_TRUE; } else { nowInWhitespace = ch == '\t'; } if (!nowInWhitespace) { if (IsDiscardable(ch, &flags)) { aSkipChars->SkipChar(); nowInWhitespace = inWhitespace; } else { *aOutput++ = ch; aSkipChars->KeepChar(); lastCharArabic = IS_ARABIC_CHAR(ch); } } else { if (inWhitespace) { aSkipChars->SkipChar(); } else { if (ch != ' ') { flags |= TEXT_WAS_TRANSFORMED; } *aOutput++ = ' '; aSkipChars->KeepChar(); } } inWhitespace = nowInWhitespace; } if (lastCharArabic) { *aIncomingFlags |= INCOMING_ARABICCHAR; } else { *aIncomingFlags &= ~INCOMING_ARABICCHAR; } if (inWhitespace) { *aIncomingFlags |= INCOMING_WHITESPACE; } else { *aIncomingFlags &= ~INCOMING_WHITESPACE; } } if (outputStart + aLength != aOutput) { flags |= TEXT_WAS_TRANSFORMED; } *aAnalysisFlags = flags; return aOutput; }
nsresult Conv_06_FE_WithReverse(const nsString& aSrc, nsString& aDst, PRUint32 aDir) { PRUnichar *aSrcUnichars = (PRUnichar *)aSrc.get(); PRUint32 i, beginArabic, endArabic, size; beginArabic = 0; size = aSrc.Length(); aDst.Truncate(); PRBool foundArabic = PR_FALSE; for (endArabic=0;endArabic<size;endArabic++) { if (aSrcUnichars[endArabic] == 0x0000) break; // no need to convert char after the NULL while( (IS_06_CHAR(aSrcUnichars[endArabic])) || (IS_ARABIC_CHAR(aSrcUnichars[endArabic])) || (aSrcUnichars[endArabic]==0x0020) || (IS_ARABIC_DIGIT(aSrcUnichars[endArabic])) ) { if(! foundArabic) { beginArabic=endArabic; foundArabic=PR_TRUE; } endArabic++; } if(foundArabic) { endArabic--; PRUnichar buf[8192]; PRUint32 len=8192; ArabicShaping(&aSrcUnichars[beginArabic], endArabic-beginArabic+1, buf, &len, PR_TRUE, PR_FALSE); // to reverse the numerals PRUint32 endNumeral, beginNumeral = 0; for (endNumeral=0;endNumeral<=len-1;endNumeral++){ PRBool foundNumeral = PR_FALSE; while((endNumeral < len) && (IS_ARABIC_DIGIT(buf[endNumeral])) ) { if(!foundNumeral) { foundNumeral=PR_TRUE; beginNumeral=endNumeral; } endNumeral++; } if(foundNumeral){ endNumeral--; PRUnichar numbuf[20]; for(i=beginNumeral; i<=endNumeral; i++){ numbuf[i-beginNumeral]=buf[endNumeral-i+beginNumeral]; } for(i=0;i<=endNumeral-beginNumeral;i++){ buf[i+beginNumeral]=numbuf[i]; } } } if(aDir==1){//ltr for (i=0;i<=len-1;i++){ aDst+= buf[i]; } } else if(aDir==2){//rtl for (i=0;i<=len-1;i++){ aDst+= buf[len-1-i]; } } } else { aDst += aSrcUnichars[endArabic]; } foundArabic=PR_FALSE; }// for : loop the buffer return NS_OK; }
nsresult ArabicShaping(const PRUnichar* aString, PRUint32 aLen, PRUnichar* aBuf, PRUint32 *aBufLen, PRBool aInputLogical, PRBool aOutputLogical) { nsAutoString tempString(aString, aLen); if (tempString.Length() != aLen) return NS_ERROR_OUT_OF_MEMORY; PRUnichar *tempBuf = tempString.BeginWriting(); if (aInputLogical) { ReverseString(tempBuf, aLen); } const PRUnichar* src = tempBuf; const PRUnichar* p; PRUnichar* dest = aBuf; PRUnichar formB; PRInt8 leftJ, thisJ, rightJ; PRInt8 leftNoTrJ, rightNoTrJ; thisJ = leftNoTrJ = eNJ; rightJ = GetJoiningClass(*(src)); while(src<tempBuf+aLen-1) { leftJ = thisJ; if ((eTr != leftJ) || ((leftJ == eTr) && ( ( (src-1) >= tempBuf) && !IS_ARABIC_CHAR(*(src-1))))) leftNoTrJ = thisJ; if(src-2 >= (tempBuf)){ for(p=src-2; (p >= (tempBuf))&& (eTr == leftNoTrJ) && (IS_ARABIC_CHAR(*(p+1))) ; p--) leftNoTrJ = GetJoiningClass(*(p)) ; } thisJ = rightJ; rightJ = rightNoTrJ = GetJoiningClass(*(src+1)) ; if(src+2 <= (tempBuf+aLen-1)){ for(p=src+2; (p <= (tempBuf+aLen-1))&&(eTr == rightNoTrJ) && (IS_ARABIC_CHAR(*(src+1))); p++) rightNoTrJ = GetJoiningClass(*(p)) ; } formB = PresentationFormB(*src, DecideForm(leftNoTrJ, thisJ, rightNoTrJ)); *dest++ = formB; src++; } if((eTr != thisJ) || ((thisJ == eTr) && (((src-1)>=tempBuf) && (!IS_ARABIC_CHAR(*(src-1)))))) leftNoTrJ = thisJ; if(src-2 >= (tempBuf)){ for(p=src-2; (src-2 >= (tempBuf)) && (eTr == leftNoTrJ) && (IS_ARABIC_CHAR(*(p+1))); p--) leftNoTrJ = GetJoiningClass(*(p)) ; } formB = PresentationFormB(*src, DecideForm(leftNoTrJ, rightJ, eNJ)); *dest++ = formB; src++; PRUnichar *lSrc = aBuf; PRUnichar *lDest = aBuf; while(lSrc < (dest-1)) { PRUnichar next = *(lSrc+1); if(((0xFEDF == next) || (0xFEE0 == next)) && (0xFE80 == (0xFFF1 & *lSrc))) { PRBool done = PR_FALSE; PRUint16 key = ((*lSrc) << 8) | ( 0x00FF & next); PRUint16 i; for(i=0;i<8;i++) { if(key == gArabicLigatureMap[i]) { done = PR_TRUE; // lam and alef in the source are mapped to a lam-alef ligature in the // destination, so lSrc is incremented by 2 here *lDest++ = 0xFEF5 + i; lSrc+=2; break; } } if(! done) *lDest++ = *lSrc++; } else if (0x200C == *lSrc || 0x200D == *lSrc) // Strip zero-width joining controls ZWJ and ZWNJ from the shaped text lSrc++; else *lDest++ = *lSrc++; } if(lSrc < dest) *lDest++ = *lSrc++; *aBufLen = lDest - aBuf; NS_ASSERTION(*aBufLen <= aLen, "ArabicShaping() likely did a buffer overflow!"); if (aOutputLogical) { ReverseString(aBuf, *aBufLen); } return NS_OK; }