static int GetRelatedness(XmlLanguage keyLang, XmlLanguage userLang)
        {
            try
            {
                // Get equivalent cultures.
                CultureInfo keyCulture = CultureInfo.GetCultureInfoByIetfLanguageTag(keyLang.IetfLanguageTag);
                CultureInfo userCulture = CultureInfo.GetCultureInfoByIetfLanguageTag(userLang.IetfLanguageTag);
                if (!userCulture.IsNeutralCulture)
                {
                    userCulture = userCulture.Parent;
                }

                // If the key is a prefix or parent of the user language it's a good match.
                if (IsPrefixOf(keyLang.IetfLanguageTag, userLang.IetfLanguageTag) || userCulture.Equals(keyCulture))
                {
                    return 2;
                }

                // If the key and user language share a common prefix or parent neutral culture, it's a reasonable match.
                if (IsPrefixOf(TrimSuffix(userLang.IetfLanguageTag), keyLang.IetfLanguageTag) || userCulture.Equals(keyCulture.Parent))
                {
                    return 1;
                }
            }
            catch (ArgumentException)
            {
                // Language tag with no corresponding CultureInfo.
            }

            // They're unrelated languages.
            return 0;
        }
 private static bool Compatible(XmlLanguage lang, CultureInfo culture)
 {
     if (lang == null || lang == XmlLanguage.Empty) return true;
     var ll = lang.IetfLanguageTag.ToLowerInvariant();
     while (!culture.Equals(CultureInfo.InvariantCulture))
     {
         if (ll == culture.IetfLanguageTag.ToLowerInvariant()) return true;
         culture = culture.Parent;
     }
     return false;
 }
        /// <summary>
        /// Construct a Family map object
        /// </summary>
        /// <param name="firstChar">first character</param>
        /// <param name="lastChar">last character</param>
        /// <param name="language">language</param>
        /// <param name="targetFamilyName">target family name</param>
        /// <param name="scaleInEm">font scale in EM</param>
        internal FontFamilyMap(
            int             firstChar,
            int             lastChar,
            XmlLanguage     language,
            string          targetFamilyName,
            double          scaleInEm
            )
        {
            if (firstChar == 0 && lastChar == LastUnicodeScalar)
                _ranges = _defaultRanges;
            else
                _ranges = new Range[]{ new Range(firstChar, lastChar) };

            _language = language;
            _scaleInEm = scaleInEm;
            _targetFamilyName = targetFamilyName;
        }
        private static void SetCulture(
            XmlLanguage lang, CultureInfo cult)
        {
            var propertynames = new[]
                            {
                                "_equivalentCulture",
                                "_specificCulture",
                                "_compatibleCulture"
                            };

            const BindingFlags flags = BindingFlags.ExactBinding |
                BindingFlags.SetField | BindingFlags.Instance |
                BindingFlags.NonPublic;

            foreach (var name in propertynames)
            {
                var field = typeof(XmlLanguage).GetField(name, flags);
                field.SetValue(lang, cult);
            }
        }
Beispiel #5
0
        private void PrepareAttributes(InputScope inputScope, double fontSize, FontFamily fontFamily, XmlLanguage language, Visual visual, int count, Guid[] filterAttributes)
        {
            if (_preparedattributes == null)
            {
                _preparedattributes = new ArrayList(count);
            }
            else
            {
                _preparedattributes.Clear();
            }

            int i;
            for (i = 0; i < _supportingattributes.Length; i++)
            {
                if (count != 0)
                {
                    int j;
                    bool found = false;
                    for (j = 0; j < count; j++)
                    {
                        if (_supportingattributes[i].Guid.Equals(filterAttributes[j]))
                            found = true;
                    }

                    if (!found)
                        continue;
                }

                UnsafeNativeMethods.TS_ATTRVAL attrval = new UnsafeNativeMethods.TS_ATTRVAL();
                attrval.attributeId = _supportingattributes[i].Guid;
                attrval.overlappedId = (int)_supportingattributes[i].Style;
                attrval.val = new NativeMethods.VARIANT();

                // This VARIANT is returned to the caller, which supposed to call VariantClear().
                // GC does not have to clear it.
                attrval.val.SuppressFinalize();

                switch (_supportingattributes[i].Style)
                {
                    case AttributeStyle.InputScope:
                        object obj = new InputScopeAttribute(inputScope);
                        attrval.val.vt = (short)NativeMethods.tagVT.VT_UNKNOWN;
                        attrval.val.data1.Value = Marshal.GetIUnknownForObject(obj);
                        break;

                    case AttributeStyle.Font_Style_Height:
                        // We always evaluate the font size and returns a value.
                        attrval.val.vt = (short)NativeMethods.tagVT.VT_I4;
                        attrval.val.data1.Value = (IntPtr)(int)fontSize;
                        break;

                    case AttributeStyle.Font_FaceName:
                        {
                            string familyName = GetFontFamilyName(fontFamily, language);
                            if (familyName != null)
                            {
                                attrval.val.vt = (short)NativeMethods.tagVT.VT_BSTR;
                                attrval.val.data1.Value = Marshal.StringToBSTR(familyName);
                            }
                        }
                        break;

                    case AttributeStyle.Font_SizePts:
                        attrval.val.vt = (short)NativeMethods.tagVT.VT_I4;
                        attrval.val.data1.Value = (IntPtr)(int)(fontSize / 96.0 * 72.0);
                        break;

                    case AttributeStyle.Text_ReadOnly:
                        attrval.val.vt = (short)NativeMethods.tagVT.VT_BOOL;
                        attrval.val.data1.Value = IsReadOnly ? (IntPtr)1 : (IntPtr)0;
                        break;

                    case AttributeStyle.Text_Orientation:
                        attrval.val.vt = (short)NativeMethods.tagVT.VT_I4;
                        attrval.val.data1.Value = (IntPtr)0;

                        // Get the transformation that is relative from source.
                        PresentationSource source = null;

                        source = PresentationSource.CriticalFromVisual((Visual)RenderScope);
                        if (source != null)
                        {
                            Visual root = source.RootVisual;
                            if ((root !=  null) && (visual != null))
                            {
                                //
                                // Calc radian from Matirix. This is approximate calculation from the first row.
                                // If tf.M12 is 0, angle will be 0. So we don't have to calc it.
                                //
                                GeneralTransform transform = visual.TransformToAncestor(root);
                                Transform t = transform.AffineTransform;
                                // 
                                if (t != null)
                                {
                                    Matrix tf = t.Value;
                                    if ((tf.M11 != 0) || (tf.M12 != 0))
                                    {
                                        double radSin = Math.Asin(tf.M12 / Math.Sqrt((tf.M11 * tf.M11) + (tf.M12 * tf.M12)));
                                        double radCos = Math.Acos(tf.M11 / Math.Sqrt((tf.M11 * tf.M11) + (tf.M12 * tf.M12)));
                                        // double angleSin = Math.Round((radSin * 180) / Math.PI, 0);
                                        double angleCos = Math.Round((radCos * 180) / Math.PI, 0);
                                        double angle;

                                        // determine angle from the sign of radSin;
                                        if (radSin <= 0)
                                            angle = angleCos;
                                        else
                                            angle = 360 - angleCos;

                                        attrval.val.data1.Value = (IntPtr)((int)angle * 10);
                                    }
                                }
                            }
                        }
                        break;

                    case AttributeStyle.Text_VerticalWriting:
                        //
                        // 


                        attrval.val.vt = (short)NativeMethods.tagVT.VT_BOOL;
                        attrval.val.data1.Value = (IntPtr)0;
                        break;
                }

                _preparedattributes.Add(attrval);
            }
        }
Beispiel #6
0
        // determine a family name from a FontFamily and XmlLanguage
        private static string GetFontFamilyName(FontFamily fontFamily, XmlLanguage language)
        {
            if (fontFamily == null)
                return null;

            // If the font family was constructed from a font name or URI, return that value.
            if (fontFamily.Source != null)
                return fontFamily.Source;

            // Use the dictionary of names provided by the font.
            LanguageSpecificStringDictionary names = fontFamily.FamilyNames;
            if (names == null)
                return null;

            // try every matching language to most-specific to least specific, including ""
            foreach (XmlLanguage matchingLanguage in language.MatchingLanguages)
            {
                string name = names[matchingLanguage];
                if (name != null)
                    return name;
            }

            // give up!
            return null;
        }
Beispiel #7
0
 // Cache the Language property when it's used by DoDefaultExpansion, so
 // that we can detect changes.  (This could also be done by a virtual
 // OnLanguageChanged method, if FrameworkElement ever defines one.)
 private void CacheLanguage(XmlLanguage language)
 {
     _language = language;
 }
Beispiel #8
0
        // Returns the CultureInfo of the content at a position.
        // Returns null if there is no CultureInfo matching the current XmlLanguage. 
        private CultureInfo GetCurrentCultureAndLanguage(ITextPointer position, out XmlLanguage language) 
        {
            CultureInfo cultureInfo; 
            bool hasModifiers;

            // TextBox takes the input language iff no local LanguageProperty is set.
            if (!_textEditor.AcceptsRichContent && 
                _textEditor.UiScope.GetValueSource(FrameworkElement.LanguageProperty, null, out hasModifiers) == BaseValueSourceInternal.Default)
            { 
                cultureInfo = _defaultCulture; 
                language = XmlLanguage.GetLanguage(cultureInfo.IetfLanguageTag);
            } 
            else
            {
                language = (XmlLanguage)position.GetValue(FrameworkElement.LanguageProperty);
 
                if (language == null)
                { 
                    cultureInfo = null; 
                }
                else 
                {
                    try
                    {
                        cultureInfo = language.GetSpecificCulture(); 
                    }
                    catch (InvalidOperationException) 
                    { 
                        // Someone set a bogus language on the run.
                        cultureInfo = null; 
                    }
                }
            }
 
            return cultureInfo;
        } 
Beispiel #9
0
        // Returns the closest of either a halting position or the position preceding text
        // tagged with a differing XmlLanguage from a start position.
        private ITextPointer GetNextLanguageTransition(ITextPointer position, LogicalDirection direction, XmlLanguage language, ITextPointer haltPosition)
        { 
            ITextPointer navigator = position.CreatePointer();
 
            while ((direction == LogicalDirection.Forward && navigator.CompareTo(haltPosition) < 0) || 
                   (direction == LogicalDirection.Backward && navigator.CompareTo(haltPosition) > 0))
            { 
                if (GetCurrentLanguage(navigator) != language)
                    break;

                navigator.MoveToNextContextPosition(direction); 
            }
 
            // If we moved past haltPosition on the final MoveToNextContextPosition, move back. 
            if ((direction == LogicalDirection.Forward && navigator.CompareTo(haltPosition) > 0) ||
                (direction == LogicalDirection.Backward && navigator.CompareTo(haltPosition) < 0)) 
            {
                navigator.MoveToPosition(haltPosition);
            }
 
            return navigator;
        } 
Beispiel #10
0
		public XmlLanguage(CultureInfo culture)
		{
			_language = System.Windows.Markup.XmlLanguage.GetLanguage(culture.IetfLanguageTag);
		}
        //-----------------------------------------------------------------------------------------------
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            FXmlLanguage = XmlLanguage.GetLanguage(FLanguage);

            this.SetFontSizeList();
            this.SetLanguageList();

            if (this.DlgFontWeight == FontWeights.Bold)
                chkBold.IsChecked = true;

            this.DlgSampleText = FSampleText;
            txtSample.Text = FSampleText;
        }
        //---------------------------------------------------------------------------------------------
        private void cmbLanguage_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (cmbLanguage.Items.Count < 1)
                return;

            ComboBoxItem item = cmbLanguage.SelectedItem as ComboBoxItem;
            FXmlLanguage = item.Tag as XmlLanguage;

            if (FXmlLanguage == null)
                FLanguage = null;
            else
                FLanguage = FXmlLanguage.IetfLanguageTag;

            this.UpdateFamilyName();
        }
Beispiel #13
0
 internal CultureInfo GetCultureInfo()
 {
     if (_ci == null || _lang != Language)
     {
         _lang = Language;
         _ci = Util.Util.GetEquivalentCulture(_lang);
     }
     return _ci;
 }
        internal static bool MatchCulture(XmlLanguage familyMapLanguage, CultureInfo culture)
        {
            // If there is no family map langue, the family map applies to any language.
            if (familyMapLanguage == null)
            {
                return true;
            }

            if (culture != null)
            {
                return familyMapLanguage.RangeIncludes(culture);
            }   

            return false;
        }
        /// <summary>
        /// Returns information about which family maps apply to the specified culture.
        /// The return value is used by GetFamilyMapOfChar.
        /// </summary>
        internal ushort[] GetFamilyMapsOfLanguage(XmlLanguage language)
        {
            ushort[] ranges = null;

            // Look for a family map range for the specified language or one of its matching languages
            if (_familyMapRangesByLanguage != null && language != null)
            {
                foreach (XmlLanguage matchingLanguage in language.MatchingLanguages)
                {
                    // break out of loop to handle default list of ranges
                    if (matchingLanguage.IetfLanguageTag.Length == 0)
                        break;

                    if (_familyMapRangesByLanguage.TryGetValue(matchingLanguage, out ranges))
                    {
                        // Recreate the list of ranges if we've added more family maps.
                        if (!IsFamilyMapRangesValid(ranges))
                        {
                            ranges = CreateFamilyMapRanges(matchingLanguage);
                            _familyMapRangesByLanguage[matchingLanguage] = ranges;
                        }
                        return ranges;
                    }
                }
            }

            // Use the default list of ranges (containing only family maps that match
            // any culture); recreate it if we've added more family maps.
            if (!IsFamilyMapRangesValid(_defaultFamilyMapRanges))
            {
                _defaultFamilyMapRanges = CreateFamilyMapRanges(null);
            }

            return _defaultFamilyMapRanges;
        }
        private ushort[] CreateFamilyMapRanges(XmlLanguage language)
        {
            // We could use an ArrayList, but a ushort[] is not much more code
            // and requires many fewer boxed objects.
            ushort[] ranges = new ushort[InitialFamilyMapRangesCapacity];
            ranges[0] = (ushort)_familyMaps.Count;
            int count = 1;

            Debug.Assert(count == FirstFamilyMapRange);

            for (int i = 0; i < _familyMaps.Count; ++i)
            {
                if (FontFamilyMap.MatchLanguage(_familyMaps[i].Language, language))
                {
                    // grow ranges if necessary.
                    if (count + 2 > ranges.Length)
                    {
                        ushort[] temp = new ushort[ranges.Length * 2 - FirstFamilyMapRange];
                        ranges.CopyTo(temp, 0);
                        ranges = temp;
                    }

                    // beginning of range
                    ranges[count++] = (ushort)i;

                    ++i;
                    while (i < _familyMaps.Count && FontFamilyMap.MatchLanguage(_familyMaps[i].Language, language))
                    {
                        ++i;
                    }

                    // end of range, i.e., last index + 1
                    ranges[count++] = (ushort)i;
                }
            }

            // reallocate ranges to the exact size required
            if (count < ranges.Length)
            {
                ushort[] temp = new ushort[count];
                Array.Copy(ranges, temp, count);
                ranges = temp;
            }

            return ranges;
        }
Beispiel #17
0
        private void ExpandToWordBreakAndContext(ITextPointer position, LogicalDirection direction, XmlLanguage language,
            out ITextPointer contentPosition, out ITextPointer contextPosition) 
        {
            ITextPointer start; 
            ITextPointer end; 
            ITextPointer outwardPosition;
            ITextPointer inwardPosition; 
            TextMap textMap;
            ArrayList segments;
            SpellerInterop.STextRange sTextRange;
            LogicalDirection inwardDirection; 
            int i;
 
            contentPosition = position; 
            contextPosition = position;
 
            if (position.GetPointerContext(direction) == TextPointerContext.None)
            {
                // There is no following context, we're at document start/end.
                return; 
            }
 
            // Disable spell checking functionality since we're only 
            // interested in word breaks here.  This greatly cuts down
            // the engine's workload. 
            _spellerInterop.SetContextOption("IsSpellChecking", false);

            //
            // Build an array of wordbreak offsets surrounding the position. 
            //
 
            // 1. Search outward, into surrounding text.  We need MinWordBreaksForContext 
            // word breaks to handle multi-word errors.
            outwardPosition = SearchForWordBreaks(position, direction, language, MinWordBreaksForContext, true /* stopOnError */); 

            // 2. Search inward, towards content.  We just need one word break inward.
            inwardDirection = direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward;
            inwardPosition = SearchForWordBreaks(position, inwardDirection, language, 1, false /* stopOnError */); 

            // Get combined word breaks.  This may not be the same as we calculated 
            // in two parts above, since we don't know yet whether or not position is 
            // on a word break.
            if (direction == LogicalDirection.Backward) 
            {
                start = outwardPosition;
                end = inwardPosition;
            } 
            else
            { 
                start = inwardPosition; 
                end = outwardPosition;
            } 
            textMap = new TextMap(start, end, position, position);
            segments = new ArrayList(MinWordBreaksForContext + 1);
            _spellerInterop.EnumTextSegments(textMap.Text, textMap.TextLength, null,
                new SpellerInterop.EnumTextSegmentsCallback(ExpandToWordBreakCallback), segments); 

            // 
            // Use our table of word breaks to calculate context and content positions. 
            //
            if (segments.Count == 0) 
            {
                // No segments.  This can happen if position is surrounded by
                // nothing but white space.  We've already initialized contentPosition
                // and contextPosition so there's nothing to do. 
            }
            else 
            { 
                int leftWordBreak;
                int rightWordBreak; 
                int contentOffset;
                int contextOffset;

                // Figure out where position lives in the segment list. 
                i = FindPositionInSegmentList(textMap, direction, segments, out leftWordBreak, out rightWordBreak);
 
                // contentPosition should be an edge on the segment we found. 
                if (direction == LogicalDirection.Backward)
                { 
                    contentOffset = textMap.ContentStartOffset == rightWordBreak ? rightWordBreak : leftWordBreak;
                }
                else
                { 
                    contentOffset = textMap.ContentStartOffset == leftWordBreak ? leftWordBreak : rightWordBreak;
                } 
                contentPosition = textMap.MapOffsetToPosition(contentOffset); 

                // contextPosition should be MinWordBreaksForContext - 1 words away. 
                if (direction == LogicalDirection.Backward)
                {
                    i -= (MinWordBreaksForContext - 1);
                    sTextRange = (SpellerInterop.STextRange)segments[Math.Max(i, 0)]; 
                    // We might actually follow contentOffset if we're at the document edge.
                    // Don't let that happen. 
                    contextOffset = Math.Min(sTextRange.Start, contentOffset); 
                }
                else 
                {
                    i += MinWordBreaksForContext;
                    sTextRange = (SpellerInterop.STextRange)segments[Math.Min(i, segments.Count-1)];
                    // We might actually preceed contentOffset if we're at the document edge. 
                    // Don't let that happen.
                    contextOffset = Math.Max(sTextRange.Start + sTextRange.Length, contentOffset); 
                } 
                contextPosition = textMap.MapOffsetToPosition(contextOffset);
            } 

            // Final fixup: if the dirty range covers only formatting (which is not passed
            // to the speller engine) then we might actually "expand" in the wrong
            // direction, since the TextMap will jump over formatting. 
            // Backup if necessary.
            if (direction == LogicalDirection.Backward) 
            { 
                if (position.CompareTo(contentPosition) < 0)
                { 
                    contentPosition = position;
                }
                if (position.CompareTo(contextPosition) < 0)
                { 
                    contextPosition = position;
                } 
            } 
            else
            { 
                if (position.CompareTo(contentPosition) > 0)
                {
                    contentPosition = position;
                } 
                if (position.CompareTo(contextPosition) > 0)
                { 
                    contextPosition = position; 
                }
            } 
        }
Beispiel #18
0
 public GlyphRun CreateGlyphRun(Point origin, XmlLanguage language)
 { 
     return new GlyphRun( 
         glyphTypeface,               // GlyphTypeface
         bidiLevel,                   // Bidi level 
         sideways,                    // sideways flag
         fontRenderingSize,           // rendering em size in MIL units
         glyphIndices,                // glyph indices
         origin,                      // origin of glyph-drawing space 
         advanceWidths,               // glyph advances
         glyphOffsets,                // glyph offsets 
         unicodeString.ToCharArray(), // unicode characters 
         deviceFontName,              // device font
         clusterMap,                  // cluster map 
         caretStops,                  // caret stops
         language                     // language
     );
 } 
Beispiel #19
0
        private ITextPointer SearchForWordBreaks(ITextPointer position, LogicalDirection direction, XmlLanguage language, int minWordCount, bool stopOnError)
        { 
            ITextPointer closestErrorPosition;
            ITextPointer searchPosition; 
            ITextPointer start; 
            ITextPointer end;
            StaticTextPointer nextErrorTransition; 
            int segmentCount;
            TextMap textMap;

            searchPosition = position.CreatePointer(); 

            closestErrorPosition = null; 
            if (stopOnError) 
            {
                nextErrorTransition = _statusTable.GetNextErrorTransition(position.CreateStaticPointer(), direction); 
                if (!nextErrorTransition.IsNull)
                {
                    closestErrorPosition = nextErrorTransition.CreateDynamicTextPointer(LogicalDirection.Forward);
                } 
            }
 
            bool hitBreakPoint = false; 

            do 
            {
                searchPosition.MoveByOffset(direction == LogicalDirection.Backward ? -ContextBlockSize : +ContextBlockSize);

                // Don't go past closestErrorPosition. 
                if (closestErrorPosition != null)
                { 
                    if (direction == LogicalDirection.Backward && closestErrorPosition.CompareTo(searchPosition) > 0 || 
                        direction == LogicalDirection.Forward && closestErrorPosition.CompareTo(searchPosition) < 0)
                    { 
                        searchPosition.MoveToPosition(closestErrorPosition);
                        hitBreakPoint = true;
                    }
                } 

                // Don't venture into text in another language. 
                ITextPointer closestLanguageTransition = GetNextLanguageTransition(position, direction, language, searchPosition); 

                if (direction == LogicalDirection.Backward && closestLanguageTransition.CompareTo(searchPosition) > 0 || 
                    direction == LogicalDirection.Forward && closestLanguageTransition.CompareTo(searchPosition) < 0)
                {
                    searchPosition.MoveToPosition(closestLanguageTransition);
                    hitBreakPoint = true; 
                }
 
                if (direction == LogicalDirection.Backward) 
                {
                    start = searchPosition; 
                    end = position;
                }
                else
                { 
                    start = position;
                    end = searchPosition; 
                } 

                textMap = new TextMap(start, end, start, end); 
                segmentCount = _spellerInterop.EnumTextSegments(textMap.Text, textMap.TextLength, null, null, null);
            }
            while (!hitBreakPoint &&
                   segmentCount < minWordCount + 1 && 
                   searchPosition.GetPointerContext(direction) != TextPointerContext.None);
 
            return searchPosition; 
        }