Exemple #1
0
        /// <summary>
        /// Add something to the line. Return true if we should keep trying to add more. (That is, all of the current thing fit,
        /// and there is still room left; this routine is not responsible to determine whether there IS anything else to add.)
        /// If there is not yet anything in the line, this routine MUST add something; otherwise, it is allowed to fail,
        /// returning false without changing anything.
        /// </summary>
        private bool AddSomethingToLine()
        {
            m_currentRenderRun = m_renderRuns[m_renderRunIndex];
            Box boxToAdd = m_currentRenderRun.Box;

            if (boxToAdd != null)
            {
                // The current run works out to a single box; add it if it fits. Add it anyway if the line
                // is currently empty.
                boxToAdd.Layout(m_layoutInfo);
                if (m_currentLine.FirstBox != null && boxToAdd.Width > m_spaceLeftOnCurrentLine)
                {
                    return(false);
                }
                m_spaceLeftOnCurrentLine -= boxToAdd.Width;
                AddBoxToLine(boxToAdd, LgEndSegmentType.kestOkayBreak);                 // always OK to break after non-string.
                boxToAdd.Container = m_para;
                m_ichRendered      = m_currentRenderRun.RenderLim;
                m_renderRunIndex++;
            }
            else
            {
                // current run is not a simple box. Make a text box out of part or all of it, or possibly also subsequent
                // runs that are not boxes and use the same renderer.
                IRenderEngine renderer = m_layoutInfo.GetRenderer(m_currentRenderRun.Ws);
                // If our text source doesn't yet know about the writing system factory, make sure it does.
                if (m_para.Source.GetWsFactory() == null)
                {
                    m_para.Source.SetWsFactory(renderer.WritingSystemFactory);
                }
                int              ichRunLim = GetLimitOfRunWithSameRenderer(renderer, m_renderRunIndex);
                ILgSegment       seg;
                int              dichLim, dxWidth;
                LgEndSegmentType est;
                bool             mustGetSomeSeg = m_currentLine.FirstBox == null;
                var              twsh           = GetNextTwsh();

                renderer.FindBreakPoint(m_layoutInfo.VwGraphics, m_para.Source, null, m_ichRendered,
                                        ichRunLim, ichRunLim, false, mustGetSomeSeg, m_spaceLeftOnCurrentLine, (mustGetSomeSeg ? LgLineBreak.klbClipBreak : LgLineBreak.klbWordBreak),
                                        m_currentLine.FirstBox == null ? LgLineBreak.klbClipBreak : LgLineBreak.klbWordBreak, twsh,
                                        false, out seg, out dichLim, out dxWidth, out est, null);
                if (est == LgEndSegmentType.kestNothingFit && twsh != LgTrailingWsHandling.ktwshAll)
                {
                    // Nothing of the one we were trying for, try for the other.
                    twsh = GetNextTwsh();
                    renderer.FindBreakPoint(m_layoutInfo.VwGraphics, m_para.Source, null, m_ichRendered,
                                            ichRunLim, ichRunLim, false, mustGetSomeSeg, m_spaceLeftOnCurrentLine, (mustGetSomeSeg ? LgLineBreak.klbClipBreak : LgLineBreak.klbWordBreak),
                                            m_currentLine.FirstBox == null ? LgLineBreak.klbClipBreak : LgLineBreak.klbWordBreak, twsh,
                                            false, out seg, out dichLim, out dxWidth, out est, null);
                }
                switch (est)
                {
                case LgEndSegmentType.kestNoMore:
                case LgEndSegmentType.kestOkayBreak:
                case LgEndSegmentType.kestMoreLines:
                case LgEndSegmentType.kestWsBreak:
                case LgEndSegmentType.kestMoreWhtsp:
                    boxToAdd = new StringBox(m_para.Style, seg, m_ichRendered);
                    boxToAdd.Layout(m_layoutInfo);
                    m_spaceLeftOnCurrentLine -= boxToAdd.Width;
                    m_ichRendered            += dichLim;
                    boxToAdd.Container        = m_para;
                    // If we get NoMore, we should also check, because it might really be a ws break at the end
                    // of the run.
                    if (est == LgEndSegmentType.kestNoMore && ichRunLim < m_para.Source.Length && ichRunLim > 0 &&
                        WsInSource(ichRunLim - 1, m_para.Source) != WsInSource(ichRunLim, m_para.Source))
                    {
                        // The renderer failed to detect it because not told to look further in the source,
                        // but there is in fact a writing system break.
                        // However, if the next character is a box, we want to treat it as a definitely good break.
                        if (m_para.Source.IsThereABoxAt(ichRunLim))
                        {
                            est = LgEndSegmentType.kestOkayBreak;
                        }
                        else
                        {
                            est = LgEndSegmentType.kestWsBreak;
                        }
                    }
                    AddBoxToLine(boxToAdd, est);
                    m_renderRunIndex = AdvanceRenderRunIndexToIch(m_ichRendered, m_renderRunIndex);
                    // We want to return true if more could be put on this line.
                    // Of the cases that take this branch, NoMore means no more input at all, so we can't add any more;
                    // MoreLines means this line is full. So for both of those we return false. OkayBreak allows us to try
                    // to put more segments on this line, as does ws break, and moreWhtsp.
                    return(est == LgEndSegmentType.kestOkayBreak || est == LgEndSegmentType.kestWsBreak || est == LgEndSegmentType.kestMoreWhtsp);

                case LgEndSegmentType.kestNothingFit:
                    Debug.Assert(m_currentLine.FirstBox != null, "Making segment must not return kestNothingFit if line contains nothing");
                    return(false);

                //case LgEndSegmentType.kestHardBreak:
                //    if()
                //    return true;
                default:
                    Debug.Assert(false);
                    break;
                }
            }
            return(true);
        }