All Downloads are FREE. Search and download functionalities are using the official Maven repository.

src.com.ibm.as400.access.BidiShape Maven / Gradle / Ivy

There is a newer version: 11.1
Show newest version
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename:  BidiShape.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2005 International Business Machines Corporation and
// others.  All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////

package com.ibm.as400.access;

/**
 *  

Multi-threading considerations: This class is thread-safe, * since its only public method is synchronized, and there are no instance * variables. However, to avoid delays, each thread should use its own * instances of this class. **/ class BidiShape { /* replaces Arabic base letters by the appropriate * presentation forms. */ /* Link attribute are unsigned 16 bit integer with the following format: */ /* bit 0: links to the right */ /* bit 1: links to the left */ /* bit 2: is irrelevant to linking */ /* bit 4: Lam type UNI Code */ /* bit 5: Alef type UNI Code */ /* bit 8-15: offset to presentation shapes starting at U+FE70 */ static final char Tail = 0x200B ; private static final short shapeTable[][][]= { /* lastLink = 0 | lastLink = 1 | lastLink = 2 | lastLink = 3 */ /* nextLink = 0 */ { {0,0,0,0}, {0,0,0,0}, {0,1,0,3}, {0,1,0,1} }, /* nextLink = 1 */ { {0,0,2,2}, {0,0,1,2}, {0,1,1,2}, {0,1,1,3} }, /* nextLink = 2 */ { {0,0,0,0}, {0,0,0,0}, {0,1,0,3}, {0,1,0,3} }, /* nextLink = 3 */ { {0,0,1,2}, {0,0,1,2}, {0,1,1,2}, {0,1,1,3} } }; private static final int convertFEto06[] = { 0x64B, 0x64B, 0x64C, 0x64C, 0x64D, 0x64D, 0x64E, 0x64E, 0x64F, 0x64F, 0x650, 0x650, 0x651, 0x651, 0x652, 0x652, 0x621, 0x622, 0x622, 0x623,0x623, 0x624,0x624, 0x625,0x625, 0x626,0x626,0x626,0x626, 0x627,0x627, 0x628,0x628,0x628,0x628, 0x629,0x629, 0x62A,0x62A,0x62A,0x62A, 0x62B,0x62B,0x62B,0x62B, 0x62C,0x62C,0x62C,0x62C, 0x62D,0x62D,0x62D,0x62D, 0x62E,0x62E,0x62E,0x62E, 0x62F,0x62F, 0x630,0x630, 0x631,0x631, 0x632,0x632, 0x633,0x633, 0x633,0x633, 0x634, 0x634,0x634,0x634, 0x635,0x635,0x635,0x635, 0x636,0x636,0x636,0x636, 0x637,0x637,0x637,0x637, 0x638,0x638,0x638,0x638, 0x639,0x639,0x639,0x639, 0x63A,0x63A,0x63A,0x63A, 0x641,0x641,0x641,0x641, 0x642,0x642,0x642,0x642, 0x643,0x643,0x643,0x643, 0x644,0x644,0x644,0x644, 0x645,0x645,0x645,0x645, 0x646,0x646,0x646,0x646, 0x647,0x647,0x647,0x647, 0x648, 0x648, 0x649,0x649, 0x64A,0x64A,0x64A,0x64A, 0x65C, 0x65C, 0x65D,0x65D, 0x65E,0x65E, 0x65F,0x65F }; private static final int convert06toFE[] = { 0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1D, 0x1F, 0x23, 0x25, 0x29, 0x2D, 0x31, 0x35, 0x39, 0x3B, 0x3D, 0x3F, 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x65, 0x69, 0x6D, 0x71, 0x75, 0x79, 0x7D, 0x7F, 0x81, 0x0, 0x2, 0x4, 0x6, 0x8, 0xA, 0xC, 0xE }; /*****************************************************************************/ private static final int Link06[]= { 1 + 32 + 256 * 0x11, 1 + 32 + 256 * 0x13, 1 + 256 * 0x15, 1 + 32 + 256 * 0x17, 1 + 2 + 256 * 0x19, 1 + 32 + 256 * 0x1D, 1 + 2 + 256 * 0x1F, 1 + 256 * 0x23, 1 + 2 + 256 * 0x25, 1 + 2 + 256 * 0x29, 1 + 2 + 256 * 0x2D, 1 + 2 + 256 * 0x31, 1 + 2 + 256 * 0x35, 1 + 256 * 0x39, 1 + 256 * 0x3B, 1 + 256 * 0x3D, 1 + 256 * 0x3F, 1 + 2 + 256 * 0x41, 1 + 2 + 256 * 0x45, 1 + 2 + 256 * 0x49, 1 + 2 + 256 * 0x4D, 1 + 2 + 256 * 0x51, 1 + 2 + 256 * 0x55, 1 + 2 + 256 * 0x59, 1 + 2 + 256 * 0x5D, 0, 0, 0, 0, 0, /* 0x63B - 0x63F */ 1 + 2, 1 + 2 + 256 * 0x61, 1 + 2 + 256 * 0x65, 1 + 2 + 256 * 0x69, 1 + 2 + 16 + 256 * 0x6D, 1 + 2 + 256 * 0x71, 1 + 2 + 256 * 0x75, 1 + 2 + 256 * 0x79, 1 + 256 * 0x7D, 1 + 256 * 0x7F, 1 + 2 + 256 * 0x81, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x64B - 0x652 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x653 - 0x65B */ 1 + 256 * 0x85, 1 + 256 * 0x87, 1 + 256 * 0x89, 1 + 256 * 0x8B, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x660 - 0x66F */ 4, 0, 1 + 32, 1 + 32, 0, 1 + 32, 1, 1, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1+2, 1, 1+2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1+2, 1, 1+2, 1+2, 1+2, 1+2, 1, 1 }; /*****************************************************************************/ private static final short LinkFE[]= { 1 + 2, 1 + 2, 1 + 2, 0, 1+ 2, 0, 1+ 2, 1 + 2, 1+ 2, 1 + 2, 1+2, 1 + 2, 1+ 2, 1 + 2, 1+2, 1 + 2, 0, 0 + 32, 1 + 32, 0 + 32, 1 + 32, 0, 1, 0 + 32, 1 + 32, 0, 2, 1 + 2, 1, 0 + 32, 1 + 32, 0, 2, 1 + 2, 1, 0, 1, 0, 2, 1 + 2, 1, 0, 2, 1 + 2, 1, 0, 2, 1 + 2, 1, 0, 2, 1 + 2, 1, 0, 2, 1 + 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0 + 16, 2 + 16, 1 + 2 +16, 1 + 16, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 2, 1+2, 1, 0, 1, 0, 1, 0, 2, 1+2, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; /*****************************************************************************/ private static final short IrreleventPos[]= { 0x0, 0x2, 0x4, 0x6, 0x8, 0xA, 0xC, 0xE, } ; //Used by Lam-Alef methods static char AlefType[] = { '\u0622', '\u0622', '\u0623', '\u0623', '\u0625', '\u0625', '\u0627', '\u0627', }; //Used by Tashkeel handeling methods static char Tashkeel[] = { '\ufe70', //Tanween Fath '\ufe72', //Tanween Dam '\ufe74', //Tanween Kasr '\ufe76', //Fatha '\ufe78', //Dama '\ufe7A', //Kassra '\ufe7c', //Shadda '\ufe7e', //Sekooun }; //Used by Tashkeel handeling methods static char Tashkeel_Tatweel[] = { '\ufe71', //Tanween Fath with tatweel '\ufe72', //Tanween Dam -- No Ttween Dam with Tashkeel in the FE Range '\ufe74', //Tanween Kasr -- No Ttween Dam with Tashkeel in the FE Range '\ufe77', //Fatha with tatweel '\ufe79', //Dama with tatweel '\ufe7b', //Kassra with tatweel '\ufe7d', //Shadda with tatweel '\ufe7f', //Sekooun with tatweel }; private static final int LINKR = 1; private static final int LINKL = 2; private static final int IRRELEVANT = 4; private static final int LAMTYPE = 16; private static final int ALEFTYPE = 32; private static final int LINKFIELD = 3; /** * Method shapingRoutine * This method represents the shaping routine. * @param inAttr The input Bidi Attributes (TextType, TextShape, ...etc.) * @param outAttr The output Bidi Attributes (TextType, TextShape, ...etc.) * @param str The buffer to be shaped. * @param rtl The buffer orientation. */ synchronized void shapingRoutine(BidiFlagSet inAttr, BidiFlagSet outAttr, char str[], boolean rtl) { int currLink; /* link attributes of current character at position Ix */ int lastLink=0; /* link attributes of the last character which was not irrelevant to linking */ int nextLink=0; /* link attributes of the next character which is not irrelevant to linking */ int prevLink=0; /* link attributes of the character before the last which is not irrelevant to linking */ int lastPos; /* position of the last character which was not irrelevant */ int Nx; /* position of the next character which is not irrelevant */ int prevPos; /* position of the character before the last which was not irr*/ int iEnd, Nw, step, Shape, Ix; char wLamalef; int flag; BidiFlag inTextType, outTextType, /*inTextShape,*/ outTextShape; int bufLen = str.length; if ( bufLen == 0) return; //Initialize variables inTextType = inAttr.getType(); outTextType = outAttr.getType(); //inTextShape = inAttr.getText(); outTextShape = outAttr.getText(); if(inTextType == BidiFlag.TYPE_VISUAL && outTextType == BidiFlag.TYPE_IMPLICIT) //Visual to Implicit { //We must test if this check is the best check for shapping Shaped -> Nominal for (int idx = 0; idx < bufLen ; idx++) { //Convert the characters from FE to 06 range if ( (str[idx] >= 0xFE70) && (str[idx] <= 0xFEF4 ) ) { //This change fix NULL pointer exception with IBMJDK 1.4 //IBMJDK1.4 cann't resolve casting correctly int newCharValue = str[idx] - 0xFE70; str[idx] = (char)(convertFEto06 [ newCharValue ] ) ; } } }//end if Visual to Implicit else if(outTextType == BidiFlag.TYPE_VISUAL) { //We must test if this check is the best check for shapping -> Nominal /* This pass is done so that Arabic characters are processed in language */ /* order. If outAttr is RTL , this means start processing from the begining of*/ /* the str (source) till its end; if outAttr is LTR , this means start */ /* processing from the end of the str (source) till its beginning */ if (rtl) { Ix = 0; /* Setting the low boundary of the processing */ iEnd = str.length ; /* Setting the high boundary of the processing */ step = +1; } else { Ix = str.length - 1; /* Setting the low boundary of the processing */ iEnd = -1; /* Setting the high boundary of the processing */ step = -1; } prevLink = 0; lastLink = 0; currLink = uba_getLink ( str[Ix] ); prevPos = Ix; lastPos = Ix; Nx = -2; while ( Ix != iEnd ) { if ((currLink & 0xFF00) > 0 ) /* If there are more than one shape */ { Nw = Ix + step; while ( Nx < 0 ) { /* we need to know about next char */ if (Nw == iEnd) { nextLink = 0; Nx = 30000; /* will stay so until end of pass*/ } else { nextLink = uba_getLink(str[Nw]); if ((nextLink & IRRELEVANT) == 0) Nx = Nw; else Nw += step; } } if ( ((currLink & ALEFTYPE) > 0) && ((lastLink & LAMTYPE) > 0)) { wLamalef = Lamalef( str[Ix] ); //get from 0x065C-0x065f if ( wLamalef != 0) { if (rtl) { str[lastPos] = wLamalef ; for(int h=Ix;h0; h--) {str[h] =str[h-1];} str[0] =(char) 0x0020; Ix=lastPos; } //LTR }//(wLamalef != 0) lastLink = prevLink; currLink = uba_getLink(wLamalef); Nx = -2; //force recompute of nextLink } /* get the proper shape according to link ability of neighbors and of character; depends on the order of the shapes (isolated, initial, middle, final) in the compatibility area */ flag=specialChar (str[Ix]); if (outTextShape == BidiFlag.TEXT_INITIAL) { if(flag==0) Shape = 2; else Shape = 0; } else if (outTextShape == BidiFlag.TEXT_MIDDLE) { if(flag == 0) Shape = 3; else Shape = 1; } else if (outTextShape == BidiFlag.TEXT_FINAL) { if(flag == 0) Shape = 1; else Shape = 1; } else if (outTextShape == BidiFlag.TEXT_ISOLATED) { Shape = 0; } else { Shape = shapeTable[nextLink & (LINKR + LINKL)] [lastLink & (LINKR + LINKL)] [currLink & (LINKR + LINKL)]; } str[Ix] = (char)(0xFE70 + ( currLink >> 8 ) + Shape) ; } /* move one notch forward */ if ((currLink & IRRELEVANT) == 0) { prevLink = lastLink; lastLink = currLink; prevPos = lastPos; lastPos = Ix; } //Tashkil characters if ( ((currLink & IRRELEVANT) > 0) && (0 <= (str[Ix] - 0x064B)) && ((str[Ix] - 0x064B) < IrreleventPos.length ) ) { int charidx = str[Ix] - 0x064B; int MyShape =0; int next = (int) (nextLink & (LINKR + LINKL)); int last =lastLink & (LINKR + LINKL); if ( ( (last==3)&& (next==1) ) || ( (last==3) && (next==3) ) ) MyShape= 1; if ( ((nextLink & ALEFTYPE) > 0) && ((lastLink & LAMTYPE) > 0) ) MyShape=0; if ( (str[Ix]==0x064C) //Wawdoma || (str[Ix]==0x064D) ) //kasrten MyShape=0; str[Ix] = (char)(0xFE70 + IrreleventPos[charidx]+ MyShape) ; } Ix += step; if ( Ix == Nx ) { currLink = nextLink; Nx = -2; } else { if (Ix != iEnd) currLink = uba_getLink ( str[Ix]) ; } } //end while }// end of else to visual } /** * Method shape. * In this method, the shaping process (Arabic options handling and shaping routine) is performed. * * @param inAttr The input Bidi Attributes (TextType, TextShape, ...etc.) * @param outAttr The output Bidi Attributes (TextType, TextShape, ...etc.) * @param str The buffer to be shaped. * @param optionSet The Arabic options used in shaping process. */ synchronized char[] shape(BidiFlagSet inAttr, BidiFlagSet outAttr, char str[], ArabicOptionSet optionSet) { boolean rtl = true; BidiFlag inTextType, outTextType, /*inTextShape,*/ outTextShape; ArabicOption lamAlefOpt, seenOpt, yehHamzaOpt, tashkeelOpt; int bufLen = str.length; if ( bufLen == 0) return str; if(optionSet == null) //Set Arabic options to the default values in case user did not specify them. { optionSet = new ArabicOptionSet(); } //Initialize variables inTextType = inAttr.getType(); outTextType = outAttr.getType(); rtl = outAttr.getOrientation() == BidiFlag.ORIENTATION_RTL; //inTextShape = inAttr.getText(); outTextShape = outAttr.getText(); lamAlefOpt = optionSet.getLamAlefMode(); seenOpt = optionSet.getSeenMode(); yehHamzaOpt = optionSet.getYehHamzaMode(); tashkeelOpt = optionSet.getTashkeelMode(); if(inTextType == BidiFlag.TYPE_VISUAL && outTextType == BidiFlag.TYPE_IMPLICIT) //Visual to Implicit { //Seen Deshaping if( (seenOpt == ArabicOption.SEEN_NEAR) || (seenOpt == ArabicOption.SEEN_AUTO) ) deshapeSeenNear(str,bufLen); /*Yeh Hamza DeShapping*/ if (( yehHamzaOpt == ArabicOption.YEHHAMZA_TWO_CELL_NEAR ) || ( yehHamzaOpt == ArabicOption.YEHHAMZA_AUTO)) { deshapeYehHamzaTwoCellNear(str, bufLen); } /*Tashkeel DeShapping*/ if((tashkeelOpt == ArabicOption.TASHKEEL_KEEP) || ( tashkeelOpt == ArabicOption.TASHKEEL_AUTO)) { //No processing is done } else if (tashkeelOpt == ArabicOption.TASHKEEL_CUSTOMIZED_ATBEGIN) { customizeTashkeelAtBegin( str, bufLen); } else if (tashkeelOpt == ArabicOption.TASHKEEL_CUSTOMIZED_ATEND) { customizeTashkeelAtEnd( str, bufLen); } /*LamAlef DeShapping*/ if( lamAlefOpt == ArabicOption.LAMALEF_RESIZE_BUFFER ){ str=deshapeLamAlefWithResizeBuffer(str, bufLen); bufLen= str.length; } else if (lamAlefOpt == ArabicOption.LAMALEF_NEAR) { deshapeLamAlefNear(str, bufLen); } else if (lamAlefOpt == ArabicOption.LAMALEF_ATBEGIN) { deshapeLamAlefAtBegin(str, bufLen); } else if (lamAlefOpt == ArabicOption.LAMALEF_ATEND) { deshapeLamAlefAtEnd(str, bufLen); } else if(lamAlefOpt == ArabicOption.LAMALEF_AUTO ){ deshapeLamAlefAuto(str, bufLen,rtl); } shapingRoutine(inAttr, outAttr, str, rtl); }//end if Visual to Implicit else if(outTextType == BidiFlag.TYPE_VISUAL) { shapingRoutine(inAttr, outAttr, str, rtl); /* Seen Shapping*/ if( (seenOpt == ArabicOption.SEEN_NEAR) || (seenOpt == ArabicOption.SEEN_AUTO) ) shapeSeenNear(str,bufLen, rtl); /* Yeh Hamza Shapping*/ if( (yehHamzaOpt == ArabicOption.YEHHAMZA_TWO_CELL_NEAR) || ( yehHamzaOpt == ArabicOption.YEHHAMZA_AUTO)){ shapeYehHamzaTwoCellNear(str, bufLen, rtl); } /*Tashkeel Shapping*/ if((tashkeelOpt == ArabicOption.TASHKEEL_KEEP) || ( tashkeelOpt == ArabicOption.TASHKEEL_AUTO)) { //No processing is done } else if (tashkeelOpt == ArabicOption.TASHKEEL_CUSTOMIZED_ATBEGIN) { customizeTashkeelAtBegin( str, bufLen); } else if (tashkeelOpt == ArabicOption.TASHKEEL_CUSTOMIZED_ATEND) { customizeTashkeelAtEnd( str, bufLen); } /* LamAlef Handling*/ if( lamAlefOpt == ArabicOption.LAMALEF_RESIZE_BUFFER ){ str=handleLamAlefWithResizeBuffer(str, bufLen, rtl); bufLen=str.length; } else if (lamAlefOpt == ArabicOption.LAMALEF_NEAR){ handleLamAlefNear(str, bufLen, rtl); } else if (lamAlefOpt == ArabicOption.LAMALEF_ATBEGIN) { // In case of LTR spaces are already in the absolute begining of buffer if (rtl) handleLamAlefAtBegin(str, bufLen); } else if (lamAlefOpt == ArabicOption.LAMALEF_ATEND) { // In case of RTL spaces are already in the absolute end of buffer if (!rtl) handleLamAlefAtEnd(str, bufLen); } else if(lamAlefOpt == ArabicOption.LAMALEF_AUTO ) { //No processing is done } }// end of else if to shaped return str; } /** * Method uba_getLink. * * @param x the character to be checked * @return int */ private static int uba_getLink(char x) { if(x >= 0x0622 && x <= 0x06D3) //06 Range return(Link06[x-0x0622]); else if(x == 0x200D) //(ZWJ) return(3); else if(x >= 0x206D && x <= 0x206F) //Alternate Formating return(4); else if(x >= 0xFE70 && x <= 0xFEFC) //FE range return(LinkFE[x-0xFE70]); else return(0); } /** * Method Lamalef. * * @param x the character to be checked * @return char */ private static char Lamalef(char x) { switch(x) { case 0x0622: return (0x065C); case 0x0623: return (0x065D); case 0x0625: return (0x065E); case 0x0627: return (0x065F); } return (0); } /** * Method specialChar. * * @param ch the character to be checked * @return int */ private static int specialChar(char ch) { // hamza , if((ch >= 0x0621 && ch < 0x0626)|| (ch == 0x0627 )|| (ch > 0x062e && ch < 0x0633) || (ch > 0x0647 && ch < 0x064a) || ch == 0x0629) return(1); else return(0); } /** * Method SeenChar. * This method checks if the passed chracter is one of the Seen family characters. * Seen family characters are Seen, Sheen, Sad and Dad. For each character of them there are * two shapes. * * @param ch The character to be checked. * @return boolean true, if the character belongs to Seen family. * false, otherwise */ private static boolean SeenChar(char ch) { if ( (ch==0xFEB1) || (ch==0xFEB2) || (ch==0xFEB5) || (ch==0xFEB6) || (ch==0xFEB9) || (ch==0xFEBA) || (ch==0xFEBD) || (ch==0xFEBE) ) return(true); else return(false); } //The following methods are responsible for handling Arabic Options /* ******************************** */ /* */ /* Methods for Lam Alef handling */ /* */ /* ******************************** */ /** * Method handleLamAlefWithResizeBuffer. * This method shrink the input buffer by the number of Lam-Alef occurences. * The buffer is supposed to come with LamAlef shaped with a space at end/begin * of the buffer depending on wherther the output is rtl or ltr. * And the method role is to remove this space and shrink the buffer * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. * @return int The new size of the buffer. * */ private char[] handleLamAlefWithResizeBuffer(char[] buffer, int length, boolean rtl){ int counter =0 ; int lamAlefCount=0; char compressedBuffer[]; for (counter=0;counter= 0xFEF5) && (buffer[counter] <= 0xFEFC )) lamAlefCount++; } if(lamAlefCount == 0) return buffer; compressedBuffer = new char[length-lamAlefCount]; if(rtl){//Remove the sapces at the end of the buffer System.arraycopy(buffer,0, compressedBuffer, 0, buffer.length-lamAlefCount); } else {//Remove the sapces in the begining of the buffer System.arraycopy(buffer, lamAlefCount, compressedBuffer, 0, buffer.length-lamAlefCount); } return compressedBuffer; } /** * Method deshapeLamAlefWithResizeBuffer. * This method enlarge the input buffer by the number of Lam-Alef occurences. * All Lam-Alef characters are expanded to Lam + Alef characters . * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. * @return int The new size of the buffer. * */ private char[] deshapeLamAlefWithResizeBuffer(char[] buffer, int length){ char ChAlefType; int oldBufferCounter =0 ; int newBufferCounter =0 ; int lamAlefCount=0; char expandedBuffer[]; for (oldBufferCounter=0;oldBufferCounter= 0xFEF5) && (buffer[oldBufferCounter] <= 0xFEFC )) lamAlefCount++; } if(lamAlefCount == 0) return buffer; expandedBuffer = new char[length+lamAlefCount]; oldBufferCounter =0; while (oldBufferCounter < length) { if ( ( buffer[oldBufferCounter] >= 0xFEF5) && (buffer[oldBufferCounter] <= 0xFEFC )) { ChAlefType = (char)AlefType[buffer[oldBufferCounter]-0xFEF5]; expandedBuffer[newBufferCounter] = '\u0644'; newBufferCounter++; expandedBuffer[newBufferCounter] = ChAlefType; } else { expandedBuffer[newBufferCounter] = buffer[oldBufferCounter]; } newBufferCounter++; oldBufferCounter ++; } return expandedBuffer; } /** * Method handleLamAlefNear * This method moves the spaces located in the begining of buffer with respect to * orientation (buffer[0] in LTR and buffer[length -1] in RTL) to the position near * to each of Lam-Alef characters. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. * */ private void handleLamAlefNear(char[] buffer, int length, boolean rtl) { int count = 0; int tempIdx; while (count < length) { if ((buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[length - 1] == 0x0020 && rtl) { for (tempIdx = length -1; tempIdx > count + 1; tempIdx--) buffer [tempIdx] = buffer [tempIdx - 1]; if(count < length - 1) buffer[count + 1] = 0x0020; } else if ((buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[0] == 0x0020 && !rtl) { for (tempIdx = 0; tempIdx < count - 1; tempIdx++) buffer [tempIdx] = buffer [tempIdx + 1]; if (count != 0) buffer[count - 1] = 0x0020; } count ++; } } /** * Method deshapeLamAlefNear * This method expands Lam-Alef character to Lam and Alef using the space near to * Lam-Alef character. In case no spaces occurs near this character no processing * will be done and the output buffer will contain the Lam-Alef character in its * FE hexadecimal value. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void deshapeLamAlefNear(char[] buffer, int length) { char ChAlefType; int count = 1; while (count < length) { if ( (buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && ( (count!= length - 1) && ( buffer[count + 1] == 0x0020) ) ) { ChAlefType = (char)AlefType[buffer[count]-0xFEF5]; buffer[count + 1] = ChAlefType; buffer[count] = '\u0644'; } count ++; } } /** * Method handleLamAlefAtBegin * This method moves the space located in the absolute end of buffer to the absolute begin of buffer so these * spaces can be used in Lam-Alef deshaping in the other way back. * character. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void handleLamAlefAtBegin(char[] buffer, int length) { int count = 0; int tempIdx, lamAlefOccurences = 0; while (count < length) { if ((buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[length - 1] == 0x0020) { for (tempIdx = length - 1; tempIdx >lamAlefOccurences; tempIdx--) buffer [tempIdx] = buffer [tempIdx - 1]; buffer[lamAlefOccurences] = 0x0020; lamAlefOccurences++; count++; } count ++; } } /** * Method deshapeLamAlefAtBegin * This method expands Lam-Alef character to Lam and Alef using the spaces in the absolute begin of buffer. * In case no spaces occurs near this character no processing will be done and the output buffer will contain * the Lam-Alef character in its FE hexadecimal value. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void deshapeLamAlefAtBegin(char[] buffer, int length) { char ChAlefType; int count = 0 ; int tempIdx; while (count < length) { if ( (buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[0] == 0x0020) { ChAlefType = (char)AlefType[buffer[count]-0xFEF5]; for (tempIdx = 0; tempIdx < count - 1; tempIdx++) buffer [tempIdx] = buffer [tempIdx + 1]; buffer[count - 1] = '\u0644'; buffer[count] = ChAlefType; } count ++; } } /** * Method handleLamAlefAtEnd * This method moves the space located in the absolute begin of buffer to the absolute end of buffer so these * spaces can be used in Lam-Alef deshaping in the other way back. * character. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void handleLamAlefAtEnd(char[] buffer, int length) { int count = 0; int tempIdx, lamAlefOccurences = 0; while (count < length) { if ((buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[0] == 0x0020) { for (tempIdx = 0; tempIdx < length - lamAlefOccurences - 1; tempIdx++) buffer [tempIdx] = buffer [tempIdx + 1]; buffer[length - lamAlefOccurences - 1] = 0x0020; lamAlefOccurences++; } count ++; } } /** * Method deshapeLamAlefAtEnd * This method expands Lam-Alef character to Lam and Alef using the spaces in the absolute end of buffer. * In case no spaces occurs near this character no processing will be done and the output buffer will contain * the Lam-Alef character in its FE hexadecimal value. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void deshapeLamAlefAtEnd(char[] buffer, int length) { char ChAlefType; int count = 0 ; int tempIdx; while (count < length) { if ( (buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC ) && buffer[length - 1] == 0x0020) { ChAlefType = (char)AlefType[buffer[count]-0xFEF5]; for (tempIdx = length - 1; tempIdx > count + 1; tempIdx--) buffer [tempIdx] = buffer [tempIdx - 1]; buffer[count] = '\u0644'; buffer[count + 1] = ChAlefType; } count ++; } } /** * Method handleLamAlefAuto. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. * */ private void handleLamAlefAuto(char[] buffer, int length, boolean rtl) {} /** * Method deshapeLamAlefAuto. * * This method expands LamAlef character to Lam and Alef characters consuming the space * located in the in the begining of buffer with respect to orientation (buffer[0] in LTR * and buffer[length -1] in RTL) * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. */ private void deshapeLamAlefAuto(char[] buffer, int length, boolean rtl){ char ChAlefType; int count =0 ; while (count < length) { if ( ( buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC )&&buffer[length-1]==0x0020&&rtl) { ChAlefType = (char)AlefType[buffer[count]-0xFEF5]; for(int h=length-1;h>count;h--) buffer[h] = buffer[h-1]; buffer[count+1] = ChAlefType; buffer[count] = '\u0644'; } else if ( ( buffer[count] >= 0xFEF5) && (buffer[count] <= 0xFEFC )&&buffer[0]==0x0020&&!rtl) { ChAlefType = (char)AlefType[buffer[count]-0xFEF5]; for(int h=0;h= 0) && ( buffer[idx-1] == 0x0020) ) ) buffer[idx-1] = BidiShape.Tail; } } } /** * This method replaces Seen Tail by a space near to the Seen character. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void deshapeSeenNear(char[] buffer, int length) { for (int idx = 0; idx < length ; idx++) { if (buffer[idx] == BidiShape.Tail) buffer[idx]= (char)0x0020; } } /** * Method shapeSeenAtBegin. * * @param buffer * @param length * @param rtl */ private void shapeSeenAtBegin(char[] buffer, int length, boolean rtl){} /** * Method deshapeSeenAtBegin. * * @param buffer * @param length * @param rtl */ private void deshapeSeenAtBegin(char[] buffer, int length, boolean rtl){} /** * Method shapeSeenAtEnd. * * @param buffer * @param length * @param rtl */ private void shapeSeenAtEnd(char[] buffer, int length, boolean rtl){} /** * Method deshapeSeenAtEnd. * * @param buffer * @param length * @param rtl */ private void deshapeSeenAtEnd(char[] buffer, int length, boolean rtl){} /** * Method handleSeenAuto. * * @param buffer * @param length * @param rtl */ private void handleSeenAuto(char[] buffer, int length, boolean rtl){} /** * Method deshapeSeenAuto. * @param buffer * @param length * @param rtl */ private void deshapeSeenAuto(char[] buffer, int length, boolean rtl){} /* ******************************** */ /* */ /* Methods for Yeh Hamza handling */ /* */ /* ******************************** */ /** * Method shapeYehHamzaTwoCellNear. * This method convert every YehHamza to Yeh + Hamza depending on whether the output * buffer is rtl or ltr using the space near the YeahHamza * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * @param rtl The buffer orientation. * */ private void shapeYehHamzaTwoCellNear(char[] buffer, int length, boolean rtl){ int counter=0; for (counter =0; counter < length ; counter++) { if(rtl) { if ( buffer[counter] == 0xfe8a ) { buffer[counter]= 0xfef0;//Yeh if ( (counter+1 < length) && ( buffer[counter+1] == 0x0020) ) buffer[counter+1] = 0xfe80; //hamza } if ( buffer[counter] == 0xfe89 ) { buffer[counter] = 0xfeef ;//Yeh if ( (counter+1 < length) && ( buffer[counter+1] == 0x0020) ) buffer[counter+1] = 0xfe80 ;//hamza } } else { if ( buffer[counter] == 0xfe8a ) { buffer[counter]= 0xfef0;//Yeh if ( (counter-1 >= 0) && ( buffer[counter-1] == 0x0020) ) buffer[counter-1] = 0xfe80; //hamza } if ( buffer[counter] == 0xfe89 ) { buffer[counter] = 0xfeef;//Yeh if ( (counter-1 >= 0) && ( buffer[counter-1] == 0x0020) ) buffer[counter-1] = 0xfe80 ;//hamza } } } } /** * Method deshapeYehHamzaTwoCellNear. * This method convert every Yeh follwed by a Hamza to YehHamza character * and put the spaces near the character * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void deshapeYehHamzaTwoCellNear(char[] buffer, int length){ int counter=0; for (counter =0; counter < length ; counter++) { if ((counter+1 = 0xFE70) && (buffer[count] <= 0xFE72) ) || (buffer[count] == 0xFE74) || ( (buffer[count] >= 0xFE76) && (buffer[count] <= 0xFE7B) ) || ( (buffer[count] >= 0xFE7E) && (buffer[count] <= 0xFE7F) ) ) { for(int idx = count; idx > tashkeelOcuurences; idx--) buffer[idx] = buffer[idx - 1]; buffer[tashkeelOcuurences] = 0x0020; tashkeelOcuurences++; } count ++; } } /** * Method customizeTashkeelAtEnd. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void customizeTashkeelAtEnd(char[] buffer, int length) { int count =0 ; int tashkeelOcuurences = 0; while (count < length) { if ( ( (buffer[count] >= 0xFE70) && (buffer[count] <= 0xFE72) ) || (buffer[count] == 0xFE74) || ( (buffer[count] >= 0xFE76) && (buffer[count] <= 0xFE7B) ) || ( (buffer[count] >= 0xFE7E) && (buffer[count] <= 0xFE7F) ) ) { for(int idx = count; idx < length - tashkeelOcuurences - 1; idx++) buffer[idx] = buffer[idx + 1]; buffer[length - tashkeelOcuurences - 1] = 0x0020; tashkeelOcuurences++; } count ++; } } /** * Method handleTashkeelAuto. * * @param buffer The buffer containing the data to be processed. * @param length The buffer length. * */ private void handleTashkeelAuto(char[] buffer, int length){} }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy