You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1527 lines
57 KiB
1527 lines
57 KiB
define(["dojo/_base/lang", "dojo/_base/declare", "dojo/Stateful"], |
|
function(lang,declare,Stateful) { |
|
lang.getObject("string", true, dojox); |
|
|
|
var BidiEngine = declare("dojox.string.BidiEngine", Stateful, { |
|
// summary: |
|
// This class provides a bidi transformation engine, i.e. |
|
// functions for reordering and shaping bidi text. |
|
// description: |
|
// Bidi stands for support for languages with a bidirectional script. |
|
// |
|
// Usually Unicode Bidi Algorithm used by OS platform (and web browsers) is capable of properly |
|
// transforming Bidi text and as a result it is adequately displayed on the screen. |
|
// However, in some situations, Unicode Bidi Algorithm is not invoked or is not properly applied. |
|
// This may occur in situation in which software responsible for rendering the text is not leveraging |
|
// Unicode Bidi Algorithm implemented by OS (e.g. GFX renderers). |
|
// |
|
// Bidi engine provided in this class implements Unicode Bidi Algorithm as specified at |
|
// http://www.unicode.org/reports/tr9/. |
|
// |
|
// For more information on basic Bidi concepts please read |
|
// "Bidirectional script support - A primer" available from |
|
// http://www.ibm.com/developerworks/websphere/library/techarticles/bidi/bidigen.html. |
|
// |
|
// As of February 2011, Bidi engine has following limitations: |
|
// |
|
// 1. No support for following numeric shaping options: |
|
// - H - Hindi, |
|
// - C - Contextual, |
|
// - N - Nominal. |
|
// 2. No support for following shaping options: |
|
// - I - Initial shaping, |
|
// - M - Middle shaping, |
|
// - F - Final shaping, |
|
// - B - Isolated shaping. |
|
// 3. No support for LRE/RLE/LRO/RLO/PDF (they are handled like neutrals). |
|
// 4. No support for Windows compatibility. |
|
// 5. No support for insert/remove marks. |
|
// 6. No support for code pages. |
|
// |
|
|
|
// Input Bidi layout in which inputText is passed to the function. |
|
inputFormat: "ILYNN", |
|
|
|
// Output Bidi layout to which inputText should be transformed. |
|
outputFormat: "VLNNN", |
|
|
|
// Array, containing positions of each character from the source text in the resulting text. |
|
sourceToTarget: [], |
|
|
|
// Array, containing positions of each character from the resulting text in the source text. |
|
targetToSource: [], |
|
|
|
// Array, containing bidi level of each character from the source text |
|
levels: [], |
|
|
|
bidiTransform: function (/*String*/text, /*String*/formatIn, /*String*/formatOut) { |
|
// summary: |
|
// Central public API for Bidi engine. Transforms the text according to formatIn, formatOut |
|
// parameters. If formatIn or formatOut parametrs are not valid throws an exception. |
|
// inputText: |
|
// Input text subject to application of Bidi transformation. |
|
// formatIn: |
|
// Input Bidi layout in which inputText is passed to the function. |
|
// formatOut: |
|
// Output Bidi layout to which inputText should be transformed. |
|
// description: |
|
// Both formatIn and formatOut parameters are 5 letters long strings. |
|
// For example - "ILYNN". Each letter is associated with specific attribute of Bidi layout. |
|
// Possible and default values for each one of the letters are provided below: |
|
// |
|
// First letter: |
|
// |
|
// - Letter position/index: |
|
// 1 |
|
// - Letter meaning: |
|
// Ordering Schema. |
|
// - Possible values: |
|
// - I - Implicit (Logical). |
|
// - V - Visual. |
|
// - Default value: |
|
// I |
|
// |
|
// Second letter: |
|
// |
|
// - Letter position/index: |
|
// 2 |
|
// - Letter meaning: |
|
// Orientation. |
|
// - Possible values: |
|
// - L - Left To Right. |
|
// - R - Right To Left. |
|
// - C - Contextual Left to Right. |
|
// - D - Contextual Right to Left. |
|
// - Default value: |
|
// L |
|
// |
|
// Third letter: |
|
// |
|
// - Letter position/index: |
|
// 3 |
|
// - Letter meaning: |
|
// Symmetric Swapping. |
|
// - Possible values: |
|
// - Y - Symmetric swapping is on. |
|
// - N - Symmetric swapping is off. |
|
// - Default value: |
|
// Y |
|
// |
|
// Fourth letter: |
|
// |
|
// - Letter position/index: |
|
// 4 |
|
// - Letter meaning: |
|
// Shaping. |
|
// - Possible values: |
|
// - S - Text is shaped. |
|
// - N - Text is not shaped. |
|
// - Default value: |
|
// N |
|
// |
|
// Fifth letter: |
|
// |
|
// - Letter position/index: |
|
// 5 |
|
// - Letter meaning: |
|
// Numeric Shaping. |
|
// - Possible values: |
|
// - N - Nominal. |
|
// - Default value: |
|
// N |
|
// |
|
// The output of this function is original text (passed via first argument) transformed from |
|
// input Bidi layout (second argument) to output Bidi layout (last argument). |
|
// |
|
// Sample call: |
|
// | mytext = bidiTransform("HELLO WORLD", "ILYNN", "VLYNN"); |
|
// In this case, "HELLO WORLD" text is transformed from Logical - LTR to Visual - LTR Bidi layout |
|
// with default values for symmetric swapping (Yes), shaping (Not shaped) and numeric shaping |
|
// (Nominal). |
|
// returns: String |
|
// Original text transformed from input Bidi layout (second argument) |
|
// to output Bidi layout (last argument). |
|
// Throws an exception if the bidi layout strings are not valid. |
|
// tags: |
|
// public |
|
|
|
this.sourceToTarget = []; |
|
this.targetToSource = []; |
|
if (!text) { |
|
return ""; |
|
} |
|
initMaps(this.sourceToTarget, this.targetToSource, text.length); |
|
if (!this.checkParameters(formatIn, formatOut)) { |
|
return text; |
|
} |
|
|
|
formatIn = this.inputFormat; |
|
formatOut = this.outputFormat; |
|
var result = text; |
|
var bdx = BDX; |
|
var orientIn = getOrientation(formatIn.charAt(1)), |
|
orientOut = getOrientation(formatOut.charAt(1)), |
|
osIn = (formatIn.charAt(0) === "I") ? "L" : formatIn.charAt(0), |
|
osOut = (formatOut.charAt(0) === "I") ? "L" : formatOut.charAt(0), |
|
inFormat = osIn + orientIn, |
|
outFormat = osOut + orientOut, |
|
swap = formatIn.charAt(2) + formatOut.charAt(2); |
|
|
|
bdx.defInFormat = inFormat; |
|
bdx.defOutFormat = outFormat; |
|
bdx.defSwap = swap; |
|
|
|
var stage1Text = doBidiReorder(text, inFormat, outFormat, swap, bdx), |
|
isRtl = false; |
|
|
|
if (formatOut.charAt(1) === "R") { |
|
isRtl = true; |
|
} else if (formatOut.charAt(1) === "C" || formatOut.charAt(1) === "D") { |
|
isRtl = this.checkContextual(stage1Text); |
|
} |
|
|
|
this.sourceToTarget = stMap; |
|
this.targetToSource = reverseMap(this.sourceToTarget); |
|
tsMap = this.targetToSource; |
|
|
|
if (formatIn.charAt(3) === formatOut.charAt(3)) { |
|
result = stage1Text; |
|
} else if (formatOut.charAt(3) === "S") { |
|
result = shape(isRtl, stage1Text, true); |
|
} else { //formatOut.charAt(3) === "N" |
|
result = deshape(stage1Text, isRtl, true); |
|
} |
|
this.sourceToTarget = stMap; |
|
this.targetToSource = tsMap; |
|
this.levels = lvMap; |
|
return result; |
|
}, |
|
|
|
_inputFormatSetter: function (format) { |
|
if (!validFormat.test(format)) { |
|
throw new Error("dojox/string/BidiEngine: the bidi layout string is wrong!"); |
|
} |
|
this.inputFormat = format; |
|
}, |
|
|
|
_outputFormatSetter: function (format) { |
|
if (!validFormat.test(format)) { |
|
throw new Error("dojox/string/BidiEngine: the bidi layout string is wrong!"); |
|
} |
|
this.outputFormat = format; |
|
}, |
|
|
|
checkParameters: function (/*String*/formatIn, /*String*/formatOut) { |
|
// summary: |
|
// Checks layout parameters. |
|
// formatIn: |
|
// Input Bidi layout in which inputText is passed to the function. |
|
// formatOut: |
|
// Output Bidi layout to which inputText should be transformed. |
|
// description: |
|
// Checks, that layout parameters are different and contain allowed values. |
|
// Allowed values for format string are: |
|
// - 1st letter: I, V |
|
// - 2nd letter: L, R, C, D |
|
// - 3rd letter: Y, N |
|
// - 4th letter: S, N |
|
// - 5th letter: N |
|
// returns: /*Boolean*/ |
|
// true - if layout parameters are valid. |
|
// false - otherwise. |
|
// tags: |
|
// private |
|
|
|
if (!formatIn) { |
|
formatIn = this.inputFormat; |
|
} else { |
|
this.set("inputFormat", formatIn); |
|
} |
|
if (!formatOut) { |
|
formatOut = this.outputFormat; |
|
} else { |
|
this.set("outputFormat", formatOut); |
|
} |
|
if (formatIn === formatOut) { |
|
return false; |
|
} |
|
return true; |
|
}, |
|
|
|
checkContextual: function (/*String*/text) { |
|
// summary: |
|
// Determine the base direction of a bidi text according |
|
// to its first strong directional character. |
|
// text: |
|
// The text to check. |
|
// returns: /*String*/ |
|
// "ltr" or "rtl" according to the first strong character. |
|
// If there is no strong character, returns the value of the |
|
// document dir property. |
|
// tags: |
|
// public |
|
var dir = firstStrongDir(text); |
|
if (dir !== "ltr" && dir !== "rtl") { |
|
try { |
|
dir = document.dir.toLowerCase(); |
|
} catch (e) { |
|
} |
|
if (dir !== "ltr" && dir !== "rtl") { |
|
dir = "ltr"; |
|
} |
|
} |
|
return dir; |
|
}, |
|
|
|
hasBidiChar: function (/*String*/text) { |
|
// summary: |
|
// Return true if text contains RTL directed character. |
|
// text: |
|
// The source string. |
|
// description: |
|
// Searches for RTL directed character. |
|
// Returns true if found, else returns false. |
|
// returns: /*Boolean*/ |
|
// true - if text has a RTL directed character. |
|
// false - otherwise. |
|
// tags: |
|
// public |
|
|
|
return bidiChars.test(text); |
|
} |
|
}); |
|
|
|
function doBidiReorder(/*String*/text, /*String*/inFormat, |
|
/*String*/outFormat, /*String*/swap, /*Object*/bdx) { |
|
// summary: |
|
// Reorder the source text according to the bidi attributes |
|
// of source and result. |
|
// text: |
|
// The text to reorder. |
|
// inFormat: |
|
// Ordering scheme and base direction of the source text. |
|
// Can be "LLTR", "LRTL", "LCLR", "LCRL", "VLTR", "VRTL", |
|
// "VCLR", "VCRL". |
|
// The first letter is "L" for logical ordering scheme, |
|
// "V" for visual ordering scheme. |
|
// The other letters specify the base direction. |
|
// "CLR" means contextual direction defaulting to LTR if |
|
// there is no strong letter. |
|
// "CRL" means contextual direction defaulting to RTL if |
|
// there is no strong letter. |
|
// The initial value is "LLTR", if none, the initial value is used. |
|
// outFormat: |
|
// Required ordering scheme and base direction of the |
|
// result. Has the same format as inFormat. |
|
// If none, the initial value "VLTR" is used. |
|
// swap: |
|
// Symmetric swapping attributes of source and result. |
|
// The allowed values can be "YN", "NY", "YY" and "NN". |
|
// The first letter reflects the symmetric swapping attribute |
|
// of the source, the second letter that of the result. |
|
// bdx: Object |
|
// Used for intermediate data storage |
|
// returns: |
|
// Text reordered according to source and result attributes. |
|
|
|
var params = prepareReorderingParameters(text, {inFormat: inFormat, outFormat: outFormat, swap: swap}, bdx); |
|
if (params.inFormat === params.outFormat) { |
|
return text; |
|
} |
|
inFormat = params.inFormat; |
|
outFormat = params.outFormat; |
|
swap = params.swap; |
|
var inOrdering = inFormat.substring(0, 1), |
|
inOrientation = inFormat.substring(1, 4), |
|
outOrdering = outFormat.substring(0, 1), |
|
outOrientation = outFormat.substring(1, 4); |
|
bdx.inFormat = inFormat; |
|
bdx.outFormat = outFormat; |
|
bdx.swap = swap; |
|
if ((inOrdering === "L") && (outFormat === "VLTR")) { //core cases |
|
//cases: LLTR->VLTR, LRTL->VLTR |
|
if (inOrientation === "LTR") { |
|
bdx.dir = LTR; |
|
return doReorder(text, bdx); |
|
} |
|
if (inOrientation === "RTL") { |
|
bdx.dir = RTL; |
|
return doReorder(text, bdx); |
|
} |
|
} |
|
if ((inOrdering === "V") && (outOrdering === "V")) { |
|
//inOrientation != outOrientation |
|
//cases: VRTL->VLTR, VLTR->VRTL |
|
bdx.dir = inOrientation === "RTL"? RTL : LTR; |
|
return invertStr(text, bdx); |
|
} |
|
if ((inOrdering === "L") && (outFormat === "VRTL")) { |
|
//cases: LLTR->VRTL, LRTL->VRTL |
|
if (inOrientation === "LTR") { |
|
bdx.dir = LTR; |
|
text = doReorder(text, bdx); |
|
} else { |
|
//inOrientation == RTL |
|
bdx.dir = RTL; |
|
text = doReorder(text, bdx); |
|
} |
|
return invertStr(text); |
|
} |
|
if ((inFormat === "VLTR") && (outFormat === "LLTR")) { |
|
//case: VLTR->LLTR |
|
bdx.dir = LTR; |
|
return doReorder(text, bdx); |
|
} |
|
if ((inOrdering === "V") && (outOrdering === "L") && (inOrientation !== outOrientation)) { |
|
//cases: VLTR->LRTL, VRTL->LLTR |
|
text = invertStr(text); |
|
return (inOrientation === "RTL") ? doBidiReorder(text, "LLTR", "VLTR", swap, bdx) : |
|
doBidiReorder(text, "LRTL", "VRTL", swap, bdx); |
|
} |
|
if ((inFormat === "VRTL") && (outFormat === "LRTL")) { |
|
//case VRTL->LRTL |
|
return doBidiReorder(text, "LRTL", "VRTL", swap, bdx); |
|
} |
|
if ((inOrdering === "L") && (outOrdering === "L")) { |
|
//inOrientation != outOrientation |
|
//cases: LRTL->LLTR, LLTR->LRTL |
|
var saveSwap = bdx.swap; |
|
bdx.swap = saveSwap.substr(0, 1) + "N"; |
|
if (inOrientation === "RTL") { |
|
//LRTL->LLTR |
|
bdx.dir = RTL; |
|
text = doReorder(text, bdx); |
|
bdx.swap = "N" + saveSwap.substr(1, 2); |
|
bdx.dir = LTR; |
|
text = doReorder(text, bdx); |
|
} else { //LLTR->LRTL |
|
bdx.dir = LTR; |
|
text = doReorder(text, bdx); |
|
bdx.swap = "N" + saveSwap.substr(1, 2); |
|
text = doBidiReorder(text, "VLTR", "LRTL", bdx.swap, bdx); |
|
} |
|
return text; |
|
} |
|
} |
|
|
|
function prepareReorderingParameters(/*String*/text, /*Object*/params, /*Object*/bdx) { |
|
// summary: |
|
// Prepare reordering parameters |
|
// text: |
|
// The text to reorder. |
|
// params: |
|
// Object, containing reordering parameters: |
|
// - inFormat: Ordering scheme and base direction of the source text. |
|
// - outFormat: Required ordering scheme and base direction of the result. |
|
// - swap: Symmetric swapping attributes of source and result. |
|
// bdx: Object |
|
// Used for intermediate data storage |
|
// tags: |
|
// private |
|
|
|
if (params.inFormat === undefined) { |
|
params.inFormat = bdx.defInFormat; |
|
} |
|
if (params.outFormat === undefined) { |
|
params.outFormat = bdx.defOutFormat; |
|
} |
|
if (params.swap === undefined) { |
|
params.swap = bdx.defSwap; |
|
} |
|
if (params.inFormat === params.outFormat) { |
|
return params; |
|
} |
|
var dir, inOrdering = params.inFormat.substring(0, 1), |
|
inOrientation = params.inFormat.substring(1, 4), |
|
outOrdering = params.outFormat.substring(0, 1), |
|
outOrientation = params.outFormat.substring(1, 4); |
|
if (inOrientation.charAt(0) === "C") { |
|
dir = firstStrongDir(text); |
|
if (dir === "ltr" || dir === "rtl") { |
|
inOrientation = dir.toUpperCase(); |
|
} else { |
|
inOrientation = params.inFormat.charAt(2) === "L" ? "LTR" : "RTL"; |
|
} |
|
params.inFormat = inOrdering + inOrientation; |
|
} |
|
if (outOrientation.charAt(0) === "C") { |
|
dir = firstStrongDir(text); |
|
if (dir === "rtl") { |
|
outOrientation = "RTL"; |
|
} else if (dir === "ltr") { |
|
dir = lastStrongDir(text); |
|
outOrientation = dir.toUpperCase(); |
|
} else { |
|
outOrientation = params.outFormat.charAt(2) === "L" ? "LTR" : "RTL"; |
|
} |
|
params.outFormat = outOrdering + outOrientation; |
|
} |
|
return params; |
|
} |
|
|
|
function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress) { |
|
// summary: |
|
// Shape the source text. |
|
// rtl: |
|
// Flag indicating if the text is in RTL direction (logical |
|
// direction for Arabic words). |
|
// text: |
|
// The text to shape. |
|
// compress: |
|
// A flag indicates to insert extra space after the lam alef compression |
|
// to preserve the buffer size or not insert an extra space which will lead |
|
// to decrease the buffer size. This option can be: |
|
// |
|
// - true (default) to not insert extra space after compressing Lam+Alef into one character Lamalef |
|
// - false to insert an extra space after compressed Lamalef to preserve the buffer size |
|
// returns: |
|
// text shaped. |
|
// tags: |
|
// private. |
|
|
|
if (text.length === 0) { |
|
return; |
|
} |
|
if (rtl === undefined) { |
|
rtl = true; |
|
} |
|
if (compress === undefined) { |
|
compress = true; |
|
} |
|
text = String(text); |
|
|
|
var str06 = text.split(""), |
|
Ix = 0, |
|
step = +1, |
|
nIEnd = str06.length; |
|
if (!rtl) { |
|
Ix = str06.length - 1; |
|
step = -1; |
|
nIEnd = 1; |
|
} |
|
var compressArray = doShape(str06, Ix, step, nIEnd, compress); |
|
var outBuf = ""; |
|
for (var idx = 0; idx < str06.length; idx++) { |
|
if (!(compress && indexOf(compressArray, compressArray.length, idx) > -1)) { |
|
outBuf += str06[idx]; |
|
} else { |
|
updateMap(tsMap, idx, !rtl, -1); |
|
stMap.splice(idx, 1); |
|
} |
|
} |
|
return outBuf; |
|
} |
|
|
|
function doShape(str06, Ix, step, nIEnd, compress) { |
|
// summary: |
|
// Shape the source text. |
|
// str06: |
|
// Array containing source text |
|
// Ix: |
|
// Index of the first handled element |
|
// step: |
|
// direction of the process |
|
// nIEnd: |
|
// Index of the last handled element |
|
// compress: |
|
// A flag indicates to insert extra space after the lam alef compression |
|
// to preserve the buffer size or not insert an extra space which will lead |
|
// to decrease the buffer size. |
|
// returns: |
|
// Array, contained shaped text. |
|
// tags: |
|
// private. |
|
|
|
var previousCursive = 0, compressArray = [], compressArrayIndx = 0; |
|
for (var index = Ix; index * step < nIEnd; index = index + step) { |
|
if (isArabicAlefbet(str06[index]) || isArabicDiacritics(str06[index])) { |
|
// Arabic letter Lam |
|
if (str06[index] === "\u0644" && isNextAlef(str06, (index + step), step, nIEnd)) { |
|
str06[index] = (previousCursive === 0) ? |
|
getLamAlefFE(str06[index + step], LamAlefInialTableFE) : |
|
getLamAlefFE(str06[index + step], LamAlefMedialTableFE); |
|
index += step; |
|
setAlefToSpace(str06, index, step, nIEnd); |
|
if (compress) { |
|
compressArray[compressArrayIndx] = index; |
|
compressArrayIndx++; |
|
} |
|
previousCursive = 0; |
|
continue; |
|
} |
|
var currentChr = str06[index]; |
|
if (previousCursive === 1) { |
|
// if next is Arabic |
|
// Character is in medial form |
|
// else character is in final form |
|
str06[index] = (isNextArabic(str06, (index + step), step, nIEnd)) ? |
|
getMedialFormCharacterFE(str06[index]) : getFormCharacterFE(str06[index], FinalForm); |
|
} else { |
|
if (isNextArabic(str06, (index + step), step, nIEnd) === true) { |
|
//character is in Initial form |
|
str06[index] = getFormCharacterFE(str06[index], InitialForm); |
|
} else { |
|
str06[index] = getFormCharacterFE(str06[index], IsolatedForm); |
|
} |
|
} |
|
//exam if the current character is cursive |
|
if (!isArabicDiacritics(currentChr)) { |
|
previousCursive = 1; |
|
} |
|
if (isStandAlonCharacter(currentChr) === true) { |
|
previousCursive = 0; |
|
} |
|
} else { |
|
previousCursive = 0; |
|
} |
|
} |
|
return compressArray; |
|
} |
|
|
|
function firstStrongDir(/*String*/text) { |
|
// summary: |
|
// Return the first strong character direction |
|
// text: |
|
// The source string. |
|
// description: |
|
// Searches for first "strong" character. |
|
// Returns if strong character was found with the direction defined by this |
|
// character, if no strong character was found returns an empty string. |
|
// returns: String |
|
// "ltr" - if the first strong character is Latin. |
|
// "rtl" - if the first strong character is RTL directed character. |
|
// "" - if the strong character wasn't found. |
|
// tags: |
|
// private |
|
|
|
var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text); |
|
// if found return the direction that defined by the character |
|
return fdc ? (fdc[0] <= "z" ? "ltr" : "rtl") : ""; |
|
} |
|
|
|
function lastStrongDir(text) { |
|
// summary: |
|
// Return the last strong character direction |
|
// text: |
|
// The source string. |
|
// description: |
|
// Searches for first (from the end) "strong" character. |
|
// Returns if strong character was found with the direction defined by this |
|
// character, if no strong character was found returns an empty string. |
|
// tags: |
|
// private |
|
var chars = text.split(""); |
|
chars.reverse(); |
|
return firstStrongDir(chars.join("")); |
|
} |
|
|
|
function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consumeNextSpace) { |
|
// summary: |
|
// deshape the source text. |
|
// text: |
|
// the text to be deshape. |
|
// rtl: |
|
// flag indicating if the text is in RTL direction (logical |
|
// direction for Arabic words). |
|
// consumeNextSpace: |
|
// flag indicating whether to consume the space next to the |
|
// the lam alef if there is a space followed the Lamalef character to preserve the buffer size. |
|
// In case there is no space next to the lam alef the buffer size will be increased due to the |
|
// expansion of the lam alef one character into lam+alef two characters |
|
// returns: |
|
// text deshaped. |
|
if (text.length === 0) { |
|
return; |
|
} |
|
if (consumeNextSpace === undefined) { |
|
consumeNextSpace = true; |
|
} |
|
if (rtl === undefined) { |
|
rtl = true; |
|
} |
|
text = String(text); |
|
|
|
var outBuf = "", strFE = []; |
|
strFE = text.split(""); |
|
for (var i = 0; i < text.length; i++) { |
|
var increase = false; |
|
if (strFE[i] >= "\uFE70" && strFE[i] < "\uFEFF") { |
|
var chNum = text.charCodeAt(i); |
|
if (strFE[i] >= "\uFEF5" && strFE[i] <= "\uFEFC") { |
|
//expand the LamAlef |
|
if (rtl) { |
|
//Lam + Alef |
|
if (i > 0 && consumeNextSpace && strFE[i - 1] === " ") { |
|
outBuf = outBuf.substring(0, outBuf.length - 1) + "\u0644"; |
|
} else { |
|
outBuf += "\u0644"; |
|
increase = true; |
|
} |
|
outBuf += AlefTable[(chNum - 65269) / 2]; |
|
} else { |
|
outBuf += AlefTable[(chNum - 65269) / 2]; |
|
outBuf += "\u0644"; |
|
if (i + 1 < text.length && consumeNextSpace && strFE[i + 1] === " ") { |
|
i++; |
|
} else { |
|
increase = true; |
|
} |
|
} |
|
if (increase) { |
|
updateMap(tsMap, i, true, 1); |
|
stMap.splice(i, 0, stMap[i]); |
|
} |
|
} else { |
|
outBuf += FETo06Table[chNum - 65136]; |
|
} |
|
} else { |
|
outBuf += strFE[i]; |
|
} |
|
} |
|
return outBuf; |
|
} |
|
|
|
function doReorder(str, bdx) { |
|
// summary: |
|
// Helper to the doBidiReorder. Manages the UBA. |
|
// str: |
|
// the string to reorder. |
|
// bdx: Object |
|
// Used for intermediate data storage |
|
// returns: |
|
// text reordered according to source and result attributes. |
|
// tags: |
|
// private |
|
var chars = str.split(""), levels = []; |
|
|
|
computeLevels(chars, levels, bdx); |
|
swapChars(chars, levels, bdx); |
|
invertLevel(2, chars, levels, bdx); |
|
invertLevel(1, chars, levels, bdx); |
|
lvMap = levels; |
|
return chars.join(""); |
|
} |
|
|
|
function computeLevels(chars, levels, bdx) { |
|
var len = chars.length, |
|
impTab = bdx.dir ? impTabRtl : impTabLtr, |
|
prevState = null, newClass = null, newLevel = null, newState = 0, |
|
action = null, cond = null, condPos = -1, i = null, ix = null, |
|
types = [], |
|
classes = []; |
|
bdx.hiLevel = bdx.dir; |
|
bdx.lastArabic = false; |
|
bdx.hasUbatAl = false; |
|
bdx.hasUbatB = false; |
|
bdx.hasUbatS = false; |
|
for (i = 0; i < len; i++) { |
|
types[i] = getCharacterType(chars[i]); |
|
} |
|
for (ix = 0; ix < len; ix++) { |
|
prevState = newState; |
|
classes[ix] = newClass = getCharClass(chars, types, classes, ix, bdx); |
|
newState = impTab[prevState][newClass]; |
|
action = newState & 0xF0; |
|
newState &= 0x0F; |
|
levels[ix] = newLevel = impTab[newState][ITIL]; |
|
if (action > 0) { |
|
if (action === 0x10) { // set conditional run to level 1 |
|
for (i = condPos; i < ix; i++) { |
|
levels[i] = 1; |
|
} |
|
condPos = -1; |
|
} else { // 0x20 confirm the conditional run |
|
condPos = -1; |
|
} |
|
} |
|
cond = impTab[newState][ITCOND]; |
|
if (cond) { |
|
if (condPos === -1) { |
|
condPos = ix; |
|
} |
|
} else { // unconditional level |
|
if (condPos > -1) { |
|
for (i = condPos; i < ix; i++) { |
|
levels[i] = newLevel; |
|
} |
|
condPos = -1; |
|
} |
|
} |
|
if (types[ix] === UBAT_B) { |
|
levels[ix] = 0; |
|
} |
|
bdx.hiLevel |= newLevel; |
|
} |
|
if (bdx.hasUbatS) { |
|
handleUbatS(types, levels, len, bdx); |
|
} |
|
} |
|
|
|
function handleUbatS(types, levels, len, bdx) { |
|
for (var i = 0; i < len; i++) { |
|
if (types[i] === UBAT_S) { |
|
levels[i] = bdx.dir; |
|
for (var j = i - 1; j >= 0; j--) { |
|
if (types[j] === UBAT_WS) { |
|
levels[j] = bdx.dir; |
|
} else { |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
function swapChars(chars, levels, bdx) { |
|
// summary: |
|
// Swap characters with symmetrical mirroring as all kinds of parenthesis. |
|
// (When needed). |
|
// chars: |
|
// The source string as Array of characters. |
|
// levels: |
|
// An array (like hash) of flags for each character in the source string, |
|
// that defines if swapping should be applied on the following character. |
|
// bdx: Object |
|
// Used for intermediate data storage |
|
// tags: |
|
// private |
|
|
|
if (bdx.hiLevel === 0 || bdx.swap.substr(0, 1) === bdx.swap.substr(1, 2)) { |
|
return; |
|
} |
|
for (var i = 0; i < chars.length; i++) { |
|
if (levels[i] === 1) { |
|
chars[i] = getMirror(chars[i]); |
|
} |
|
} |
|
} |
|
|
|
function getCharacterType(ch) { |
|
// summary: |
|
// Return the type of the character. |
|
// ch: |
|
// The character to be checked. |
|
|
|
// description: |
|
// Check the type of the character according to MasterTable, |
|
// type = LTR, RTL, neutral,Arabic-Indic digit etc. |
|
// tags: |
|
// private |
|
var uc = ch.charCodeAt(0), |
|
hi = MasterTable[uc >> 8]; |
|
return (hi < TBBASE) ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF]; |
|
} |
|
|
|
function invertStr(str, bdx) { |
|
// summary: |
|
// Return the reversed string. |
|
// str: |
|
// The string to be reversed. |
|
// description: |
|
// Reverse the string str. |
|
// tags: |
|
// private |
|
var chars = str.split(""); |
|
if (bdx) { |
|
var levels = []; |
|
computeLevels(chars, levels, bdx); |
|
lvMap = levels; |
|
} |
|
chars.reverse(); |
|
stMap.reverse(); |
|
return chars.join(""); |
|
} |
|
|
|
function indexOf(cArray, cLength, idx) { |
|
for (var i = 0; i < cLength; i++) { |
|
if (cArray[i] === idx) { |
|
return i; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
function isArabicAlefbet(c) { |
|
for (var i = 0; i < ArabicAlefBetIntervalsBegine.length; i++) { |
|
if (c >= ArabicAlefBetIntervalsBegine[i] && c <= ArabicAlefBetIntervalsEnd[i]) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
function isNextArabic(str06, index, step, nIEnd) { |
|
while (((index) * step) < nIEnd && isArabicDiacritics(str06[index])) { |
|
index += step; |
|
} |
|
if (((index) * step) < nIEnd && isArabicAlefbet(str06[index])) { |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
function isNextAlef(str06, index, step, nIEnd) { |
|
while (((index) * step) < nIEnd && isArabicDiacritics(str06[index])) { |
|
index += step; |
|
} |
|
var c = " "; |
|
if (((index) * step) < nIEnd) { |
|
c = str06[index]; |
|
} else { |
|
return false; |
|
} |
|
for (var i = 0; i < AlefTable.length; i++) { |
|
if (AlefTable[i] === c) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
function invertLevel(lev, chars, levels, bdx) { |
|
if (bdx.hiLevel < lev) { |
|
return; |
|
} |
|
if (lev === 1 && bdx.dir === RTL && !bdx.hasUbatB) { |
|
chars.reverse(); |
|
stMap.reverse(); |
|
return; |
|
} |
|
var len = chars.length, start = 0, end, lo, hi, tmp; |
|
while (start < len) { |
|
if (levels[start] >= lev) { |
|
end = start + 1; |
|
while (end < len && levels[end] >= lev) { |
|
end++; |
|
} |
|
for (lo = start, hi = end - 1 ; lo < hi; lo++, hi--) { |
|
tmp = chars[lo]; |
|
chars[lo] = chars[hi]; |
|
chars[hi] = tmp; |
|
tmp = stMap[lo]; |
|
stMap[lo] = stMap[hi]; |
|
stMap[hi] = tmp; |
|
} |
|
start = end; |
|
} |
|
start++; |
|
} |
|
} |
|
|
|
function getCharClass(chars, types, classes, ix, bdx) { |
|
// summary: |
|
// Return the class if ix character in chars. |
|
// chars: |
|
// The source string as Array of characters. |
|
// types: |
|
// Array of types, for each character in chars. |
|
// classes: |
|
// Array of classes that already been solved. |
|
// ix: |
|
// the index of checked character. |
|
// bdx: Object |
|
// Used for intermediate data storage |
|
// tags: |
|
// private |
|
var cType = types[ix], |
|
results = { |
|
UBAT_L : function () { bdx.lastArabic = false; return UBAT_L; }, |
|
UBAT_R : function () { bdx.lastArabic = false; return UBAT_R; }, |
|
UBAT_ON : function () { return UBAT_ON; }, |
|
UBAT_AN : function () { return UBAT_AN; }, |
|
UBAT_EN : function () { return bdx.lastArabic ? UBAT_AN : UBAT_EN; }, |
|
UBAT_AL : function () { bdx.lastArabic = true; bdx.hasUbatAl = true; return UBAT_R; }, |
|
UBAT_WS : function () { return UBAT_ON; }, |
|
UBAT_CS : function () { |
|
var wType, nType; |
|
if (ix < 1 || (ix + 1) >= types.length || |
|
((wType = classes[ix - 1]) !== UBAT_EN && wType !== UBAT_AN) || |
|
((nType = types[ix + 1]) !== UBAT_EN && nType !== UBAT_AN)) { |
|
return UBAT_ON; |
|
} |
|
if (bdx.lastArabic) { |
|
nType = UBAT_AN; |
|
} |
|
return nType === wType ? nType : UBAT_ON; |
|
}, |
|
UBAT_ES : function () { |
|
var wType = ix > 0 ? classes[ix - 1] : UBAT_B; |
|
if (wType === UBAT_EN && (ix + 1) < types.length && types[ix + 1] === UBAT_EN) { |
|
return UBAT_EN; |
|
} |
|
return UBAT_ON; |
|
}, |
|
UBAT_ET : function () { |
|
if (ix > 0 && classes[ix - 1] === UBAT_EN) { |
|
return UBAT_EN; |
|
} |
|
if (bdx.lastArabic) { |
|
return UBAT_ON; |
|
} |
|
var i = ix + 1, |
|
len = types.length; |
|
while (i < len && types[i] === UBAT_ET) { |
|
i++; |
|
} |
|
if (i < len && types[i] === UBAT_EN) { |
|
return UBAT_EN; |
|
} |
|
return UBAT_ON; |
|
}, |
|
UBAT_NSM : function () { |
|
if (bdx.inFormat === "VLTR") { // visual to implicit transformation |
|
var len = types.length, |
|
i = ix + 1; |
|
while (i < len && types[i] === UBAT_NSM) { |
|
i++; |
|
} |
|
if (i < len) { |
|
var c = chars[ix], |
|
rtlCandidate = (c >= 0x0591 && c <= 0x08FF) || c === 0xFB1E, |
|
wType = types[i]; |
|
if (rtlCandidate && (wType === UBAT_R || wType === UBAT_AL)) { |
|
return UBAT_R; |
|
} |
|
} |
|
} |
|
if (ix < 1 || types[ix - 1] === UBAT_B) { |
|
return UBAT_ON; |
|
} |
|
return classes[ix - 1]; |
|
}, |
|
UBAT_B : function () { bdx.lastArabic = true; bdx.hasUbatB = true; return bdx.dir; }, |
|
UBAT_S : function () { bdx.hasUbatS = true; return UBAT_ON; }, |
|
UBAT_LRE : function () { bdx.lastArabic = false; return UBAT_ON; }, |
|
UBAT_RLE : function () { bdx.lastArabic = false; return UBAT_ON; }, |
|
UBAT_LRO : function () { bdx.lastArabic = false; return UBAT_ON; }, |
|
UBAT_RLO : function () { bdx.lastArabic = false; return UBAT_ON; }, |
|
UBAT_PDF : function () { bdx.lastArabic = false; return UBAT_ON; }, |
|
UBAT_BN : function () { return UBAT_ON; } |
|
}; |
|
return results[TYPES_NAMES[cType]](); |
|
} |
|
|
|
function getMirror(c) { |
|
// summary: |
|
// Calculates the mirrored character of c |
|
// c: |
|
// The character to be mirrored. |
|
// tags: |
|
// private |
|
var mid, low = 0, high = SwapTable.length - 1; |
|
|
|
while (low <= high) { |
|
mid = Math.floor((low + high) / 2); |
|
if (c < SwapTable[mid][0]) { |
|
high = mid - 1; |
|
} else if (c > SwapTable[mid][0]) { |
|
low = mid + 1; |
|
} else { |
|
return SwapTable[mid][1]; |
|
} |
|
} |
|
return c; |
|
} |
|
|
|
function isStandAlonCharacter(c) { |
|
for (var i = 0; i < StandAlonForm.length; i++) { |
|
if (StandAlonForm[i] === c) { |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
function getMedialFormCharacterFE(c) { |
|
for (var i = 0; i < BaseForm.length; i++) { |
|
if (c === BaseForm[i]) { |
|
return MedialForm[i]; |
|
} |
|
} |
|
return c; |
|
} |
|
|
|
function getFormCharacterFE(/*char*/ c, /*char[]*/formArr) { |
|
for (var i = 0; i < BaseForm.length; i++) { |
|
if (c === BaseForm[i]) { |
|
return formArr[i]; |
|
} |
|
} |
|
return c; |
|
} |
|
|
|
function isArabicDiacritics(c) { |
|
return (c >= "\u064b" && c <= "\u0655") ? true : false; |
|
} |
|
|
|
function getOrientation(/*Char*/ oc) { |
|
if (oc === "L") { |
|
return "LTR"; |
|
} |
|
if (oc === "R") { |
|
return "RTL"; |
|
} |
|
if (oc === "C") { |
|
return "CLR"; |
|
} |
|
if (oc === "D") { |
|
return "CRL"; |
|
} |
|
} |
|
|
|
function setAlefToSpace(str06, index, step, nIEnd) { |
|
while (((index) * step) < nIEnd && isArabicDiacritics(str06[index])) { |
|
index += step; |
|
} |
|
if (((index) * step) < nIEnd) { |
|
str06[index] = " "; |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
function getLamAlefFE(alef06, LamAlefForm) { |
|
for (var i = 0; i < AlefTable.length; i++) { |
|
if (alef06 === AlefTable[i]) { |
|
return LamAlefForm[i]; |
|
} |
|
} |
|
return alef06; |
|
} |
|
|
|
function initMaps(map1, map2, length) { |
|
stMap = []; |
|
lvMap = []; |
|
for (var i = 0; i < length; i++) { |
|
map1[i] = i; |
|
map2[i] = i; |
|
stMap[i] = i; |
|
} |
|
} |
|
|
|
function reverseMap(sourceMap) { |
|
var map = new Array(sourceMap.length); |
|
for (var i = 0; i < sourceMap.length; i++) { |
|
map[sourceMap[i]] = i; |
|
} |
|
return map; |
|
} |
|
|
|
function updateMap(map, value, isGreater, update) { |
|
for (var i = 0; i < map.length; i++) { |
|
if (map[i] > value || (!isGreater && map[i] === value)) { |
|
map[i] += update; |
|
} |
|
} |
|
} |
|
|
|
var stMap = []; |
|
var tsMap = []; |
|
var lvMap = []; |
|
|
|
var BDX = { |
|
dir: 0, |
|
defInFormat: "LLTR", |
|
defoutFormat: "VLTR", |
|
defSwap: "YN", |
|
inFormat: "LLTR", |
|
outFormat: "VLTR", |
|
swap: "YN", |
|
hiLevel: 0, |
|
lastArabic: false, |
|
hasUbatAl: false, |
|
hasBlockSep: false, |
|
hasSegSep: false |
|
}; |
|
|
|
var ITIL = 5; |
|
|
|
var ITCOND = 6; |
|
|
|
var LTR = 0; |
|
|
|
var RTL = 1; |
|
|
|
var validFormat = /^[(I|V)][(L|R|C|D)][(Y|N)][(S|N)][N]$/; |
|
|
|
var bidiChars = /[\u0591-\u06ff\ufb1d-\ufefc]/; |
|
|
|
/****************************************************************************/ |
|
/* Array in which directional characters are replaced by their symmetric. */ |
|
/****************************************************************************/ |
|
var SwapTable = [ |
|
[ "\u0028", "\u0029" ], /* Round brackets */ |
|
[ "\u0029", "\u0028" ], |
|
[ "\u003C", "\u003E" ], /* Less than/greater than */ |
|
[ "\u003E", "\u003C" ], |
|
[ "\u005B", "\u005D" ], /* Square brackets */ |
|
[ "\u005D", "\u005B" ], |
|
[ "\u007B", "\u007D" ], /* Curly brackets */ |
|
[ "\u007D", "\u007B" ], |
|
[ "\u00AB", "\u00BB" ], /* Double angle quotation marks */ |
|
[ "\u00BB", "\u00AB" ], |
|
[ "\u2039", "\u203A" ], /* single angle quotation mark */ |
|
[ "\u203A", "\u2039" ], |
|
[ "\u207D", "\u207E" ], /* Superscript parentheses */ |
|
[ "\u207E", "\u207D" ], |
|
[ "\u208D", "\u208E" ], /* Subscript parentheses */ |
|
[ "\u208E", "\u208D" ], |
|
[ "\u2264", "\u2265" ], /* Less/greater than or equal */ |
|
[ "\u2265", "\u2264" ], |
|
[ "\u2329", "\u232A" ], /* Angle brackets */ |
|
[ "\u232A", "\u2329" ], |
|
[ "\uFE59", "\uFE5A" ], /* Small round brackets */ |
|
[ "\uFE5A", "\uFE59" ], |
|
[ "\uFE5B", "\uFE5C" ], /* Small curly brackets */ |
|
[ "\uFE5C", "\uFE5B" ], |
|
[ "\uFE5D", "\uFE5E" ], /* Small tortoise shell brackets */ |
|
[ "\uFE5E", "\uFE5D" ], |
|
[ "\uFE64", "\uFE65" ], /* Small less than/greater than */ |
|
[ "\uFE65", "\uFE64" ] |
|
]; |
|
var AlefTable = ["\u0622", "\u0623", "\u0625", "\u0627"]; |
|
|
|
var LamAlefInialTableFE = ["\ufef5", "\ufef7", "\ufef9", "\ufefb"]; |
|
|
|
var LamAlefMedialTableFE = ["\ufef6", "\ufef8", "\ufefa", "\ufefc"]; |
|
/** |
|
* Arabic Characters in the base form |
|
*/ |
|
var BaseForm = ["\u0627", "\u0628", "\u062A", "\u062B", "\u062C", "\u062D", "\u062E", "\u062F", "\u0630", "\u0631", |
|
"\u0632", "\u0633", "\u0634", "\u0635", "\u0636", "\u0637", "\u0638", "\u0639", "\u063A", "\u0641", |
|
"\u0642", "\u0643", "\u0644", "\u0645", "\u0646", "\u0647", "\u0648", "\u064A", "\u0625", "\u0623", |
|
"\u0622", "\u0629", "\u0649", "\u0644", "\u0645", "\u0646", "\u0647", "\u0648", "\u064A", "\u0625", |
|
"\u0623", "\u0622", "\u0629", "\u0649", "\u06CC", "\u0626", "\u0624"]; |
|
|
|
/** |
|
* Arabic shaped characters in Isolated form |
|
*/ |
|
var IsolatedForm = ["\uFE8D", "\uFE8F", "\uFE95", "\uFE99", "\uFE9D", "\uFEA1", "\uFEA5", "\uFEA9", "\uFEAB", |
|
"\uFEAD", "\uFEAF", "\uFEB1", "\uFEB5", "\uFEB9", "\uFEBD", "\uFEC1", "\uFEC5", "\uFEC9", |
|
"\uFECD", "\uFED1", "\uFED5", "\uFED9", "\uFEDD", "\uFEE1", "\uFEE5", "\uFEE9", "\uFEED", |
|
"\uFEF1", "\uFE87", "\uFE83", "\uFE81", "\uFE93", "\uFEEF", "\uFBFC", "\uFE89", "\uFE85", |
|
"\uFE70", "\uFE72", "\uFE74", "\uFE76", "\uFE78", "\uFE7A", "\uFE7C", "\uFE7E", "\uFE80", |
|
"\uFE89", "\uFE85"]; |
|
|
|
/** |
|
* Arabic shaped characters in Final form |
|
*/ |
|
var FinalForm = ["\uFE8E", "\uFE90", "\uFE96", "\uFE9A", "\uFE9E", "\uFEA2", "\uFEA6", "\uFEAA", "\uFEAC", "\uFEAE", |
|
"\uFEB0", "\uFEB2", "\uFEB6", "\uFEBA", "\uFEBE", "\uFEC2", "\uFEC6", "\uFECA", "\uFECE", "\uFED2", |
|
"\uFED6", "\uFEDA", "\uFEDE", "\uFEE2", "\uFEE6", "\uFEEA", "\uFEEE", "\uFEF2", "\uFE88", "\uFE84", |
|
"\uFE82", "\uFE94", "\uFEF0", "\uFBFD", "\uFE8A", "\uFE86", "\uFE70", "\uFE72", "\uFE74", "\uFE76", |
|
"\uFE78", "\uFE7A", "\uFE7C", "\uFE7E", "\uFE80", "\uFE8A", "\uFE86"]; |
|
|
|
/** |
|
* Arabic shaped characters in Media form |
|
*/ |
|
var MedialForm = ["\uFE8E", "\uFE92", "\uFE98", "\uFE9C", "\uFEA0", "\uFEA4", "\uFEA8", "\uFEAA", "\uFEAC", |
|
"\uFEAE", "\uFEB0", "\uFEB4", "\uFEB8", "\uFEBC", "\uFEC0", "\uFEC4", "\uFEC8", "\uFECC", |
|
"\uFED0", "\uFED4", "\uFED8", "\uFEDC", "\uFEE0", "\uFEE4", "\uFEE8", "\uFEEC", "\uFEEE", |
|
"\uFEF4", "\uFE88", "\uFE84", "\uFE82", "\uFE94", "\uFEF0", "\uFBFF", "\uFE8C", "\uFE86", |
|
"\uFE71", "\uFE72", "\uFE74", "\uFE77", "\uFE79", "\uFE7B", "\uFE7D", "\uFE7F", "\uFE80", |
|
"\uFE8C", "\uFE86"]; |
|
|
|
/** |
|
* Arabic shaped characters in Initial form |
|
*/ |
|
var InitialForm = ["\uFE8D", "\uFE91", "\uFE97", "\uFE9B", "\uFE9F", "\uFEA3", "\uFEA7", "\uFEA9", "\uFEAB", |
|
"\uFEAD", "\uFEAF", "\uFEB3", "\uFEB7", "\uFEBB", "\uFEBF", "\uFEC3", "\uFEC7", "\uFECB", |
|
"\uFECF", "\uFED3", "\uFED7", "\uFEDB", "\uFEDF", "\uFEE3", "\uFEE7", "\uFEEB", "\uFEED", |
|
"\uFEF3", "\uFE87", "\uFE83", "\uFE81", "\uFE93", "\uFEEF", "\uFBFE", "\uFE8B", "\uFE85", |
|
"\uFE70", "\uFE72", "\uFE74", "\uFE76", "\uFE78", "\uFE7A", "\uFE7C", "\uFE7E", "\uFE80", |
|
"\uFE8B", "\uFE85"]; |
|
|
|
/** |
|
* Arabic characters that couldn't join to the next character |
|
*/ |
|
var StandAlonForm = ["\u0621", "\u0622", "\u0623", "\u0624", "\u0625", "\u0627", "\u0629", "\u062F", "\u0630", |
|
"\u0631", "\u0632", "\u0648", "\u0649"]; |
|
|
|
var FETo06Table = ["\u064B", "\u064B", "\u064C", "\u061F", "\u064D", "\u061F", "\u064E", "\u064E", "\u064F", |
|
"\u064F", "\u0650", "\u0650", "\u0651", "\u0651", "\u0652", "\u0652", "\u0621", "\u0622", |
|
"\u0622", "\u0623", "\u0623", "\u0624", "\u0624", "\u0625", "\u0625", "\u0626", "\u0626", |
|
"\u0626", "\u0626", "\u0627", "\u0627", "\u0628", "\u0628", "\u0628", "\u0628", "\u0629", |
|
"\u0629", "\u062A", "\u062A", "\u062A", "\u062A", "\u062B", "\u062B", "\u062B", "\u062B", |
|
"\u062C", "\u062C", "\u062C", "\u062c", "\u062D", "\u062D", "\u062D", "\u062D", "\u062E", |
|
"\u062E", "\u062E", "\u062E", "\u062F", "\u062F", "\u0630", "\u0630", "\u0631", "\u0631", |
|
"\u0632", "\u0632", "\u0633", "\u0633", "\u0633", "\u0633", "\u0634", "\u0634", "\u0634", |
|
"\u0634", "\u0635", "\u0635", "\u0635", "\u0635", "\u0636", "\u0636", "\u0636", "\u0636", |
|
"\u0637", "\u0637", "\u0637", "\u0637", "\u0638", "\u0638", "\u0638", "\u0638", "\u0639", |
|
"\u0639", "\u0639", "\u0639", "\u063A", "\u063A", "\u063A", "\u063A", "\u0641", "\u0641", |
|
"\u0641", "\u0641", "\u0642", "\u0642", "\u0642", "\u0642", "\u0643", "\u0643", "\u0643", |
|
"\u0643", "\u0644", "\u0644", "\u0644", "\u0644", "\u0645", "\u0645", "\u0645", "\u0645", |
|
"\u0646", "\u0646", "\u0646", "\u0646", "\u0647", "\u0647", "\u0647", "\u0647", "\u0648", |
|
"\u0648", "\u0649", "\u0649", "\u064A", "\u064A", "\u064A", "\u064A", "\uFEF5", "\uFEF6", |
|
"\uFEF7", "\uFEF8", "\uFEF9", "\uFEFA", "\uFEFB", "\uFEFC", "\u061F", "\u061F", "\u061F"]; |
|
|
|
var ArabicAlefBetIntervalsBegine = ["\u0621", "\u0641"]; |
|
|
|
var ArabicAlefBetIntervalsEnd = ["\u063A", "\u064a"]; |
|
|
|
var impTabLtr = [ |
|
/* L, R, EN, AN, N, IL, Cond */ |
|
[ 0, 3, 0, 1, 0, 0, 0 ], /* 0 LTR text */ |
|
[ 0, 3, 0, 1, 2, 2, 0 ], /* 1 LTR+AN */ |
|
[ 0, 3, 0, 0x11, 2, 0, 1 ], /* 2 LTR+AN+N */ |
|
[ 0, 3, 5, 5, 4, 1, 0 ], /* 3 RTL text */ |
|
[ 0, 3, 0x15, 0x15, 4, 0, 1 ], /* 4 RTL cont */ |
|
[ 0, 3, 5, 5, 4, 2, 0 ] /* 5 RTL+EN/AN */ |
|
]; |
|
var impTabRtl = [ |
|
/* L, R, EN, AN, N, IL, Cond */ |
|
[ 2, 0, 1, 1, 0, 1, 0 ], /* 0 RTL text */ |
|
[ 2, 0, 1, 1, 0, 2, 0 ], /* 1 RTL+EN/AN */ |
|
[ 2, 0, 2, 1, 3, 2, 0 ], /* 2 LTR text */ |
|
[ 2, 0, 2, 0x21, 3, 1, 1 ] /* 3 LTR+cont */ |
|
]; |
|
|
|
var UBAT_L = 0; /* left to right */ |
|
var UBAT_R = 1; /* right to left */ |
|
var UBAT_EN = 2; /* European digit */ |
|
var UBAT_AN = 3; /* Arabic-Indic digit */ |
|
var UBAT_ON = 4; /* neutral */ |
|
var UBAT_B = 5; /* block separator */ |
|
var UBAT_S = 6; /* segment separator */ |
|
var UBAT_AL = 7; /* Arabic Letter */ |
|
var UBAT_WS = 8; /* white space */ |
|
var UBAT_CS = 9; /* common digit separator */ |
|
var UBAT_ES = 10; /* European digit separator */ |
|
var UBAT_ET = 11; /* European digit terminator */ |
|
var UBAT_NSM = 12; /* Non Spacing Mark */ |
|
var UBAT_LRE = 13; /* LRE */ |
|
var UBAT_RLE = 14; /* RLE */ |
|
var UBAT_PDF = 15; /* PDF */ |
|
var UBAT_LRO = 16; /* LRO */ |
|
var UBAT_RLO = 17; /* RLO */ |
|
var UBAT_BN = 18; /* Boundary Neutral */ |
|
|
|
var TYPES_NAMES = [ "UBAT_L", "UBAT_R", "UBAT_EN", "UBAT_AN", "UBAT_ON", "UBAT_B", "UBAT_S", "UBAT_AL", "UBAT_WS", |
|
"UBAT_CS", "UBAT_ES", "UBAT_ET", "UBAT_NSM", "UBAT_LRE", "UBAT_RLE", "UBAT_PDF", "UBAT_LRO", |
|
"UBAT_RLO", "UBAT_BN" ]; |
|
var TBBASE = 100; |
|
|
|
var TB00 = TBBASE + 0; |
|
var TB05 = TBBASE + 1; |
|
var TB06 = TBBASE + 2; |
|
var TB07 = TBBASE + 3; |
|
var TB20 = TBBASE + 4; |
|
var TBFB = TBBASE + 5; |
|
var TBFE = TBBASE + 6; |
|
var TBFF = TBBASE + 7; |
|
|
|
var L = UBAT_L; |
|
var R = UBAT_R; |
|
var EN = UBAT_EN; |
|
var AN = UBAT_AN; |
|
var ON = UBAT_ON; |
|
var B = UBAT_B; |
|
var S = UBAT_S; |
|
var AL = UBAT_AL; |
|
var WS = UBAT_WS; |
|
var CS = UBAT_CS; |
|
var ES = UBAT_ES; |
|
var ET = UBAT_ET; |
|
var NSM = UBAT_NSM; |
|
var LRE = UBAT_LRE; |
|
var RLE = UBAT_RLE; |
|
var PDF = UBAT_PDF; |
|
var LRO = UBAT_LRO; |
|
var RLO = UBAT_RLO; |
|
var BN = UBAT_BN; |
|
|
|
var MasterTable = [ |
|
/*******************************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/*******************************************************************************************************/ |
|
/*0-*/ TB00, L, L, L, L, TB05, TB06, TB07, R, L, L, L, L, L, L, L, |
|
/*1-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*2-*/ TB20, ON, ON, ON, L, ON, L, ON, L, ON, ON, ON, L, L, ON, ON, |
|
/*3-*/ L, L, L, L, L, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*4-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, L, L, ON, |
|
/*5-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*6-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*7-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*8-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*9-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, L, |
|
/*A-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, |
|
/*B-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*C-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*D-*/ ON, ON, ON, ON, ON, ON, ON, L, L, ON, ON, L, L, ON, ON, L, |
|
/*E-*/ L, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*F-*/ ON, ON, ON, ON, ON, ON, ON, ON, L, L, L, TBFB, AL, AL, TBFE, TBFF |
|
]; |
|
|
|
var UnicodeTable = [ |
|
[ /* Table 00: Unicode 00xx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ BN, BN, BN, BN, BN, BN, BN, BN, BN, S, B, S, WS, B, BN, BN, |
|
/*1-*/ BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, B, B, B, S, |
|
/*2-*/ WS, ON, ON, ET, ET, ET, ON, ON, ON, ON, ON, ES, CS, ES, CS, CS, |
|
/*3-*/ EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, CS, ON, ON, ON, ON, ON, |
|
/*4-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*5-*/ L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, ON, |
|
/*6-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*7-*/ L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, BN, |
|
/*8-*/ BN, BN, BN, BN, BN, B, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, |
|
/*9-*/ BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, |
|
/*A-*/ CS, ON, ET, ET, ET, ET, ON, ON, ON, ON, L, ON, ON, BN, ON, ON, |
|
/*B-*/ ET, ET, EN, EN, ON, L, ON, ON, ON, EN, L, ON, ON, ON, ON, ON, |
|
/*C-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*D-*/ L, L, L, L, L, L, L, ON, L, L, L, L, L, L, L, L, |
|
/*E-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*F-*/ L, L, L, L, L, L, L, ON, L, L, L, L, L, L, L, L |
|
], |
|
[ /* Table 01: Unicode 05xx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*1-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*2-*/ L, L, L, L, L, L, L, L, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*3-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*4-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*5-*/ L, L, L, L, L, L, L, ON, ON, L, L, L, L, L, L, L, |
|
/*6-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*7-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*8-*/ L, L, L, L, L, L, L, L, ON, L, ON, ON, ON, ON, ON, ON, |
|
/*9-*/ ON, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*A-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*B-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, R, NSM, |
|
/*C-*/ R, NSM, NSM, R, NSM, NSM, R, NSM, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*D-*/ R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, |
|
/*E-*/ R, R, R, R, R, R, R, R, R, R, R, ON, ON, ON, ON, ON, |
|
/*F-*/ R, R, R, R, R, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON |
|
], |
|
[ /* Table 02: Unicode 06xx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ AN, AN, AN, AN, ON, ON, ON, ON, AL, ET, ET, AL, CS, AL, ON, ON, |
|
/*1-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, AL, ON, ON, AL, AL, |
|
/*2-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*3-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*4-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, NSM, NSM, NSM, NSM, NSM, |
|
/*5-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*6-*/ AN, AN, AN, AN, AN, AN, AN, AN, AN, AN, ET, AN, AN, AL, AL, AL, |
|
/*7-*/ NSM, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*8-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*9-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*A-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*B-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*C-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*D-*/ AL, AL, AL, AL, AL, AL, NSM, NSM, NSM, NSM, NSM, NSM, NSM, AN, ON, NSM, |
|
/*E-*/ NSM, NSM, NSM, NSM, NSM, AL, AL, NSM, NSM, ON, NSM, NSM, NSM, NSM, AL, AL, |
|
/*F-*/ EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, AL, AL, AL, AL, AL, AL |
|
], |
|
[ /* Table 03: Unicode 07xx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, ON, AL, |
|
/*1-*/ AL, NSM, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*2-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*3-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*4-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, ON, ON, AL, AL, AL, |
|
/*5-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*6-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*7-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*8-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*9-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*A-*/ AL, AL, AL, AL, AL, AL, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*B-*/ NSM, AL, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*C-*/ R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, |
|
/*D-*/ R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, |
|
/*E-*/ R, R, R, R, R, R, R, R, R, R, R, NSM, NSM, NSM, NSM, NSM, |
|
/*F-*/ NSM, NSM, NSM, NSM, R, R, ON, ON, ON, ON, R, ON, ON, ON, ON, ON |
|
], |
|
[ /* Table 04: Unicode 20xx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ WS, WS, WS, WS, WS, WS, WS, WS, WS, WS, WS, BN, BN, BN, L, R, |
|
/*1-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*2-*/ ON, ON, ON, ON, ON, ON, ON, ON, WS, B, LRE, RLE, PDF, LRO, RLO, CS, |
|
/*3-*/ ET, ET, ET, ET, ET, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*4-*/ ON, ON, ON, ON, CS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*5-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, WS, |
|
/*6-*/ BN, BN, BN, BN, BN, ON, ON, ON, ON, ON, BN, BN, BN, BN, BN, BN, |
|
/*7-*/ EN, L, ON, ON, EN, EN, EN, EN, EN, EN, ES, ES, ON, ON, ON, L, |
|
/*8-*/ EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, ES, ES, ON, ON, ON, ON, |
|
/*9-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, |
|
/*A-*/ ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, |
|
/*B-*/ ET, ET, ET, ET, ET, ET, ET, ET, ET, ET, ON, ON, ON, ON, ON, ON, |
|
/*C-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*D-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*E-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*F-*/ NSM, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON |
|
], |
|
[ /* Table 05: Unicode FBxx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ L, L, L, L, L, L, L, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*1-*/ ON, ON, ON, L, L, L, L, L, ON, ON, ON, ON, ON, R, NSM, R, |
|
/*2-*/ R, R, R, R, R, R, R, R, R, ES, R, R, R, R, R, R, |
|
/*3-*/ R, R, R, R, R, R, R, ON, R, R, R, R, R, ON, R, ON, |
|
/*4-*/ R, R, ON, R, R, ON, R, R, R, R, R, R, R, R, R, R, |
|
/*5-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*6-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*7-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*8-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*9-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*A-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*B-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*C-*/ AL, AL, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*D-*/ ON, ON, ON, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*E-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*F-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL |
|
], |
|
[ /* Table 06: Unicode FExx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, NSM, |
|
/*1-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*2-*/ NSM, NSM, NSM, NSM, NSM, NSM, NSM, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*3-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*4-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*5-*/ CS, ON, CS, ON, ON, CS, ON, ON, ON, ON, ON, ON, ON, ON, ON, ET, |
|
/*6-*/ ON, ON, ES, ES, ON, ON, ON, ON, ON, ET, ET, ON, ON, ON, ON, ON, |
|
/*7-*/ AL, AL, AL, AL, AL, ON, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*8-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*9-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*A-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*B-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*C-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*D-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*E-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, |
|
/*F-*/ AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, AL, ON, ON, BN |
|
], |
|
[ /* Table 07: Unicode FFxx */ |
|
/****************************************************************************************/ |
|
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ |
|
/****************************************************************************************/ |
|
/*0-*/ ON, ON, ON, ET, ET, ET, ON, ON, ON, ON, ON, ES, CS, ES, CS, CS, |
|
/*1-*/ EN, EN, EN, EN, EN, EN, EN, EN, EN, EN, CS, ON, ON, ON, ON, ON, |
|
/*2-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*3-*/ L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, ON, |
|
/*4-*/ ON, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*5-*/ L, L, L, L, L, L, L, L, L, L, L, ON, ON, ON, ON, ON, |
|
/*6-*/ ON, ON, ON, ON, ON, ON, L, L, L, L, L, L, L, L, L, L, |
|
/*7-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*8-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*9-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*A-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, |
|
/*B-*/ L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, ON, |
|
/*C-*/ ON, ON, L, L, L, L, L, L, ON, ON, L, L, L, L, L, L, |
|
/*D-*/ ON, ON, L, L, L, L, L, L, ON, ON, L, L, L, ON, ON, ON, |
|
/*E-*/ ET, ET, ON, ON, ON, ET, ET, ON, ON, ON, ON, ON, ON, ON, ON, ON, |
|
/*F-*/ ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON, ON |
|
] |
|
]; |
|
|
|
return BidiEngine; |
|
});
|
|
|