A doubly linked list of text nodes
Наследование: IEnumerable
Пример #1
0
        /// <summary>
        /// Creates node list object associated with the text.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="bounds"></param>
        /// <returns></returns>
        public ProcessedText ProcessText(string text, float maxWidth, QFontAlignment alignment)
        {
            //TODO: bring justify and alignment calculations in here

            maxWidth = TransformWidthToViewport(maxWidth);

            var nodeList = new TextNodeList(text);

            nodeList.MeasureNodes(fontData, Options);

            //we "crumble" words that are two long so that that can be split up
            var nodesToCrumble = new List <TextNode>();

            foreach (TextNode node in nodeList)
            {
                if (node.Length >= maxWidth && node.Type == TextNodeType.Word)
                {
                    nodesToCrumble.Add(node);
                }
            }

            foreach (var node in nodesToCrumble)
            {
                nodeList.Crumble(node, 1);
            }

            //need to measure crumbled words
            nodeList.MeasureNodes(fontData, Options);


            var processedText = new ProcessedText();

            processedText.textNodeList = nodeList;
            processedText.maxWidth     = maxWidth;
            processedText.alignment    = alignment;


            return(processedText);
        }
Пример #2
0
        /// <summary>
        ///     Creates node list object associated with the text.
        /// </summary>
        /// <param name="options">The font render options</param>
        /// <param name="text">The text to process</param>
        /// <param name="font">The <see cref="QFont"/> to process the text with</param>
        /// <param name="maxSize">The maximum size of the processed text</param>
        /// <param name="alignment">The text alignment</param>
        /// <returns>The processed text</returns>
        public static ProcessedText ProcessText(QFont font, QFontRenderOptions options, string text, SizeF maxSize, QFontAlignment alignment)
        {
            //TODO: bring justify and alignment calculations in here
            maxSize.Width = TransformWidthToViewport(maxSize.Width, options);

            var nodeList = new TextNodeList(text);

            nodeList.MeasureNodes(font.FontData, options);

            //we "crumble" words that are two long so that that can be split up
            var nodesToCrumble = new List <TextNode>();

            foreach (TextNode node in nodeList)
            {
                if ((!options.WordWrap || node.Length >= maxSize.Width) && node.Type == TextNodeType.Word)
                {
                    nodesToCrumble.Add(node);
                }
            }

            foreach (TextNode node in nodesToCrumble)
            {
                nodeList.Crumble(node, 1);
            }

            //need to measure crumbled words
            nodeList.MeasureNodes(font.FontData, options);


            var processedText = new ProcessedText();

            processedText.TextNodeList = nodeList;
            processedText.MaxSize      = maxSize;
            processedText.Alignment    = alignment;


            return(processedText);
        }
Пример #3
0
        /// <summary>
        /// Creates node list object associated with the text.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="bounds"></param>
        /// <returns></returns>
        public ProcessedText ProcessText(string text, RectangleF bounds, QFontAlignment alignment)
        {
            //TODO: bring justify and alignment calculations in here

            var nodeList = new TextNodeList(text);

            nodeList.MeasureNodes(fontData, options);

            //we "crumble" words that are two long so that that can be split up
            var nodesToCrumble = new List <TextNode>();

            foreach (TextNode node in nodeList)
            {
                if (node.Length >= bounds.Width && node.Type == TextNodeType.Word)
                {
                    nodesToCrumble.Add(node);
                }
            }

            foreach (var node in nodesToCrumble)
            {
                nodeList.Crumble(node, 1);
            }

            //need to measure crumbled words
            nodeList.MeasureNodes(fontData, options);


            var processedText = new ProcessedText();

            processedText.textNodeList = nodeList;
            processedText.bounds       = bounds;
            processedText.alignment    = alignment;


            return(processedText);
        }
Пример #4
0
        /// <summary>
        /// Creates node list object associated with the text.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="bounds"></param>
        /// <returns></returns>
        public ProcessedText ProcessText(string text, SizeF maxSize, QFontAlignment alignment)
        {
            //TODO: bring justify and alignment calculations in here

            maxSize.Width = TransformWidthToViewport(maxSize.Width);

            var nodeList = new TextNodeList(text);
            nodeList.MeasureNodes(fontData, Options);

            //we "crumble" words that are two long so that that can be split up
            var nodesToCrumble = new List<TextNode>();
            foreach (TextNode node in nodeList)
                if ((!Options.WordWrap || node.Length >= maxSize.Width) && node.Type == TextNodeType.Word)
                    nodesToCrumble.Add(node);

            foreach (var node in nodesToCrumble)
                nodeList.Crumble(node, 1);

            //need to measure crumbled words
            nodeList.MeasureNodes(fontData, Options);

            var processedText = new ProcessedText();
            processedText.textNodeList = nodeList;
            processedText.maxSize = maxSize;
            processedText.alignment = alignment;

            return processedText;
        }
Пример #5
0
 public TextNodeListEnumerator(TextNodeList targetList)
 {
     this.targetList = targetList;
 }
Пример #6
0
        private SizeF PrintOrMeasure(ProcessedText processedText, bool measureOnly, Rectangle clippingRectangle = default(Rectangle))
        {
            // init values we'll return
            float maxMeasuredWidth = 0f;

            float xPos = 0f;
            float yPos = 0f;

            float xOffset = xPos;
            float yOffset = yPos;

            //make sure fontdata font's options are synced with the actual options
            ////if (_font.FontData.dropShadowFont != null && _font.FontData.dropShadowFont.Options != this.Options)
            ////{
            ////    _font.FontData.dropShadowFont.Options = this.Options;
            ////}

            float          maxWidth  = processedText.maxSize.Width;
            QFontAlignment alignment = processedText.alignment;


            //TODO - use these instead of translate when rendering by position (at some point)

            TextNodeList nodeList = processedText.textNodeList;

            for (TextNode node = nodeList.Head; node != null; node = node.Next)
            {
                node.LengthTweak = 0f; //reset tweaks
            }
            if (alignment == QFontAlignment.Right)
            {
                xOffset -= (float)Math.Ceiling(TextNodeLineLength(nodeList.Head, maxWidth) - maxWidth);
            }
            else if (alignment == QFontAlignment.Centre)
            {
                xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(nodeList.Head, maxWidth));
            }
            else if (alignment == QFontAlignment.Justify)
            {
                JustifyLine(nodeList.Head, maxWidth);
            }


            bool  atLeastOneNodeCosumedOnLine = false;
            float length = 0f;

            for (TextNode node = nodeList.Head; node != null; node = node.Next)
            {
                bool newLine = false;

                if (node.Type == TextNodeType.LineBreak)
                {
                    newLine = true;
                }
                else
                {
                    if (this.Options.WordWrap && SkipTrailingSpace(node, length, maxWidth) && atLeastOneNodeCosumedOnLine)
                    {
                        newLine = true;
                    }
                    else if (length + node.ModifiedLength <= maxWidth || !atLeastOneNodeCosumedOnLine)
                    {
                        atLeastOneNodeCosumedOnLine = true;

                        if (!measureOnly)
                        {
                            RenderWord(xOffset + length, yOffset, node, ref clippingRectangle);
                        }
                        length += node.ModifiedLength;

                        maxMeasuredWidth = Math.Max(length, maxMeasuredWidth);
                    }
                    else if (this.Options.WordWrap)
                    {
                        newLine = true;
                        if (node.Previous != null)
                        {
                            node = node.Previous;
                        }
                    }
                    else
                    {
                        continue; // continue so we still read line breaks even if reached max width
                    }
                }

                if (newLine)
                {
                    if (processedText.maxSize.Height > 0 &&
                        yOffset + LineSpacing - yPos >= processedText.maxSize.Height)
                    {
                        break;
                    }

                    yOffset += LineSpacing;
                    xOffset  = xPos;
                    length   = 0f;
                    atLeastOneNodeCosumedOnLine = false;

                    if (node.Next != null)
                    {
                        if (alignment == QFontAlignment.Right)
                        {
                            xOffset -= (float)Math.Ceiling(TextNodeLineLength(node.Next, maxWidth) - maxWidth);
                        }
                        else if (alignment == QFontAlignment.Centre)
                        {
                            xOffset -= (float)Math.Ceiling(0.5f * TextNodeLineLength(node.Next, maxWidth));
                        }
                        else if (alignment == QFontAlignment.Justify)
                        {
                            JustifyLine(node.Next, maxWidth);
                        }
                    }
                }
            }

            LastSize = new SizeF(maxMeasuredWidth, yOffset + LineSpacing - yPos);
            return(LastSize);
        }
Пример #7
0
 public TextNodeListEnumerator(TextNodeList targetList)
 {
     this.targetList = targetList;
 }
Пример #8
0
        /// <summary>
        /// Creates node list object associated with the text.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="bounds"></param>
        /// <returns></returns>
        public ProcessedText ProcessText(string text, RectangleF bounds, QFontAlignment alignment)
        {
            //TODO: bring justify and alignment calculations in here

            var nodeList = new TextNodeList(text);
            nodeList.MeasureNodes(fontData, options);

            //we "crumble" words that are two long so that that can be split up
            var nodesToCrumble = new List<TextNode>();
            foreach (TextNode node in nodeList)
                if (node.Length >= bounds.Width && node.Type == TextNodeType.Word)
                    nodesToCrumble.Add(node);

            foreach (var node in nodesToCrumble)
                nodeList.Crumble(node, 1);

            //need to measure crumbled words
            nodeList.MeasureNodes(fontData, options);

            var processedText = new ProcessedText();
            processedText.textNodeList = nodeList;
            processedText.bounds = bounds;
            processedText.alignment = alignment;

            return processedText;
        }
Пример #9
0
		private ProcessedText SafeProcessText(Rectangle clientRectangle, string text, float maxWidth, QFontAlignment alignment)
		{
			//TODO: bring justify and alignment calculations in here

			maxWidth = TransformWidthToViewport(clientRectangle, maxWidth);

			var nodeList = new TextNodeList(text);
			nodeList.MeasureNodes(fontData, Options);

			//we "crumble" words that are two long so that that can be split up
			var nodesToCrumble = new List<TextNode>();
			foreach (TextNode node in nodeList)
				if (node.Length >= maxWidth && node.Type == TextNodeType.Word)
					nodesToCrumble.Add(node);

			foreach (var node in nodesToCrumble)
				nodeList.Crumble(node, 1);

			//need to measure crumbled words
			nodeList.MeasureNodes(fontData, Options);


			var processedText = new ProcessedText();
			processedText.textNodeList = nodeList;
			processedText.maxWidth = maxWidth;
			processedText.alignment = alignment;

			return processedText;
		}