private static CultureInfo GetNumberCulture(TextRunProperties properties, out NumberSubstitutionMethod method, out bool ignoreUserOverride) { ignoreUserOverride = true; NumberSubstitution sub = properties.NumberSubstitution; if (sub == null) { method = NumberSubstitutionMethod.AsCulture; return(CultureMapper.GetSpecificCulture(properties.CultureInfo)); } method = sub.Substitution; switch (sub.CultureSource) { case NumberCultureSource.Text: return(CultureMapper.GetSpecificCulture(properties.CultureInfo)); case NumberCultureSource.User: ignoreUserOverride = false; return(CultureInfo.CurrentCulture); case NumberCultureSource.Override: return(sub.CultureOverride); } return(null); }
/// <summary> /// Initializes a NumberSubstitution object with explicit values. /// </summary> /// <param name="source">Specifies how the number culture is determined.</param> /// <param name="cultureOverride">Number culture if NumberCultureSource.Override is specified.</param> /// <param name="substitution">Type of number substitution to perform.</param> public NumberSubstitution( NumberCultureSource source, CultureInfo cultureOverride, NumberSubstitutionMethod substitution) { _source = source; _cultureOverride = ThrowIfInvalidCultureOverride(cultureOverride); _substitution = substitution; }
/// <summary> /// Setter for NumberSubstitution DependencyProperty /// </summary> public static void SetSubstitution(DependencyObject target, NumberSubstitutionMethod value) { if (target == null) { throw new ArgumentNullException("target"); } target.SetValue(SubstitutionProperty, value); }
/// <summary> /// Resolves number substitution method to one of following values: /// European /// Traditional /// NativeNational /// </summary> internal static NumberSubstitutionMethod GetResolvedSubstitutionMethod(TextRunProperties properties, CultureInfo digitCulture, out bool ignoreUserOverride) { ignoreUserOverride = true; NumberSubstitutionMethod resolvedMethod = NumberSubstitutionMethod.European; if (digitCulture != null) { NumberSubstitutionMethod method; CultureInfo numberCulture = GetNumberCulture(properties, out method, out ignoreUserOverride); if (numberCulture != null) { // First, disambiguate AsCulture method, which depends on digit substitution contained in CultureInfo.NumberFormat if (method == NumberSubstitutionMethod.AsCulture) { switch (numberCulture.NumberFormat.DigitSubstitution) { case DigitShapes.Context: method = NumberSubstitutionMethod.Context; break; case DigitShapes.NativeNational: method = NumberSubstitutionMethod.NativeNational; break; default: method = NumberSubstitutionMethod.European; break; } } // Next, disambiguate Context method, which maps to Traditional if digitCulture != null resolvedMethod = method; if (resolvedMethod == NumberSubstitutionMethod.Context) { resolvedMethod = NumberSubstitutionMethod.Traditional; } } } return(resolvedMethod); }
private CultureInfo GetDigitCulture(CultureInfo numberCulture, NumberSubstitutionMethod method, out bool contextual) { contextual = false; if (numberCulture == null) { return(null); } if (method == NumberSubstitutionMethod.AsCulture) { switch (numberCulture.NumberFormat.DigitSubstitution) { case DigitShapes.Context: method = NumberSubstitutionMethod.Context; break; case DigitShapes.NativeNational: method = NumberSubstitutionMethod.NativeNational; break; default: return(null); } } CultureInfo digitCulture; switch (method) { case NumberSubstitutionMethod.Context: if (IsArabic(numberCulture) || IsFarsi(numberCulture)) { contextual = true; digitCulture = GetTraditionalCulture(numberCulture); } else { digitCulture = null; } break; case NumberSubstitutionMethod.NativeNational: if (!HasLatinDigits(numberCulture)) { digitCulture = numberCulture; } else { digitCulture = null; } break; case NumberSubstitutionMethod.Traditional: digitCulture = GetTraditionalCulture(numberCulture); break; default: digitCulture = null; break; } return(digitCulture); }
internal void GetShapeableText( CharacterBufferReference characterBufferReference, int stringLength, TextRunProperties textRunProperties, CultureInfo digitCulture, bool isRightToLeftParagraph, IList <TextShapeableSymbols> shapeableList, IShapeableTextCollector collector, TextFormattingMode textFormattingMode ) { SpanVector <int> cachedScaledTypefaceIndexSpans; int ichItem = 0; CharacterBufferRange unicodeString = new CharacterBufferRange( characterBufferReference, stringLength ); CultureInfo culture = textRunProperties.CultureInfo; IList <Span> spans; GCHandle gcHandle; IntPtr ptext = characterBufferReference.CharacterBuffer.PinAndGetCharacterPointer(characterBufferReference.OffsetToFirstChar, out gcHandle); // Contextual number substitution cannot be performed on the run level, since it depends // on context - nearest preceding strong character. For this reason, contextual number // substitutions has been already done (TextStore.CreateLSRunsUniformBidiLevel) and // digitCulture has been updated to reflect culture which is dependent on the context. // NumberSubstitutionMethod.AsCulture method can be resolved to Context, hence it also needs to be resolved to appropriate // not ambiguous method. // Both of those values (Context and AsCulture) are resolved to one of following: European, Traditional or NativeNational, // which can be safely handled by DWrite without getting context information. bool ignoreUserOverride; NumberSubstitutionMethod numberSubstitutionMethod = DigitState.GetResolvedSubstitutionMethod(textRunProperties, digitCulture, out ignoreUserOverride); // Itemize the text based on DWrite's text analysis for scripts and number substitution. unsafe { checked { spans = MS.Internal.Text.TextInterface.TextAnalyzer.Itemize( (ushort *)ptext.ToPointer(), (uint)stringLength, culture, MS.Internal.FontCache.DWriteFactory.Instance, isRightToLeftParagraph, digitCulture, ignoreUserOverride, (uint)numberSubstitutionMethod, ClassificationUtility.Instance, UnsafeNativeMethods.CreateTextAnalysisSink, UnsafeNativeMethods.GetScriptAnalysisList, UnsafeNativeMethods.GetNumberSubstitutionList, UnsafeNativeMethods.CreateTextAnalysisSource ); } } characterBufferReference.CharacterBuffer.UnpinCharacterPointer(gcHandle); SpanVector itemSpans = new SpanVector(null, new FrugalStructList <Span>((ICollection <Span>)spans)); cachedScaledTypefaceIndexSpans = new SpanVector <int>(-1); foreach (Span itemSpan in itemSpans) { MapItem( new CharacterBufferRange( unicodeString, ichItem, itemSpan.length ), culture, itemSpan, ref cachedScaledTypefaceIndexSpans, ichItem ); #if DEBUG ValidateMapResult( ichItem, itemSpan.length, ref cachedScaledTypefaceIndexSpans ); #endif ichItem += itemSpan.length; } Debug.Assert(ichItem == unicodeString.Length); // intersect item spans with shapeable spans to create span of shapeable runs int ich = 0; SpanRider itemSpanRider = new SpanRider(itemSpans); SpanRider <int> typefaceIndexSpanRider = new SpanRider <int>(cachedScaledTypefaceIndexSpans); while (ich < unicodeString.Length) { itemSpanRider.At(ich); typefaceIndexSpanRider.At(ich); int index = typefaceIndexSpanRider.CurrentValue; Debug.Assert(index >= 0); int cch = unicodeString.Length - ich; cch = Math.Min(cch, itemSpanRider.Length); cch = Math.Min(cch, typefaceIndexSpanRider.Length); ScaledShapeTypeface scaledShapeTypeface = _cachedScaledTypefaces[index]; collector.Add( shapeableList, new CharacterBufferRange( unicodeString, ich, cch ), textRunProperties, (MS.Internal.Text.TextInterface.ItemProps)itemSpanRider.CurrentElement, scaledShapeTypeface.ShapeTypeface, scaledShapeTypeface.ScaleInEm, scaledShapeTypeface.NullShape, textFormattingMode ); ich += cch; } }
public static void SetSubstitution(System.Windows.DependencyObject target, NumberSubstitutionMethod value) { }
/// <summary> /// Creates a number substitution object using a locale name, substitution method, and an indicator whether to ignore user overrides (use NLS defaults for the given culture instead). /// </summary> /// <param name="factory">A reference to a DirectWrite factory <see cref="Factory"/></param> /// <param name="substitutionMethod">A value that specifies how to apply number substitution on digits and related punctuation. </param> /// <param name="localeName">The name of the locale to be used in the numberSubstitution object. </param> /// <param name="ignoreUserOverride">A Boolean flag that indicates whether to ignore user overrides. </param> /// <unmanaged>HRESULT IDWriteFactory::CreateNumberSubstitution([In] DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod,[In] const wchar_t* localeName,[In] BOOL ignoreUserOverride,[Out] IDWriteNumberSubstitution** numberSubstitution)</unmanaged> public NumberSubstitution(Factory factory, NumberSubstitutionMethod substitutionMethod, string localeName, bool ignoreUserOverride) { factory.CreateNumberSubstitution(substitutionMethod, localeName, ignoreUserOverride, this); }
private CultureInfo GetDigitCulture(CultureInfo numberCulture, NumberSubstitutionMethod method, out bool contextual) { contextual = false; if (numberCulture == null) { return null; } if (method == NumberSubstitutionMethod.AsCulture) { switch (numberCulture.NumberFormat.DigitSubstitution) { case DigitShapes.Context: method = NumberSubstitutionMethod.Context; break; case DigitShapes.NativeNational: method = NumberSubstitutionMethod.NativeNational; break; default: return null; } } CultureInfo digitCulture; switch (method) { case NumberSubstitutionMethod.Context: if (IsArabic(numberCulture) || IsFarsi(numberCulture)) { contextual = true; digitCulture = GetTraditionalCulture(numberCulture); } else { digitCulture = null; } break; case NumberSubstitutionMethod.NativeNational: if (!HasLatinDigits(numberCulture)) { digitCulture = numberCulture; } else { digitCulture = null; } break; case NumberSubstitutionMethod.Traditional: digitCulture = GetTraditionalCulture(numberCulture); break; default: digitCulture = null; break; } return digitCulture; }
private static CultureInfo GetNumberCulture(TextRunProperties properties, out NumberSubstitutionMethod method, out bool ignoreUserOverride) { ignoreUserOverride = true; NumberSubstitution sub = properties.NumberSubstitution; if (sub == null) { method = NumberSubstitutionMethod.AsCulture; return CultureMapper.GetSpecificCulture(properties.CultureInfo); } method = sub.Substitution; switch (sub.CultureSource) { case NumberCultureSource.Text: return CultureMapper.GetSpecificCulture(properties.CultureInfo); case NumberCultureSource.User: ignoreUserOverride = false; return CultureInfo.CurrentCulture; case NumberCultureSource.Override: return sub.CultureOverride; } return null; }
internal static CultureInfo GetNumberCulture(TextRunProperties properties, out NumberSubstitutionMethod method) { NumberSubstitution sub = properties.NumberSubstitution; if (sub == null) { method = NumberSubstitutionMethod.AsCulture; return CultureMapper.GetSpecificCulture(properties.CultureInfo); } method = sub.Substitution; switch (sub.CultureSource) { case NumberCultureSource.Text: return CultureMapper.GetSpecificCulture(properties.CultureInfo); case NumberCultureSource.User: return CultureInfo.CurrentCulture; case NumberCultureSource.Override: return sub.CultureOverride; } return null; }
public NumberSubstitution(NumberCultureSource source, System.Globalization.CultureInfo cultureOverride, NumberSubstitutionMethod substitution) { }