Esempio n. 1
0
        /// <summary>
        ///   This method applies the given culture to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="culture"> This parameter references the culture to apply to the range. </param>
        public void SetCulture(IndexedRange textRange, CultureInfo culture)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Culture = culture;
            }
        }
Esempio n. 2
0
            public static IndexedRange GetRange(NSRange theRange)
            {
                IndexedRange result;

                if (theRange.Location == NSRange.NotFound)
                {
                    return(null);
                }

                if (!ranges.TryGetValue(theRange, out result))
                {
                    result       = new IndexedRange();
                    result.Range = new NSRange(theRange.Location, theRange.Length);
                }
                return(result);
            }
Esempio n. 3
0
		public static void Draw(Painter painterSink, ITextMetrics metrics, IndexedRange range)
		{
			Contract.Requires(painterSink != null);
			Contract.Requires(metrics != null);

			for(int i = range.StartIndex; i <= range.LastIndex; ++i)
			{
				if(metrics.IsClusterStart(i))
				{
					if(metrics.IsVisible(i))
					{
						Rectangle region = metrics.Regions[i];

						Point baseline = new Point(
							region.Left + metrics.BaselineOffset.Width, region.Top + metrics.BaselineOffset.Height);

						if(metrics.IsRightToLeft(i))
						{
							baseline = new Point(region.Right + metrics.BaselineOffset.Width, baseline.Y);
						}

						painterSink.SaveState();

						painterSink.Translate(baseline.X, baseline.Y);

						Outline outline = metrics.Outlines[i];

						painterSink.Scale(outline.EmSize, outline.EmSize);

						if (outline.NormalizedOutline != null)
						{
							painterSink.Fill(outline.NormalizedOutline);
						}

						painterSink.RestoreState();
					}
				}
			}
		}
Esempio n. 4
0
        /// <summary>
        ///   This method applies the given font family to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="family"> This parameter references the font family to apply to the range. </param>
        public void SetFamily(IndexedRange textRange, string family)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Family = family;
            }
        }
Esempio n. 5
0
        /// <summary>
        ///   This method applies the given font style to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="style"> This parameter indicates the font style to apply to the range. </param>
        public void SetStyle(IndexedRange textRange, FontStyle style)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Style = style;
            }
        }
Esempio n. 6
0
        /// <summary>
        ///   This method applies the results of script analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="scriptAnalysis"> This parameter contains the results to apply to the range. </param>
        void TextAnalysisSink.SetScriptAnalysis(
			int textPosition, int textLength, ScriptAnalysis scriptAnalysis)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            foreach(int index in range)
            {
                _OutputSink.Characters[index].ScriptAnalysis = scriptAnalysis;
            }
        }
Esempio n. 7
0
        internal ParagraphMetrics(
			Paragraph paragraph, FormatterSink formattedData, TextGeometryCache geometryCache)
        {
            Contract.Requires(paragraph != null);
            Contract.Requires(formattedData != null);
            Contract.Requires(geometryCache != null);

            _Paragraph = paragraph;

            _Leading = formattedData.Leading;
            _LayoutRegion = formattedData.LayoutRegion;
            _BaselineOffset = formattedData.BaselineOffset;

            _Clusters = formattedData.Clusters.ToArray();

            _ClusterBidiLevels = new byte[formattedData.Clusters.Count];

            _Outlines = CreateOutlineList(formattedData, geometryCache, out _ClusterBidiLevels);

            // create the text index to cluster index transformation table
            _TextToCluster = new int[formattedData.FullText.Length];

            for(int i = 0; i < _Clusters.Length; ++i)
            {
                foreach(int characterIndex in _Clusters[i].Characters)
                {
                    _TextToCluster[characterIndex] = i;
                }
            }

            // determine the region that encompasses all formatted clusters
            float left = float.MaxValue;
            float top = float.MaxValue;
            float right = float.MinValue;
            float bottom = float.MinValue;

            for(int i = 0; i < _Clusters.Length; ++i)
            {
                left = Math.Min(left, _Clusters[i].Region.Left);
                top = Math.Min(top, _Clusters[i].Region.Top);
                right = Math.Max(right, _Clusters[i].Region.Right);
                bottom = Math.Max(bottom, _Clusters[i].Region.Bottom);
            }

            _TextRegion = Rectangle.FromEdges(left, top, right, bottom);

            // determine the ranges of each line
            _LineListBuilder.Clear();

            int lastLine = 0;

            IndexedRange range = IndexedRange.Empty;

            for(int i = 0; i < formattedData.Runs.Count; ++i)
            {
                if(formattedData.Runs[i].LineNumber > lastLine)
                {
                    _LineListBuilder.Add(ToTextRange(range));

                    range = new IndexedRange(formattedData.Runs[i].Clusters.StartIndex, 0);

                    lastLine = formattedData.Runs[i].LineNumber;
                }

                range = range.Extend(formattedData.Runs[i].Clusters.Length);
            }

            if(range.Length > 0)
            {
                _LineListBuilder.Add(ToTextRange(range));
            }

            _Lines = new LineCollection(_LineListBuilder);

            // build a collection of regions mapping to text indexes
            _RegionListBuilder.Clear();

            for(int i = 0; i < paragraph.Text.Length; ++i)
            {
                _RegionListBuilder.Add(_Clusters[_TextToCluster[i]].Region);
            }

            _Regions = new RegionCollection(_RegionListBuilder);
        }
Esempio n. 8
0
			internal void Reset()
			{
				_Runs.Clear();
				_States.Clear();

				_Alignment = Alignment.Stretch;
				_Indentation = DefaultIndentation;
				_Leading = DefaultLeading;
				_Spacing = DefaultSpacing;
				_Tracking = DefaultTracking;

				_Text.Clear();

				_ActiveCulture = DefaultCulture;
				_ActiveFamily = DefaultFamily;
				_ActivePointSize = DefaultPointSize;
				_ActiveHAlignment = Alignment.Stretch;
				_ActiveVAlignment = Alignment.Stretch;
				_ActiveInline = Size.Empty;
				_ActiveTextRange = IndexedRange.Empty;
				_ActiveStretch = FontStretch.Regular;
				_ActiveStyle = FontStyle.Regular;
				_ActiveWeight = FontWeight.Regular;
				_ActiveFeatures = null;
			}
Esempio n. 9
0
        /// <summary>
        ///   This method converts a cluster range to a text range.
        /// </summary>
        /// <param name="clusters"> This parameter contains the cluster range to convert. </param>
        /// <returns> This method returns the converted text range. </returns>
        private IndexedRange ToTextRange(IndexedRange clusters)
        {
            int textLength = 0;

            foreach(int index in clusters)
            {
                textLength += _Clusters[index].Characters.Length;
            }

            int startIndex = _Clusters[clusters.StartIndex].Characters.StartIndex;

            return new IndexedRange(startIndex, textLength);
        }
Esempio n. 10
0
        /// <summary>
        ///   This method retrieves cohesive runs of text having identical locales.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the text position. </param>
        /// <param name="textLength"> This output parameter indicates the length of text remaining for processing. </param>
        /// <returns> This method returns the run of text having a consistent locale at the given position. </returns>
        string TextAnalysisSource.GetLocaleName(int textPosition, out int textLength)
        {
            IndexedRange range = new IndexedRange(textPosition, _FullText.Length);

            foreach(int index in range)
            {
                if(_Characters[index].Culture != _Characters[textPosition].Culture)
                {
                    textLength = index - textPosition;

                    return _Characters[textPosition].Culture.Name;
                }
            }

            textLength = _FullText.Length - textPosition;

            return _Characters[textPosition].Culture.Name;
        }
Esempio n. 11
0
			public Builder ResetState()
			{
				Contract.Ensures(Contract.Result<Builder>() != null);

				_ActiveTextRange = IndexedRange.Empty;
				_ActiveCulture = DefaultCulture;
				_ActiveFamily = DefaultFamily;
				_ActiveFeatures = null;
				_ActivePointSize = DefaultPointSize;
				_ActiveStretch = FontStretch.Regular;
				_ActiveStyle = FontStyle.Regular;
				_ActiveWeight = FontWeight.Regular;
				_ActiveInline = Size.Empty;
				_ActiveHAlignment = Alignment.Stretch;
				_ActiveVAlignment = Alignment.Stretch;

				return this;
			}
Esempio n. 12
0
        /// <summary>
        ///   This method applies the given font point size to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="pointSize"> This parameter contains the font size to apply to the range. </param>
        public void SetPointSize(IndexedRange textRange, float pointSize)
        {
            Contract.Requires(Check.IsPositive(pointSize));
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].PointSize = pointSize;
            }
        }
Esempio n. 13
0
            public void ComputeRegion(IndexedRange textRange, out Rectangle result)
            {
                Contract.Requires(textRange.StartIndex < Regions.Count);
                Contract.Requires(textRange.LastIndex < Regions.Count);

                throw new NotSupportedException();
            }
Esempio n. 14
0
        /// <summary>
        ///   This method transforms the characters of the given text range to inline objects.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="inline"> This parameter indicates the size of the inline object. </param>
        /// <param name="hAlignment"> This parameter indicates the horizontal alignment of the inline object. </param>
        /// <param name="vAlignment"> This parameter indicates the vertical alignment of the inline object. </param>
        public void SetInline(
			IndexedRange textRange, Size inline, Alignment hAlignment, Alignment vAlignment)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Inline = inline;
                _OutputSink.Characters[index].HAlignment = hAlignment;
                _OutputSink.Characters[index].VAlignment = vAlignment;
            }
        }
Esempio n. 15
0
        /// <summary>
        ///   This method applies the given font features to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="features"> This parameter references the collection of font features to apply to the range. </param>
        public void SetFeatures(IndexedRange textRange, FontFeatureCollection features)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Features = features;
            }
        }
Esempio n. 16
0
        /// <summary>
        ///   This method applies the results of breakpoint analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="lineBreakpoints"> This parameter contains the results to apply to the range. </param>
        void TextAnalysisSink.SetLineBreakpoints(
			int textPosition, int textLength, DxLineBreakpoint[] lineBreakpoints)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            foreach(int index in range)
            {
                var breakpoint = lineBreakpoints[index - textPosition];

                LineBreakCondition beforeCondition = LineBreakCondition.Neutral;

                switch(breakpoint.BreakConditionBefore)
                {
                    case DxBreakCondition.CanBreak:
                        beforeCondition = LineBreakCondition.CanBreak;
                        break;
                    case DxBreakCondition.MayNotBreak:
                        beforeCondition = LineBreakCondition.MayNotBreak;
                        break;
                    case DxBreakCondition.MustBreak:
                        beforeCondition = LineBreakCondition.MustBreak;
                        break;
                    case DxBreakCondition.Neutral:
                        beforeCondition = LineBreakCondition.Neutral;
                        break;
                }

                LineBreakCondition afterCondition = LineBreakCondition.Neutral;

                switch(breakpoint.BreakConditionAfter)
                {
                    case DxBreakCondition.CanBreak:
                        afterCondition = LineBreakCondition.CanBreak;
                        break;
                    case DxBreakCondition.MayNotBreak:
                        afterCondition = LineBreakCondition.MayNotBreak;
                        break;
                    case DxBreakCondition.MustBreak:
                        afterCondition = LineBreakCondition.MustBreak;
                        break;
                    case DxBreakCondition.Neutral:
                        afterCondition = LineBreakCondition.Neutral;
                        break;
                }

                _TextShaper.Characters[index].Breakpoint = new LineBreakpoint(
                    beforeCondition,
                    afterCondition,
                    breakpoint.IsWhitespace,
                    breakpoint.IsSoftHyphen);
            }
        }
Esempio n. 17
0
        /// <summary>
        ///   This method applies the results of bidi-text analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="explicitLevel"> This parameter indicates the explicit bidi level for the range. </param>
        /// <param name="resolvedLevel"> This parameter indicates the resolved bidi level for the range. </param>
        void TextAnalysisSink.SetBidiLevel(
			int textPosition, int textLength, byte explicitLevel, byte resolvedLevel)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            _TextShaper.SetBidiLevel(range, resolvedLevel);
        }
Esempio n. 18
0
        /// <summary>
        ///   This method retrieves the geometry for a formatted cluster.
        /// </summary>
        /// <param name="clusterIndex"> This parameter indicates the formatted cluster index. </param>
        /// <param name="bidiLevel"> This parameter indicates the bidi level of the cluster. </param>
        /// <param name="font"> This parameter references the font for the cluster. </param>
        /// <param name="input"> This parameter references the formatted text output. </param>
        /// <returns> This method returns the geometry for the formatted cluster if available; otherwise, this method returns <c>null</c> . </returns>
        public Shape Retrieve(
			IndexedRange glyphRange,
			bool isVertical,
			bool isRightToLeft,
			FontHandle font,
			List<Formatting.TextShaper.Glyph> glyphs)
        {
            ResizeInternalBuffers(glyphRange.Length);

            int index = 0;

            foreach(int itemIndex in glyphRange)
            {
                _GlyphAdvances[index] = glyphs[itemIndex].Advance;
                _GlyphIndices[index] = glyphs[itemIndex].Index;

                _GlyphOffsets[index] = new GlyphOffset
                {
                    AdvanceOffset = glyphs[itemIndex].Offset.Width,
                    AscenderOffset = glyphs[itemIndex].Offset.Height
                };

                ++index;
            }

            TextGeometryKey key;

            key.Advances = _GlyphAdvances;
            key.Indices = _GlyphIndices;
            key.Offsets = _GlyphOffsets;

            Dictionary<TextGeometryKey, Shape> cacheForFont;

            if(_Cache.TryGetValue(font, out cacheForFont))
            {
                Shape result;

                if(cacheForFont.TryGetValue(key, out result))
                {
                    return result;
                }
            }
            else
            {
                cacheForFont = new Dictionary<TextGeometryKey, Shape>();

                _Cache.Add(font, cacheForFont);
            }

            Shape geometry = _Sink.CreateGeometry(
                key, isRightToLeft, isVertical, font);

            TextGeometryKey newKey;

            newKey.Advances = (float[])key.Advances.Clone();
            newKey.Indices = (short[])key.Indices.Clone();
            newKey.Offsets = (GlyphOffset[])key.Offsets.Clone();

            cacheForFont.Add(newKey, geometry);

            return geometry;
        }
Esempio n. 19
0
        /// <summary>
        ///   This method applies the given number substition to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="numberSubstitution"> This parameter references the number substitution to apply to the range. </param>
        public void SetNumberSubstitution(IndexedRange textRange, NumberSubstitution numberSubstitution)
        {
            Contract.Assert(textRange.IsWithin(_FullText));

            foreach(int index in textRange)
            {
                _Characters[index].NumberSubstitution = numberSubstitution;
            }
        }
Esempio n. 20
0
        /// <summary>
        ///   This method applies the given font weight to a range of characters.
        /// </summary>
        /// <param name="textRange"> This parameter indicates the range of characters to modify. </param>
        /// <param name="weight"> This parameter indicates the font weight to apply to the range. </param>
        public void SetWeight(IndexedRange textRange, FontWeight weight)
        {
            Contract.Assert(textRange.IsWithin(_OutputSink.FullText));

            foreach(int index in textRange)
            {
                _OutputSink.Characters[index].Weight = weight;
            }
        }
Esempio n. 21
0
        /// <summary>
        ///   This method retrieves cohesive runs of text having identical number substitutions.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the text position. </param>
        /// <param name="textLength"> This output parameter indicates the length of text remaining for processing. </param>
        /// <returns> This method returns the run of text having a consistent number substition at the given position. </returns>
        NumberSubstitution TextAnalysisSource.GetNumberSubstitution(int textPosition, out int textLength)
        {
            IndexedRange range = new IndexedRange(textPosition, _FullText.Length);

            foreach(int index in range)
            {
                if(_Characters[index].NumberSubstitution != _Characters[textPosition].NumberSubstitution)
                {
                    textLength = index - textPosition;

                    return _Characters[textPosition].NumberSubstitution;
                }
            }

            textLength = _FullText.Length - textPosition;

            return _Characters[textPosition].NumberSubstitution;
        }
Esempio n. 22
0
        /// <summary>
        ///   This method applies the results of bidi-text analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="explicitLevel"> This parameter indicates the explicit bidi level for the range. </param>
        /// <param name="resolvedLevel"> This parameter indicates the resolved bidi level for the range. </param>
        void TextAnalysisSink.SetBidiLevel(
			int textPosition, int textLength, byte explicitLevel, byte resolvedLevel)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            foreach(int index in range)
            {
                _OutputSink.Characters[index].BidiLevel = resolvedLevel;
            }
        }
Esempio n. 23
0
			public Builder RestoreState()
			{
				Contract.Ensures(Contract.Result<Builder>() != null);

				TextRun activeState = _States.Pop();

				_ActiveTextRange = activeState.TextRange;
				_ActiveCulture = activeState.Culture;
				_ActiveFamily = activeState.Family;
				_ActiveFeatures = activeState.Features;
				_ActivePointSize = activeState.PointSize;
				_ActiveStretch = activeState.Stretch;
				_ActiveStyle = activeState.Style;
				_ActiveWeight = activeState.Weight;
				_ActiveInline = activeState.Inline;
				_ActiveHAlignment = activeState.HAlignment;
				_ActiveVAlignment = activeState.VAlignment;

				return this;
			}
Esempio n. 24
0
        /// <summary>
        ///   This method applies the results of breakpoint analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="lineBreakpoints"> This parameter contains the results to apply to the range. </param>
        void TextAnalysisSink.SetLineBreakpoints(
			int textPosition, int textLength, DxLineBreakpoint[] lineBreakpoints)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            foreach(int index in range)
            {
                _OutputSink.Characters[index].Breakpoint =
                    new LineBreakpoint(lineBreakpoints[index - textPosition]);
            }
        }
Esempio n. 25
0
        /// <summary>
        ///   This method applies the results of number substition analysis to a range of characters.
        /// </summary>
        /// <param name="textPosition"> This parameter indicates the starting index of the range. </param>
        /// <param name="textLength"> This parameter indicates the length of the range. </param>
        /// <param name="numberSubstitution"> This parameter references the number substition to apply to the range. </param>
        void TextAnalysisSink.SetNumberSubstitution(
			int textPosition, int textLength, NumberSubstitution numberSubstitution)
        {
            IndexedRange range = new IndexedRange(textPosition, textLength);

            foreach(int index in range)
            {
                _OutputSink.Characters[index].NumberSubstitution = numberSubstitution;
            }
        }
Esempio n. 26
0
        public void ComputeRegion(IndexedRange range, out Rectangle region)
        {
            float left = float.MaxValue;
            float top = float.MaxValue;
            float right = float.MinValue;
            float bottom = float.MinValue;

            foreach(int index in range)
            {
                // exclude invisible clusters from consideration
                if(IsVisible(index))
                {
                    // get the cluster index from the text index
                    int cluster = _TextToCluster[index];

                    left = Math.Min(left, _Clusters[cluster].Region.Left);
                    top = Math.Min(top, _Clusters[cluster].Region.Top);
                    right = Math.Max(right, _Clusters[cluster].Region.Right);
                    bottom = Math.Max(bottom, _Clusters[cluster].Region.Bottom);
                }
            }

            region = Rectangle.FromEdges(left, top, right, bottom);
        }