private List <Run> Itemize(string s, bool rtl, int maxItems) { SCRIPT_ITEM[] pItems = new SCRIPT_ITEM[maxItems]; int pcItems = 0; // initialize Control and State SCRIPT_CONTROL control = new SCRIPT_CONTROL(); SCRIPT_STATE state = new SCRIPT_STATE(); if (rtl) { // this is needed to start paragraph from right state.SetRtl(); // to substitute arabic digits ScriptApplyDigitSubstitution(ref FDigitSubstitute, ref control, ref state); } // itemize ScriptItemize(s, s.Length, pItems.Length, ref control, ref state, pItems, ref pcItems); // create Run list. Note that ScriptItemize actually returns pcItems+1 items, // so this can be used to calculate char range easily List <Run> list = new List <Run>(); for (int i = 0; i < pcItems; i++) { string text = s.Substring(pItems[i].iCharPos, pItems[i + 1].iCharPos - pItems[i].iCharPos); list.Add(new Run(text, pItems[i].analysis)); } return(list); }
public SCRIPT_STATE GetAs_SCRIPT_STATE() { SCRIPT_STATE result = default(SCRIPT_STATE); result.word1 = (ushort)((this.uBidiLevel & 0x1F) | (this.fOverrideDirection & 1) << 5 | (this.fInhibitSymSwap & 1) << 6 | (this.fCharShape & 1) << 7 | (this.fDigitSubstitute & 1) << 8 | (this.fInhibitLigate & 1) << 9 | (this.fDisplayZWG & 1) << 10 | (this.fArabicNumContext & 1) << 11 | (this.fGcpClusters & 1) << 12 | (this.fReserved & 1) << 13 | (this.fEngineReserved & 3) << 14); return(result); }
internal SCRIPT_STATE GetAs_SCRIPT_STATE() { SCRIPT_STATE result = default(SCRIPT_STATE); result.word1 = (ushort)((uBidiLevel & 0x1F) | ((fOverrideDirection & 1) << 5) | ((fInhibitSymSwap & 1) << 6) | ((fCharShape & 1) << 7) | ((fDigitSubstitute & 1) << 8) | ((fInhibitLigate & 1) << 9) | ((fDisplayZWG & 1) << 10) | ((fArabicNumContext & 1) << 11) | ((fGcpClusters & 1) << 12) | ((fReserved & 1) << 13) | ((fEngineReserved & 3) << 14)); return(result); }
public static extern uint ScriptItemize( [MarshalAs(UnmanagedType.LPWStr)] string pwcInChars, int cInChars, int cMaxItems, ref SCRIPT_CONTROL psControl, ref SCRIPT_STATE psState, [In, Out] SCRIPT_ITEM[] pItems, ref int pcItems );
private static extern int ScriptApplyDigitSubstitution( ref SCRIPT_DIGITSUBSTITUTE psds, ref SCRIPT_CONTROL psc, ref SCRIPT_STATE pss);
/// <summary> /// Converts visual string to logical. /// </summary> /// <param name="value">A value to convert.</param> /// <param name="rtl">A base direction.</param> /// <param name="direction"> /// true for visual to logical, and false for logical to visual. /// </param> /// <returns>Converted string.</returns> public static string Convert(string value, bool rtl, bool direction) { if (value == null) { return(null); } int count = value.Length; if (count <= 1) { return(value); } if (NativeMethods.ScriptIsComplex( value, count, Constants.SIC_COMPLEX | Constants.SIC_NEUTRAL) != Constants.S_OK) { return(value); } var control = new SCRIPT_CONTROL(); var state = new SCRIPT_STATE(); int resultCount = 0; int maxCount = count + 1; //control.fInvertPreBoundDir = rtl ? 1 : 0; //control.fInvertPostBoundDir = rtl ? 1 : 0; state.uBidiLevel = rtl ? (ushort)1 : (ushort)0; var items = new SCRIPT_ITEM[maxCount]; if (NativeMethods.ScriptItemize( value, count, maxCount, ref control, ref state, items, out resultCount) != 0) { return(value); } byte[] levels = new byte[count]; for (int i = 0; i < resultCount; i++) { var level = items[i].a.s.uBidiLevel; for (int j = items[i].iCharPos, k = items[i + 1].iCharPos; j < k; j++) { levels[j] = (byte)level; } } var orders = new int[count]; if (NativeMethods.ScriptLayout(count, levels, orders, null) != 0) { return(value); } var result = new char[count]; for (int i = 0; i < count; i++) { var index = orders[i]; var c = value[index]; var level = levels[index]; if (direction && ((level & 1) == 1)) { // Minimal mirroring. switch (c) { case '{': { c = '}'; break; } case '}': { c = '{'; break; } case '(': { c = ')'; break; } case ')': { c = '('; break; } case '<': { c = '>'; break; } case '>': { c = '<'; break; } } } result[i] = c; } return(new string(result, 0, count)); }
/// <summary> /// Converts visual string to logical. /// </summary> /// <param name="value">A value to convert.</param> /// <param name="rtl">A base direction.</param> /// <param name="direction"> /// true for visual to logical, and false for logical to visual. /// </param> /// <returns>Converted string.</returns> public static string Convert(string value, bool rtl, bool direction) { if (value == null) { return null; } int count = value.Length; if (count <= 1) { return value; } if (NativeMethods.ScriptIsComplex( value, count, Constants.SIC_COMPLEX | Constants.SIC_NEUTRAL) != Constants.S_OK) { return value; } var control = new SCRIPT_CONTROL(); var state = new SCRIPT_STATE(); int resultCount = 0; int maxCount = count + 1; //control.fInvertPreBoundDir = rtl ? 1 : 0; //control.fInvertPostBoundDir = rtl ? 1 : 0; state.uBidiLevel = rtl ? (ushort)1 : (ushort)0; var items = new SCRIPT_ITEM[maxCount]; if (NativeMethods.ScriptItemize( value, count, maxCount, ref control, ref state, items, out resultCount) != 0) { return value; } byte[] levels = new byte[count]; for(int i = 0; i < resultCount; i++) { var level = items[i].a.s.uBidiLevel; for(int j = items[i].iCharPos, k = items[i + 1].iCharPos; j < k; j++) { levels[j] = (byte)level; } } var orders = new int[count]; if (NativeMethods.ScriptLayout(count, levels, orders, null) != 0) { return value; } var result = new char[count]; for(int i = 0; i < count; i++) { var index = orders[i]; var c = value[index]; var level = levels[index]; if (direction && ((level & 1) == 1)) { // Minimal mirroring. switch(c) { case '{': { c = '}'; break; } case '}': { c = '{'; break; } case '(': { c = ')'; break; } case ')': { c = '('; break; } case '<': { c = '>'; break; } case '>': { c = '<'; break; } } } result[i] = c; } return new string(result, 0, count); }