Esempio n. 1
0
        public override bool Compose(DrawContext dc, Style c, int availWidth, out ItemMetrics im, bool suppressWhitespace, out ITextLayout next)
        {
            TextItemMetrics metrics = new TextItemMetrics(this);

            im = metrics;

            this.style = c;
            next       = null;
            // TODO: L: optimise
            Size sz = dc.Graphics.MeasureText(" ");

            spaceWidth = sz.Width;
            height     = sz.Height;
            width      = 0;
            // get the font ascent
            ascent = c.FontAscent;

            if (textNode.NodeType == XmlNodeType.SignificantWhitespace)
            {
                // special case, simply set to single space width and return
                width = sz.Width;
                len   = textNode.Value.Length;
                metrics.CanBreakBefore = true;
                metrics.CanBreakAfter  = true;
                return(true);
            }

            int startSpaceCount = GetStartSpaceCount();

            if (startSpaceCount > 0 && suppressWhitespace)
            {
                TrimStart(startSpaceCount);
                startSpaceCount = 0;
            }

            if (startSpaceCount > 1)
            {
                TrimStart(startSpaceCount - 1);
                startSpaceCount = 1;
            }

            len = startSpaceCount;
            if (start + len == textNode.Value.Length)
            {
                // this is pure whitespace
                width = sz.Width;
                return(true);
            }

            metrics.CanBreakBefore = startSpaceCount > 0;

            bool hasMoreContent = true;
            bool firstWord      = true;
            bool fit            = false;
            int  endSpaceCount  = 0;

            int  finalWidth  = startSpaceCount * spaceWidth;
            int  splitLen    = 0;
            int  splitWidth  = 0;
            bool needNewline = false;

//			bool newline=false;

            while (hasMoreContent)
            {
                int testLen;
                int tesc;
                hasMoreContent = IncludeNextWord(out testLen, out tesc);

                string segString  = textNode.Value.Substring(start + len, testLen - len - tesc);
                string testString = ProcessText(segString);
                int    segWidth   = dc.Graphics.MeasureText(testString).Width;
                int    testWidth  = finalWidth + segWidth;

//				string testString=ProcessText(textNode.Value.Substring(start, testLen-tesc));
//				int testWidth=dc.Graphics.MeasureText(testString).Width;

                fit = testWidth < availWidth;

                if (fit || firstWord)
                {
                    // either it fits or it has to fit because this is the first word
                    metrics.AddSegment(start + len, testLen - len, segWidth);

                    splitLen      = len;
                    len           = testLen;
                    splitWidth    = finalWidth;
                    endSpaceCount = tesc;
                    finalWidth    = testWidth + (endSpaceCount > 0 ? spaceWidth : 0);

                    if (!fit && firstWord)
                    {
                        needNewline = true;
                    }

                    if (!fit || endSpaceCount > 1)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }

                firstWord = false;
            }

            // this is handled by custom class
//			if ( style.Pre && newline )
//				bi.ForceBreakAfter=true;

            Debug.Assert(len > 0, "Must have laid out something!");

            // at this point we have these possibilities:
            //		everything fit - fit == true, nothing to do, return true
            //		not everything fit - fit == false, get next, return false
            //			and cannot split - oldLen=-1, return false
            //			and can split - oldLen > 0, ConfigureSplitInfo, return true

            metrics.CanBreakAfter = endSpaceCount > 0;
            width = finalWidth;

            if (splitLen > 0)
            {
                canSplit        = true;
                splitIndex      = splitLen;
                splitLeftWidth  = splitWidth;
                splitRightWidth = finalWidth - splitWidth;
            }

            if (start + len < textNode.Value.Length)
            {
                next = GetNextFragment();
            }

            if (endSpaceCount > 1)
            {
                TrimEnd(endSpaceCount - 1);
                endSpaceCount = 1;
            }

            return(!needNewline);
        }
Esempio n. 2
0
        public override bool Compose(DrawContext dc, Style c, int availWidth, out ItemMetrics im, bool suppressWhitespace, out ITextLayout next)
        {
            TextItemMetrics metrics=new TextItemMetrics(this);
            im=metrics;

            this.style=c;
            next=null;
            // TODO: L: optimise
            Size sz=dc.Graphics.MeasureText(" ");
            spaceWidth=sz.Width;
            height=sz.Height;
            width=0;
            // get the font ascent
            ascent=c.FontAscent;

            if ( textNode.NodeType == XmlNodeType.SignificantWhitespace )
            {
                // special case, simply set to single space width and return
                width=sz.Width;
                len=textNode.Value.Length;
                metrics.CanBreakBefore=true;
                metrics.CanBreakAfter=true;
                return true;
            }

            int startSpaceCount=GetStartSpaceCount();
            if ( startSpaceCount > 0 && suppressWhitespace )
            {
                TrimStart(startSpaceCount);
                startSpaceCount=0;
            }

            if ( startSpaceCount > 1 )
            {
                TrimStart(startSpaceCount - 1);
                startSpaceCount=1;
            }

            len=startSpaceCount;
            if ( start+len == textNode.Value.Length )
            {
                // this is pure whitespace
                width=sz.Width;
                return true;
            }

            metrics.CanBreakBefore=startSpaceCount > 0;

            bool hasMoreContent=true;
            bool firstWord=true;
            bool fit=false;
            int endSpaceCount=0;

            int finalWidth=startSpaceCount * spaceWidth;
            int splitLen=0;
            int splitWidth=0;
            bool needNewline=false;
            //			bool newline=false;

            while ( hasMoreContent )
            {
                int testLen;
                int tesc;
                hasMoreContent=IncludeNextWord(out testLen, out tesc);

                string segString=textNode.Value.Substring(start+len, testLen-len-tesc);
                string testString=ProcessText(segString);
                int segWidth=dc.Graphics.MeasureText(testString).Width;
                int testWidth=finalWidth+segWidth;

            //				string testString=ProcessText(textNode.Value.Substring(start, testLen-tesc));
            //				int testWidth=dc.Graphics.MeasureText(testString).Width;

                fit=testWidth < availWidth;

                if ( fit || firstWord )
                {
                    // either it fits or it has to fit because this is the first word
                    metrics.AddSegment(start+len, testLen-len, segWidth);

                    splitLen=len;
                    len=testLen;
                    splitWidth=finalWidth;
                    endSpaceCount=tesc;
                    finalWidth=testWidth + (endSpaceCount > 0 ? spaceWidth : 0);

                    if ( !fit && firstWord )
                        needNewline=true;

                    if ( !fit || endSpaceCount > 1 )
                        break;
                }
                else
                    break;

                firstWord=false;
            }

            // this is handled by custom class
            //			if ( style.Pre && newline )
            //				bi.ForceBreakAfter=true;

            Debug.Assert(len > 0, "Must have laid out something!");

            // at this point we have these possibilities:
            //		everything fit - fit == true, nothing to do, return true
            //		not everything fit - fit == false, get next, return false
            //			and cannot split - oldLen=-1, return false
            //			and can split - oldLen > 0, ConfigureSplitInfo, return true

            metrics.CanBreakAfter=endSpaceCount > 0;
            width=finalWidth;

            if ( splitLen > 0 )
            {
                canSplit=true;
                splitIndex=splitLen;
                splitLeftWidth=splitWidth;
                splitRightWidth=finalWidth-splitWidth;
            }

            if ( start+len < textNode.Value.Length )
                next=GetNextFragment();

            if ( endSpaceCount > 1 )
            {
                TrimEnd(endSpaceCount - 1);
                endSpaceCount=1;
            }

            return !needNewline;
        }