コード例 #1
0
        // TODO: Destructor.
        // TODO: ~RenderedStringWordWrapper(){DeleteFormatters();}

        // implementation of base interface

        // TODO: specialised version of format used with Justified text
        public override void Format(Window refWnd, Sizef areaSize)
        {
            DeleteFormatters();

            var lstring = new RenderedString();
            var rstring = new RenderedString(d_renderedString);

            T frs;

            for (var line = 0; line < rstring.GetLineCount(); ++line)
            {
                float rsWidth;
                while ((rsWidth = rstring.GetPixelSize(refWnd, line).Width) > 0)
                {
                    // skip line if no wrapping occurs
                    if (rsWidth <= areaSize.Width)
                    {
                        break;
                    }

                    // split rstring at width into lstring and remaining rstring
                    rstring.Split(refWnd, line, areaSize.Width, lstring);
                    //frs = _constructor(new RenderedString(lstring));
                    frs = new T();
                    frs.SetRenderedString(new RenderedString(lstring));
                    frs.Format(refWnd, areaSize);
                    Lines.Add(frs);
                    line = 0;
                }
            }

            // last line.
            //frs = _constructor(new RenderedString(rstring));
            frs = new T();
            frs.SetRenderedString(new RenderedString(rstring));
            frs.Format(refWnd, areaSize);
            Lines.Add(frs);
        }
コード例 #2
0
        /// <summary>
        /// split the string in line \a line as close to \a split_point as possible.
        /// <para>
        /// The RenderedString \a left will receive the left portion of the split,
        /// while the right portion of the split will remain in this RenderedString.
        /// </para>
        /// </summary>
        /// <param name="refWnd"></param>
        /// <param name="line">
        /// The line number on which the split is to occur.
        /// </param>
        /// <param name="splitPoint">
        /// float value specifying the pixel location where the split should occur.
        /// The actual split will occur as close to this point as possible, though
        /// preferring a shorter 'left' portion when the split can not be made
        /// exactly at the requested point.
        /// </param>
        /// <param name="left">
        /// RenderedString object that will receieve the left portion of the split.
        /// Any existing content in the RenderedString is replaced.
        /// </param>
        /// <exception cref="InvalidRequestException">
        /// thrown if \a line is out of range.
        /// </exception>
        public void Split(Window refWnd, int line, float splitPoint, RenderedString left)
        {
            // FIXME: This function is big and nasty; it breaks all the rules for a
            // 'good' function and desperately needs some refactoring work done to it.
            // On the plus side, it does seem to work though ;)

            if (line >= GetLineCount())
            {
                throw new InvalidRequestException("line number specified is invalid.");
            }

            left.ClearComponents();

            if (d_components.Count == 0)
            {
                return;
            }

            // move all components in lines prior to the line being split to the left
            if (line > 0)
            {
                // calculate size of range
                var sz = d_lines[line - 1].First + d_lines[line - 1].Second;

                //// range start
                //ComponentList::iterator cb = d_components.begin();
                //// range end (exclusive)
                //ComponentList::iterator ce = cb + sz;
                //// copy components to left side
                //left.d_components.assign(cb, ce);
                //// erase components from this side.
                //d_components.erase(cb, ce);
                for (int i = 0; i < sz; i++)
                {
                    left.d_components.Add(d_components[0]);
                    d_components.RemoveAt(0);
                }

                //LineList::iterator lb = d_lines.begin();
                //LineList::iterator le = lb + line;
                //// copy lines to left side
                //left.d_lines.assign(lb, le);
                //// erase lines from this side
                //d_lines.erase(lb, le);
                for (int i = 0; i < line; i++)
                {
                    left.d_lines.Add(d_lines[0]);
                    d_lines.RemoveAt(0);
                }
            }

            // find the component where the requested split point lies.
            var partialExtent = 0f;

            var idx           = 0;
            var lastComponent = d_lines[0].Second;

            for (; idx < lastComponent; ++idx)
            {
                partialExtent += d_components[idx].GetPixelSize(refWnd).Width;

                if (splitPoint <= partialExtent)
                {
                    break;
                }
            }

            // case where split point is past the end
            if (idx >= lastComponent)
            {
                // transfer this line's components to the 'left' string.
                //
                // calculate size of range
                var sz = d_lines[0].Second;
                //// range start
                //ComponentList::iterator cb = d_components.begin();
                //// range end (exclusive)
                //ComponentList::iterator ce = cb + sz;
                //// copy components to left side
                //left.d_components.insert(left.d_components.end(), cb, ce);
                //// erase components from this side.
                //d_components.erase(cb, ce);
                for (int i = 0; i < sz; i++)
                {
                    left.d_components.Add(d_components[0]);
                    d_components.RemoveAt(0);
                }

                // copy line info to left side
                left.d_lines.Add(d_lines[0]);
                // erase line from this side
                d_lines.RemoveAt(0);

                // fix up lines in this object
                for (int comp = 0, i = 0; i < d_lines.Count; ++i)
                {
                    d_lines[i].First = comp;
                    comp            += d_lines[i].Second;
                }

                return;
            }

            left.AppendLineBreak();
            var leftLine = left.GetLineCount() - 1;

            // Everything up to 'idx' is xfered to 'left'
            for (var i = 0; i < idx; ++i)
            {
                left.d_components.Add(d_components[0]);
                d_components.RemoveAt(0);
                ++left.d_lines[leftLine].Second;
                --d_lines[0].Second;
            }

            // now to split item 'idx' putting half in left and leaving half in this.
            RenderedStringComponent c = d_components[0];

            if (c.CanSplit())
            {
                var lc = c.Split(refWnd, splitPoint - (partialExtent - c.GetPixelSize(refWnd).Width), idx == 0);

                if (lc != null)
                {
                    left.d_components.Add(lc);
                    ++left.d_lines[leftLine].Second;
                }
            }
            // can't split, if component width is >= split_point xfer the whole
            // component to it's own line in the left part (FIX #306)
            else if (c.GetPixelSize(refWnd).Width >= splitPoint)
            {
                left.AppendLineBreak();
                left.d_components.Add(d_components[0]);
                d_components.RemoveAt(0);
                ++left.d_lines[leftLine + 1].Second;
                --d_lines[0].Second;
            }

            // fix up lines in this object
            for (int comp = 0, i = 0; i < d_lines.Count; ++i)
            {
                d_lines[i].First = comp;
                comp            += d_lines[i].Second;
            }
        }