📄 shapearabic.c
字号:
default : return(0); break; }}/* *Name : specialChar *Function : Special Arabic characters need special handling in the shapeUnicode * function, this function returns 1 or 2 for these special characters */static int32_tspecialChar(UChar ch) { if( (ch>0x0621 && ch<0x0626)||(ch==0x0627)||(ch>0x062e && ch<0x0633)|| (ch>0x0647 && ch<0x064a)||(ch==0x0629) ) { return (1); } else if( ch>=0x064B && ch<= 0x0652 ) return (2); else if( (ch>=0x0653 && ch<= 0x0655) || ch == 0x0670 || (ch>=0xFE70 && ch<= 0xFE7F) ) return (3); else return (0);}/* *Name : getLink *Function : Resolves the link between the characters as * Arabic characters have four forms : * Isolated, Initial, Middle and Final Form */static UChargetLink(UChar ch) { if(ch >= 0x0622 && ch <= 0x06D3) { return(araLink[ch-0x0622]); } else if(ch == 0x200D) { return(3); } else if(ch >= 0x206D && ch <= 0x206F) { return(4); } else if(ch >= 0xFE70 && ch <= 0xFEFC) { return(presLink[ch-0xFE70]); } else { return(0); }}/* *Name : isTashkeelChar *Function : Returns 1 for Tashkeel characters else return 0 */static int32_tisTashkeelChar(UChar ch) { if( ch>=0x064B && ch<= 0x0652 ) return (1); else return (0);}/* *Name : shapeUnicode *Function : Converts an Arabic Unicode buffer in 06xx Range into a shaped * arabic Unicode buffer in FExx Range */static int32_tshapeUnicode(UChar *dest, int32_t sourceLength, int32_t destSize, int tashkeelFlag) { int32_t i, iend; int32_t prevPos, lastPos,Nx, Nw; unsigned int Shape; int32_t flag; int32_t lamalef_found = 0; UChar prevLink = 0, lastLink = 0, currLink, nextLink = 0; UChar wLamalef; /* * Converts the input buffer from FExx Range into 06xx Range * to make sure that all characters are in the 06xx range * even the lamalef is converted to the special region in * the 06xx range */ for (i = 0; i < sourceLength; i++) { UChar inputChar = dest[i]; if ( (inputChar >= 0xFE70) && (inputChar <= 0xFEFC)) { dest[i] = convertFEto06 [ (inputChar - 0xFE70) ] ; } } /* sets the index to the end of the buffer, together with the step point to -1 */ i = 0; iend = sourceLength; /* * This function resolves the link between the characters . * Arabic characters have four forms : * Isolated Form, Initial Form, Middle Form and Final Form */ currLink = getLink(dest[i]); prevPos = i; lastPos = i; Nx = sourceLength + 2, Nw = 0; while (i != iend) { /* If high byte of currLink > 0 then more than one shape */ if ((currLink & 0xFF00) > 0 || isTashkeelChar(dest[i])) { Nw = i + 1; while (Nx >= sourceLength) { /* we need to know about next char */ if(Nw == iend) { nextLink = 0; Nx = -1; } else { nextLink = getLink(dest[Nw]); if((nextLink & IRRELEVANT) == 0) { Nx = Nw; } else { Nw = Nw + 1; } } } if ( ((currLink & ALEFTYPE) > 0) && ((lastLink & LAMTYPE) > 0) ) { lamalef_found = 1; wLamalef = changeLamAlef(dest[i]); /*get from 0x065C-0x065f */ if ( wLamalef != 0) { dest[i] = ' '; /* The default case is to drop the Alef and replace */ dest[lastPos] =wLamalef; /* it by a space. */ i=lastPos; } lastLink = prevLink; currLink = getLink(wLamalef); } /* * 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(dest[i]); Shape = shapeTable[nextLink & (LINKR + LINKL)] [lastLink & (LINKR + LINKL)] [currLink & (LINKR + LINKL)]; if (flag == 1) { Shape = (Shape == 1 || Shape == 3) ? 1 : 0; } else if(flag == 2) { if( (lastLink & LINKL) && (nextLink & LINKR) && (tashkeelFlag == 1) && dest[i] != 0x064C && dest[i] != 0x064D ) { Shape = 1; if( (nextLink&ALEFTYPE) == ALEFTYPE && (lastLink&LAMTYPE) == LAMTYPE ) Shape = 0; } else { Shape = 0; } } if(flag == 2) { dest[i] = 0xFE70 + IrrelevantPos[(dest[i] - 0x064B)] + Shape; } else dest[i] = (UChar)((dest[i] < 0x0670 ? 0xFE70 : 0xFB50) + (currLink >> 8) + Shape); } /* move one notch forward */ if ((currLink & IRRELEVANT) == 0) { prevLink = lastLink; lastLink = currLink; prevPos = lastPos; lastPos = i; } i++; if (i == Nx) { currLink = nextLink; Nx = sourceLength + 2; } else if(i != iend) { currLink = getLink(dest[i]); } } destSize = sourceLength; return destSize;}int32_t shapeArabic(const UChar *source, int32_t sourceLength, UChar *dest, int32_t destCapacity, uint32_t options, UErrorCode *pErrorCode) { int32_t destLength; /* usual error checking */ if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return 0; } /* make sure that no reserved options values are used; allow dest==NULL only for preflighting */ if( source==NULL || sourceLength<-1 || (dest==NULL && destCapacity!=0) || destCapacity<0 || options>=U_SHAPE_DIGIT_TYPE_RESERVED || (options&U_SHAPE_DIGITS_MASK)>=U_SHAPE_DIGITS_RESERVED ) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } /* determine the source length */ if(sourceLength==-1) { sourceLength=u_strlen(source); } if(sourceLength==0) { return 0; } /* check that source and destination do not overlap */ if( dest!=NULL && ((source<=dest && dest<source+sourceLength) || (dest<=source && source<dest+destCapacity)) ) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return 0; } if((options&U_SHAPE_LETTERS_MASK)!=U_SHAPE_LETTERS_NOOP) { int32_t outputSize = sourceLength; /* calculate destination size */ /* TODO: do we ever need to do this pure preflighting? */ ASSERT((options&U_SHAPE_LENGTH_MASK) != U_SHAPE_LENGTH_GROW_SHRINK); if(outputSize>destCapacity) { *pErrorCode=U_BUFFER_OVERFLOW_ERROR; return outputSize; } /* Start of Arabic letter shaping part */ memcpy(dest, source, sourceLength*U_SIZEOF_UCHAR); ASSERT((options&U_SHAPE_TEXT_DIRECTION_MASK) == U_SHAPE_TEXT_DIRECTION_LOGICAL); switch(options&U_SHAPE_LETTERS_MASK) { case U_SHAPE_LETTERS_SHAPE : /* Call the shaping function with tashkeel flag == 1 */ destLength = shapeUnicode(dest,sourceLength,destCapacity,1); break; case U_SHAPE_LETTERS_SHAPE_TASHKEEL_ISOLATED : /* Call the shaping function with tashkeel flag == 0 */ destLength = shapeUnicode(dest,sourceLength,destCapacity,0); break; case U_SHAPE_LETTERS_UNSHAPE : ASSERT_NOT_REACHED(); break; default : /* will never occur because of validity checks above */ destLength = 0; break; } /* End of Arabic letter shaping part */ } else ASSERT_NOT_REACHED(); ASSERT((options & U_SHAPE_DIGITS_MASK) == U_SHAPE_DIGITS_NOOP); return sourceLength;}#endif // USE(ATSUI)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -