Пример #1
0
        /// <summary>
        /// Create a rectangle of the two specified UV coordinates
        /// </summary>
        /// <param name="origin">line drawing origin</param>
        /// <param name="topLeft">logical top-left point</param>
        /// <param name="bottomRight">logical bottom-right point</param>
        /// <param name="line">container line</param>
        internal static Rect RectUV(
            Point origin,
            LSPOINT topLeft,
            LSPOINT bottomRight,
            TextMetrics.FullTextLine line
            )
        {
            int dx = topLeft.x - bottomRight.x;

            if (dx == 1 || dx == -1)
            {
                // in certain situation LS can be off by 1
                bottomRight.x = topLeft.x;
            }

            Rect rect = new Rect(
                new Point(line.Formatter.IdealToReal(topLeft.x, line.PixelsPerDip), line.Formatter.IdealToReal(topLeft.y, line.PixelsPerDip)),
                new Point(line.Formatter.IdealToReal(bottomRight.x, line.PixelsPerDip), line.Formatter.IdealToReal(bottomRight.y, line.PixelsPerDip))
                );

            if (DoubleUtil.AreClose(rect.TopLeft.X, rect.BottomRight.X))
            {
                rect.Width = 0;
            }

            if (DoubleUtil.AreClose(rect.TopLeft.Y, rect.BottomRight.Y))
            {
                rect.Height = 0;
            }

            return(rect);
        }
Пример #2
0
        private double _baseGuidelineY;                                 // the Y guideline of the text line.

        /// <summary>
        /// Construct drawing state for full text
        /// </summary>
        internal DrawingState(
            DrawingContext drawingContext,
            Point lineOrigin,
            MatrixTransform antiInversion,
            TextMetrics.FullTextLine currentLine
            )
        {
            _drawingContext = drawingContext;
            _antiInversion  = antiInversion;
            _currentLine    = currentLine;

            if (antiInversion == null)
            {
                _lineOrigin = lineOrigin;
            }
            else
            {
                _vectorToLineOrigin = lineOrigin;
            }

            if (_drawingContext != null)
            {
                // LineServices draws GlyphRun and TextDecorations in multiple
                // callbacks and GlyphRuns may have different baselines. Pushing guideline
                // for each DrawGlyphRun are too costly. We optimize for the common case where
                // GlyphRuns and TextDecorations in the TextLine share the same baseline.
                _baseGuidelineY = lineOrigin.Y + currentLine.Baseline;

                _drawingContext.PushGuidelineY1(_baseGuidelineY);
            }
        }
Пример #3
0
        /// <summary>
        /// Format and produce a text line either with or without previously known
        /// line break point.
        /// </summary>
        private TextLine FormatLineInternal(
            TextSource textSource,
            int firstCharIndex,
            int lineLength,
            double paragraphWidth,
            TextParagraphProperties paragraphProperties,
            TextLineBreak previousLineBreak,
            TextRunCache textRunCache
            )
        {
            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordText, EventTrace.Level.Verbose, EventTrace.Event.WClientStringBegin, "TextFormatterImp.FormatLineInternal Start");

            // prepare formatting settings
            FormatSettings settings = PrepareFormatSettings(
                textSource,
                firstCharIndex,
                paragraphWidth,
                paragraphProperties,
                previousLineBreak,
                textRunCache,
                (lineLength != 0), // Do optimal break if break is given
                true,              // isSingleLineFormatting
                _textFormattingMode
                );

            TextLine textLine = null;

            if (!settings.Pap.AlwaysCollapsible &&
                previousLineBreak == null &&
                lineLength <= 0
                )
            {
                // simple text line.
                textLine = SimpleTextLine.Create(
                    settings,
                    firstCharIndex,
                    RealToIdealFloor(paragraphWidth),
                    textSource.PixelsPerDip
                    ) as TextLine;
            }

            if (textLine == null)
            {
                // content is complex, creating complex line
                textLine = new TextMetrics.FullTextLine(
                    settings,
                    firstCharIndex,
                    lineLength,
                    RealToIdealFloor(paragraphWidth),
                    LineFlags.None
                    ) as TextLine;
            }

            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordText, EventTrace.Level.Verbose, EventTrace.Event.WClientStringEnd, "TextFormatterImp.FormatLineInternal End");

            return(textLine);
        }
Пример #4
0
        /// <summary>
        /// Map a UV ideal coordinate to an XY ideal coordinate
        /// </summary>
        /// <param name="origin">line drawing origin</param>
        /// <param name="vectorToOrigin">vector to line origin UV</param>
        /// <param name="u">ideal distance in text flow direction</param>
        /// <param name="v">ideal distance in paragraph flow direction</param>
        /// <param name="line">container line</param>
        /// <param name="nominalX">ideal X origin</param>
        /// <param name="nominalY">ideal Y origin</param>
        internal static void UVToNominalXY(
            Point origin,
            Point vectorToOrigin,
            int u,
            int v,
            TextMetrics.FullTextLine line,
            out int nominalX,
            out int nominalY
            )
        {
            origin.Y += vectorToOrigin.Y;

            if (line.RightToLeft)
            {
                nominalX = line.ParagraphWidth - u + TextFormatterImp.RealToIdeal(-vectorToOrigin.X + origin.X);
            }
            else
            {
                nominalX = u + TextFormatterImp.RealToIdeal(vectorToOrigin.X + origin.X);
            }

            nominalY = v + TextFormatterImp.RealToIdeal(origin.Y);
        }
Пример #5
0
        /// <summary>
        /// Map a UV ideal coordinate to an XY real coordinate
        /// </summary>
        /// <param name="origin">line drawing origin</param>
        /// <param name="vectorToOrigin">vector to line origin UV</param>
        /// <param name="u">ideal distance in text flow direction</param>
        /// <param name="v">ideal distance in paragraph flow direction</param>
        /// <param name="line">container line</param>
        internal static Point UVToXY(
            Point origin,
            Point vectorToOrigin,
            int u,
            int v,
            TextMetrics.FullTextLine line
            )
        {
            Point xy;

            origin.Y += vectorToOrigin.Y;

            if (line.RightToLeft)
            {
                xy = new Point(line.Formatter.IdealToReal(line.ParagraphWidth - u, line.PixelsPerDip) - vectorToOrigin.X + origin.X, line.Formatter.IdealToReal(v, line.PixelsPerDip) + origin.Y);
            }
            else
            {
                xy = new Point(line.Formatter.IdealToReal(u, line.PixelsPerDip) + vectorToOrigin.X + origin.X, line.Formatter.IdealToReal(v, line.PixelsPerDip) + origin.Y);
            }

            return(xy);
        }
        /// <summary>
        /// Map a UV real coordinate to an XY real coordinate
        /// </summary>
        /// <param name="origin">line drawing origin XY</param>
        /// <param name="vectorToOrigin">vector to line origin UV</param>
        /// <param name="u">real distance in text flow direction</param>
        /// <param name="v">real distance in paragraph flow direction</param>
        /// <param name="line">container line</param>
        internal static Point UVToXY(
            Point origin,
            Point vectorToOrigin,
            double u,
            double v,
            TextMetrics.FullTextLine line
            )
        {
            Point xy;

            origin.Y += vectorToOrigin.Y;

            if (line.RightToLeft)
            {
                xy = new Point(line.Formatter.IdealToReal(line.ParagraphWidth) - vectorToOrigin.X - u + origin.X, v + origin.Y);
            }
            else
            {
                xy = new Point(u + vectorToOrigin.X + origin.X, v + origin.Y);
            }

            return(xy);
        }
        /// <summary>
        /// Client to ask for the possible smallest and largest paragraph width that can fully contain the passing text content
        /// </summary>
        /// <param name="textSource">an object representing text layout clients text source for TextFormatter.</param>
        /// <param name="firstCharIndex">character index to specify where in the source text the line starts</param>
        /// <param name="paragraphProperties">properties that can change from one paragraph to the next, such as text flow direction, text alignment, or indentation.</param>
        /// <param name="textRunCache">an object representing content cache of the client.</param>
        /// <returns>min max paragraph width</returns>
        public override MinMaxParagraphWidth FormatMinMaxParagraphWidth(
            TextSource textSource,
            int firstCharIndex,
            TextParagraphProperties paragraphProperties,
            TextRunCache textRunCache
            )
        {
            // prepare formatting settings
            FormatSettings settings = PrepareFormatSettings(
                textSource,
                firstCharIndex,
                0,      // infinite paragraphWidth
                paragraphProperties,
                null,   // always format the whole paragraph - no previousLineBreak
                textRunCache,
                false,  // optimalBreak
                true,   // isSingleLineFormatting
                _textFormattingMode
                );

            // create specialized line specifically for min/max calculation
            TextMetrics.FullTextLine line = new TextMetrics.FullTextLine(
                settings,
                firstCharIndex,
                0,  // lineLength
                0,  // paragraph width has no significant meaning in min/max calculation
                (LineFlags.KeepState | LineFlags.MinMax)
                );

            // line width in this case is the width of a line when the entire paragraph is laid out
            // as a single long line.
            MinMaxParagraphWidth minMax = new MinMaxParagraphWidth(line.MinWidth, line.Width);

            line.Dispose();
            return(minMax);
        }