Exemple #1
0
        public TextPipeline(FontDevice fontDevice)
        {
            Contract.Requires(fontDevice != null);

            _FontDevice = fontDevice;

            _TextAnalyzer = new Analyzer(_FontDevice.Factory);
            _AggregatorSink = new AggregatorSink();
            _Aggregator = new Aggregator(_AggregatorSink);
            _ShaperSink = new ShaperSink();
            _Shaper = new Shaper(_FontDevice, _ShaperSink);
            _FormatterSink = new FormatterSink();
            _Formatter = new Formatter(_FormatterSink);
            _TypesetterSink = new TypesetterSink();
            _Typesetter = new Typesetter(_TypesetterSink);
            _GeometryCache = new TextGeometryCache();
        }
        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);
        }
        /// <summary>
        ///   This method creates an outline collection.
        /// </summary>
        /// <param name="formattedData"> This parameter references the formatted input sink. </param>
        /// <param name="geometryCache"> This parameter references the text geometry cache. </param>
        /// <param name="clusterBidiLevels"> This parameter references the cluster bidi levels. </param>
        /// <returns> This method returns a new outline collection containing an outline for each formatted cluster. </returns>
        private static OutlineCollection CreateOutlineList(
			FormatterSink formattedData, TextGeometryCache geometryCache, out byte[] clusterBidiLevels)
        {
            _OutlineListBuilder.Clear();

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

            int geometryClusterIndex = 0;

            for(int i = 0; i < formattedData.Runs.Count; ++i)
            {
                FormattedRun run = formattedData.Runs[i];

                FontFace face = run.Font.ResolveFace();

                float emSize = face.Metrics.Ascent + face.Metrics.Descent;

                float baseline = face.Metrics.Ascent / emSize;

                foreach(int clusterIndex in run.Clusters)
                {
                    Geometry geometry = geometryCache.Retrieve(
                        clusterIndex, run.BidiLevel, run.Font, formattedData);

                    _OutlineListBuilder.Add(new Outline(geometry, run.EmSize, baseline));

                    clusterBidiLevels[geometryClusterIndex] = run.BidiLevel;

                    geometryClusterIndex++;
                }
            }

            return new OutlineCollection(_OutlineListBuilder);
        }