Represents a word inside an inline box
Because of performance, words of text are the most atomic element in the project. It should be characters, but come on, imagine the performance when drawing char by char on the device.
It may change for future versions of the library.
Пример #1
0
        void SetupStartHitPoint(CssBoxHitChain startChain, ITextService textService)
        {
            //find global location of start point
            HitInfo startHit = startChain.GetLastHit();

            //-----------------------------
            _startHitRun          = null;
            _startHitRunCharIndex = 0;
            switch (startHit.hitObjectKind)
            {
            case HitObjectKind.Run:
            {
                CssRun run = (CssRun)startHit.hitObject;
                //-------------------------------------------------------
                int sel_index;
                int sel_offset;
                run.FindSelectionPoint(textService,
                                       startHit.localX,
                                       out sel_index,
                                       out sel_offset);
                _startHitRunCharIndex = sel_index;
                //modify hitpoint
                _startHitHostLine = (CssLineBox)startChain.GetHitInfo(startChain.Count - 2).hitObject;
                _startLineBeginSelectionAtPixel = (int)(run.Left + sel_offset);
                _startHitRun = run;
            }
            break;

            case HitObjectKind.LineBox:
            {
                _startHitHostLine = (CssLineBox)startHit.hitObject;
                _startLineBeginSelectionAtPixel = startHit.localX;
                //make global
            }
            break;

            case HitObjectKind.CssBox:
            {
                CssBox box = (CssBox)startHit.hitObject;
                //find first nearest line at point
                CssLineBox startHitLine = FindNearestLine(box, startChain.RootGlobalY, 5);
                _startLineBeginSelectionAtPixel = 0;
                if (startHitLine != null)
                {
                    _startHitHostLine = startHitLine;
                }
                else
                {
                    //if not found?
                    _startHitHostLine = null;
                }
            }
            break;

            default:
            {
                throw new NotSupportedException();
            }
            }
        }
Пример #2
0
 public HitInfo(CssRun run, int x, int y)
 {
     this.hitObject     = run;
     this.hitObjectKind = HitObjectKind.Run;
     this.localX        = x;
     this.localY        = y;
 }
Пример #3
0
 public HitInfo(CssRun run, int x, int y)
 {
     this.hitObject = run;
     this.hitObjectKind = HitObjectKind.Run;
     this.localX = x;
     this.localY = y;
 }
Пример #4
0
        static void CalculateMinimumWidthAndWidestRun(CssBox box, out float maxWidth, out CssRun maxWidthRun)
        {
            //use line-base style ***

            float  maxRunWidth = 0;
            CssRun foundRun    = null;

            if (box._clientLineBoxes != null)
            {
                var lineNode = box._clientLineBoxes.First;
                while (lineNode != null)
                {
                    //------------------------
                    CssLineBox line   = lineNode.Value;
                    CssRun     tmpRun = line.FindMaxWidthRun(maxRunWidth);
                    if (tmpRun != null)
                    {
                        maxRunWidth = tmpRun.Width;
                        foundRun    = tmpRun;
                    }
                    //------------------------
                    lineNode = lineNode.Next;
                }
            }

            maxWidth    = maxRunWidth;
            maxWidthRun = foundRun;
        }
Пример #5
0
 public static void Select(this CssLineBox lineBox, int startAtPx, int endAt,
                           CssRun startRun, int startRunIndex,
                           CssRun endRun, int endRunIndex)
 {
     lineBox.SelectionSegment = new SelectionSegment(startAtPx, endAt - startAtPx)
     {
         StartHitRun       = startRun,
         StartHitCharIndex = startRunIndex,
         EndHitRun         = endRun,
         EndHitCharIndex   = endRunIndex
     };
 }
Пример #6
0
        //
        internal float CalculateLineHeight()
        {
            float         maxBottom = 0;
            List <CssRun> myruns    = _runs;
            int           j         = myruns.Count;

            for (int i = 0; i < j; ++i)
            {
                CssRun run = myruns[i];
                //maxRight = run.Right > maxRight ? run.Right : maxRight;
                maxBottom = run.Bottom > maxBottom ? run.Bottom : maxBottom;
            }
            return(maxBottom);
        }
Пример #7
0
        internal IEnumerable <CssRun> GetRunIter(CssBox box)
        {
            List <CssRun> tmpRuns = _runs;
            int           j       = tmpRuns.Count;
            CssRun        run     = null;

            for (int i = 0; i < j; ++i)
            {
                if ((run = tmpRuns[i]).OwnerBox == box)
                {
                    yield return(run);
                }
            }
        }
Пример #8
0
        //---------------------------------
        internal CssRun FindMaxWidthRun(float minimum)
        {
            float  max    = minimum;
            CssRun maxRun = null;

            for (int i = _runs.Count - 1; i >= 0; --i)
            {
                CssRun r = _runs[i];
                if (r.Width > max)
                {
                    max    = r.Width;
                    maxRun = r;
                }
            }
            return(maxRun);
        }
        static void ForEachEventListenerBubbleUp(UIEventArgs e, CssBoxHitChain hitChain, EventListenerAction listenerAction)
        {
            for (int i = hitChain.Count - 1; i >= 0; --i)
            {
                //propagate up
                var            hitInfo    = hitChain.GetHitInfo(i);
                IEventListener controller = null;
                switch (hitInfo.hitObjectKind)
                {
                default:
                {
                    continue;
                }

                case HitObjectKind.Run:
                {
                    CssRun run = (CssRun)hitInfo.hitObject;
                    controller = CssBox.UnsafeGetController(run.OwnerBox) as IEventListener;
                }
                break;

                case HitObjectKind.CssBox:
                {
                    CssBox box = (CssBox)hitInfo.hitObject;
                    controller = CssBox.UnsafeGetController(box) as IEventListener;
                }
                break;
                }

                //---------------------
                if (controller != null)
                {
                    //found controller
                    if (e.SourceHitElement == null)
                    {
                        e.SourceHitElement = controller;
                    }

                    e.CurrentContextElement = controller;
                    e.SetLocation(hitInfo.localX, hitInfo.localY);
                    if (listenerAction())
                    {
                        return;
                    }
                }
            }
        }
Пример #10
0
        public void ApplyBaseline(float baseline)
        {
            //Important notes on http://www.w3.org/TR/CSS21/tables.html#height-layout
            //iterate from rectstrip
            //In a single LineBox ,  CssBox:RectStrip => 1:1 relation


            for (int i = _runs.Count - 1; i >= 0; --i)
            {
                CssRun run = _runs[i];
                //adjust base line
                run.SetLocation(run.Left, baseline);
            }

            //if (_bottomUpBoxStrips == null)
            //{
            //    return;
            //}
            //for (int i = _bottomUpBoxStrips.Length - 1; i >= 0; --i)
            //{
            //    var rstrip = _bottomUpBoxStrips[i];
            //    var rstripOwnerBox = rstrip.owner;
            //    switch (rstripOwnerBox.VerticalAlign)
            //    {
            //        case Css.CssVerticalAlign.Sub:
            //            {
            //                this.SetBaseLine(rstripOwnerBox, baseline + rstrip.Height * .2f);
            //            } break;
            //        case Css.CssVerticalAlign.Super:
            //            {
            //                this.SetBaseLine(rstripOwnerBox, baseline - rstrip.Height * .2f);
            //            } break;
            //        case Css.CssVerticalAlign.TextTop:
            //        case Css.CssVerticalAlign.TextBottom:
            //        case Css.CssVerticalAlign.Top:
            //        case Css.CssVerticalAlign.Bottom:
            //        case Css.CssVerticalAlign.Middle:
            //            break;
            //        default:
            //            //case: baseline
            //            this.SetBaseLine(rstripOwnerBox, baseline);
            //            break;
            //    }
            //}
        }
Пример #11
0
        /// <summary>
        /// Lets the linebox add the word an its box to their lists if necessary.
        /// </summary>
        /// <param name="run"></param>
        internal void AddRun(CssRun run)
        {
#if DEBUG
            if (this.dbugIsClosed)
            {
                throw new NotSupportedException();
            }
#endif
            //if (run is CssTextRun)
            //{
            //    CssTextRun textRun = (CssTextRun)run;
            //    if (textRun.Text.Contains("Cell"))
            //    {

            //    }
            //}
            _runs.Add(run);//each word has only one owner linebox!
            CssRun.SetHostLine(run, this);
        }
Пример #12
0
        //

        internal void ClearSelection()
        {
            if (_selectedLines != null)
            {
                for (int i = _selectedLines.Count - 1; i >= 0; --i)
                {
                    _selectedLines[i].SelectionSegment = null;
                }
                _selectedLines.Clear();
            }
            else
            {
                if (_startHitHostLine != null)
                {
                    _startHitHostLine.SelectionSegment = null;
                }
            }
            _startHitRun          = _endHitRun = null;
            _startHitRunCharIndex = _endHitRunCharIndex = 0;
        }
Пример #13
0
 public void ClearSelection()
 {
     if (this.selectedLines != null)
     {
         for (int i = selectedLines.Count - 1; i >= 0; --i)
         {
             this.selectedLines[i].SelectionSegment = null;
         }
         this.selectedLines.Clear();
     }
     else
     {
         if (this.startHitHostLine != null)
         {
             this.startHitHostLine.SelectionSegment = null;
         }
     }
     this.startHitRun = this.endHitRun = null;
     this.startHitRunCharIndex = this.endHitRunCharIndex = 0;
 }
Пример #14
0
 public void ClearSelection()
 {
     if (this.selectedLines != null)
     {
         for (int i = selectedLines.Count - 1; i >= 0; --i)
         {
             this.selectedLines[i].SelectionSegment = null;
         }
         this.selectedLines.Clear();
     }
     else
     {
         if (this.startHitHostLine != null)
         {
             this.startHitHostLine.SelectionSegment = null;
         }
     }
     this.startHitRun          = this.endHitRun = null;
     this.startHitRunCharIndex = this.endHitRunCharIndex = 0;
 }
Пример #15
0
        static void ForEachOnlyEventPortalBubbleUp(UIEventArgs e, CssBoxHitChain hitPointChain, EventPortalAction eventPortalAction)
        {
            //only listener that need tunnel down
            for (int i = hitPointChain.Count - 1; i >= 0; --i)
            {
                //propagate up
                var          hitInfo    = hitPointChain.GetHitInfo(i);
                IEventPortal controller = null;
                switch (hitInfo.hitObjectKind)
                {
                default:
                {
                    continue;
                }

                case HitObjectKind.Run:
                {
                    CssRun run = (CssRun)hitInfo.hitObject;
                    controller = CssBox.UnsafeGetController(run.OwnerBox) as IEventPortal;
                }
                break;

                case HitObjectKind.CssBox:
                {
                    CssBox box = (CssBox)hitInfo.hitObject;
                    controller = CssBox.UnsafeGetController(box) as IEventPortal;
                }
                break;
                }

                //---------------------
                if (controller != null)
                {
                    e.SetLocation(hitInfo.localX, hitInfo.localY);
                    if (eventPortalAction(controller))
                    {
                        return;
                    }
                }
            }
        }
Пример #16
0
        /// <summary>
        /// Gets the minimum width that the box can be.
        /// *** The box can be as thin as the longest word plus padding
        /// </summary>
        /// <returns></returns>
        internal float CalculateMinimumWidth(int calculationEpisode)
        {
            float maxWidth = 0;
            float padding  = 0f;

            if (this._lastCalculationEpisodeNum == calculationEpisode)
            {
                return(_cachedMinimumWidth);
            }
            //---------------------------------------------------
            if (this.LineBoxCount > 0)
            {
                //use line box technique ***
                CssRun maxWidthRun = null;
                CalculateMinimumWidthAndWidestRun(this, out maxWidth, out maxWidthRun);
                //--------------------------------
                if (maxWidthRun != null)
                {
                    //bubble up***
                    var box = maxWidthRun.OwnerBox;
                    while (box != null)
                    {
                        padding += (box.ActualBorderRightWidth + box.ActualPaddingRight) +
                                   (box.ActualBorderLeftWidth + box.ActualPaddingLeft);

                        if (box == this)
                        {
                            break;
                        }
                        else
                        {
                            //bubble up***
                            box = box.ParentBox;
                        }
                    }
                }
            }
            this._lastCalculationEpisodeNum = calculationEpisode;
            return(_cachedMinimumWidth = maxWidth + padding);
        }
Пример #17
0
        public float CalculateTotalBoxBaseLine(LayoutVisitor lay)
        {
            //not correct !!
            float  maxRunHeight = 0;
            CssRun maxRun       = null;

            for (int i = _runs.Count - 1; i >= 0; --i)
            {
                CssRun run = _runs[i];
                if (run.Height > maxRunHeight)
                {
                    maxRun       = run;
                    maxRunHeight = run.Height;
                }
            }
            if (maxRun != null)
            {
                //lay.GraphicsPlatform.SampleIFonts
                //var f = maxRun.OwnerBox.ResolvedFont;
                //PixelFarm.Drawing.Fonts.ActualFont ff = f.ActualFont;
                //return (float)(f.Height * ff.AscentInPixels / f.Height);

                //return fontHeight* fontAscent / lineSpacing )
            }
            return(0);
            //int j = _runs.Count;
            //for (int i = _runs.Count - 1; i >= 0; --i)
            //{
            //    Font ownerFont = _runs[i].OwnerBox.ActualFont;
            //    HtmlRenderer.Drawing.FontsUtils.GetDescent(
            //}
            //return 0;

            //float baseline = Single.MinValue;
            //for (int i = _bottomUpBoxStrips.Count - 1; i >= 0; --i)
            //{
            //    baseline = Math.Max(baseline, _bottomUpBoxStrips[i].Top);//?top
            //}
            //return baseline;
        }
Пример #18
0
        public float CalculateTotalBoxBaseLine(LayoutVisitor lay)
        {
            //not correct !!
            float  maxRunHeight = 0;
            CssRun maxRun       = null;

            for (int i = this._runs.Count - 1; i >= 0; --i)
            {
                var run = this._runs[i];
                if (run.Height > maxRunHeight)
                {
                    maxRun       = run;
                    maxRunHeight = run.Height;
                }
            }
            if (maxRun != null)
            {
                var fontInfo = maxRun.OwnerBox.ActualFont.FontInfo;
                return(fontInfo.BaseLine);
            }
            return(0);
            //int j = this._runs.Count;
            //for (int i = this._runs.Count - 1; i >= 0; --i)
            //{
            //    Font ownerFont = _runs[i].OwnerBox.ActualFont;
            //    HtmlRenderer.Drawing.FontsUtils.GetDescent(
            //}
            //return 0;

            //float baseline = Single.MinValue;
            //for (int i = _bottomUpBoxStrips.Count - 1; i >= 0; --i)
            //{
            //    baseline = Math.Max(baseline, _bottomUpBoxStrips[i].Top);//?top
            //}
            //return baseline;
        }
Пример #19
0
        internal void CloseLine(LayoutVisitor lay)
        {
#if DEBUG
            this.dbugIsClosed = true;
#endif

            //=============================================================
            //part 1: MakeStrips()
            //=============================================================
            //***
            List <CssRun>          myruns    = _runs;
            CssBox                 lineOwner = _ownerBox;
            List <PartialBoxStrip> tmpStrips = lay.GetReadyStripList();
            //---------------------------------------------------------------------------
            //first level
            Dictionary <CssBox, PartialBoxStrip> unqiueStrips = lay.GetReadyStripDic();
            //location of run and strip related to its containng block
            float maxRight        = 0;
            float maxBottom       = 0;
            int   j               = myruns.Count;
            float firstRunStartAt = 0;
            for (int i = 0; i < j; ++i)
            {
                CssRun run = myruns[i];
                if (i == 0)
                {
                    firstRunStartAt = run.Left;
                }
                maxRight  = run.Right > maxRight ? run.Right : maxRight;
                maxBottom = run.Bottom > maxBottom ? run.Bottom : maxBottom;
                if (run.IsSpaces)
                {
                    //strip size include whitespace ?
                    continue;
                }
                //-------------
                //first level data
                RegisterStripPart(run.OwnerBox, run.Left, run.Top, run.Right, run.Bottom, tmpStrips, unqiueStrips);
            }

            //---------------------------------------------------------------------------
            //other step to upper layer, until no new strip
            int newStripIndex = 0;
            for (int numNewStripCreate = tmpStrips.Count; numNewStripCreate > 0; newStripIndex += numNewStripCreate)
            {
                numNewStripCreate = StepUpRegisterStrips(unqiueStrips, lineOwner, tmpStrips, newStripIndex);
            }

            _bottomUpBoxStrips = tmpStrips.ToArray();
            lay.ReleaseStripList(tmpStrips);
            lay.ReleaseStripDic(unqiueStrips);
            //=============================================================
            //part 2: Calculate
            //=============================================================

            this.CacheLineHeight         = maxBottom;
            this.CachedLineContentWidth  = maxRight;
            this.CachedExactContentWidth = (maxRight - firstRunStartAt);
            if (lineOwner.VisualWidth < CachedLineContentWidth)
            {
                this.CachedLineContentWidth = this.OwnerBox.VisualWidth;
            }
        }
Пример #20
0
        public static void SelectPartialToEnd(this CssLineBox lineBox, int startAtPx, CssRun startRun, int startRunIndex)
        {
            //from startAt to end of line

            //lineBox.SelectionStartAt = startAtPx;
            //lineBox.SelectionWidth = (int)lineBox.CachedLineContentWidth - startAtPx;

            lineBox.SelectionSegment = new SelectionSegment(startAtPx, (int)lineBox.CachedLineContentWidth - startAtPx)
            {
                StartHitRun = startRun,
                StartHitCharIndex = startRunIndex
            };
        }
Пример #21
0
        public static void SelectPartialFromStart(this CssLineBox lineBox, int endAtPx, CssRun endRun, int endRunIndex)
        {
            //from start of line to endAt              

            //lineBox.SelectionStartAt = 0;
            //lineBox.SelectionWidth = endAtPx;

            lineBox.SelectionSegment = new SelectionSegment(0, endAtPx)
            {
                EndHitRun = endRun,
                EndHitCharIndex = endRunIndex
            };
        }
Пример #22
0
        static void CalculateMinimumWidthAndWidestRun(CssBox box, out float maxWidth, out CssRun maxWidthRun)
        {
            //use line-base style ***

            float maxRunWidth = 0;
            CssRun foundRun = null;
            if (box._clientLineBoxes != null)
            {
                var lineNode = box._clientLineBoxes.First;
                while (lineNode != null)
                {
                    //------------------------
                    var line = lineNode.Value;
                    var tmpRun = line.FindMaxWidthRun(maxRunWidth);
                    if (tmpRun != null)
                    {
                        maxRunWidth = tmpRun.Width;
                        foundRun = tmpRun;
                    }
                    //------------------------
                    lineNode = lineNode.Next;
                }
            }

            maxWidth = maxRunWidth;
            maxWidthRun = foundRun;
        }
Пример #23
0
        internal void AddHit(CssRun run, int x, int y)
        {
            //position x,y relate with (0,0) of its run

            _hitInfoList.Add(new HitInfo(run, x, y));
        }
Пример #24
0
        internal void PaintRuns(PaintVisitor p)
        {
            List <CssRun> tmpRuns = _runs;
            int           j       = tmpRuns.Count;

            if (j < 1)
            {
                return;
            }
            //-----------------------


            //iterate from each words
            CssBox      latestOwner = null;
            DrawBoard   innerCanvas = p.InnerDrawBoard;
            RequestFont enterFont   = innerCanvas.CurrentFont;
            Color       enterColor  = innerCanvas.CurrentTextColor;

            for (int i = 0; i < j; ++i)
            {
                //-----------------
#if DEBUG
                dbugCounter.dbugRunPaintCount++;
#endif
                //-----------------

                CssRun w = tmpRuns[i];
                switch (w.Kind)
                {
                case CssRunKind.SolidContent:
                {
                    w.OwnerBox.Paint(p, new RectangleF(w.Left, w.Top, w.Width, w.Height));
                }
                break;

                case CssRunKind.BlockRun:
                {
                    //Console.WriteLine("blockrun");
                    CssBlockRun blockRun = (CssBlockRun)w;
                    int         ox       = p.CanvasOriginX;
                    int         oy       = p.CanvasOriginY;
                    //p.SetCanvasOrigin(ox + (int)(blockRun.Left + blockRun.ContentBox.LocalX), oy + (int)blockRun.Top);
                    p.SetCanvasOrigin(ox + (int)(blockRun.Left), oy + (int)blockRun.Top);
                    blockRun.ContentBox.Paint(p);
                    p.SetCanvasOrigin(ox, oy);
                }
                break;

                case CssRunKind.Text:
                {
                    if (latestOwner != w.OwnerBox)
                    {
                        //change
                        latestOwner = w.OwnerBox;
                        //change font when change owner

                        p.InnerDrawBoard.CurrentFont      = latestOwner.ResolvedFont;
                        p.InnerDrawBoard.CurrentTextColor = latestOwner.ActualColor;
                    }

                    CssTextRun textRun = (CssTextRun)w;
                    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                               textRun.TextStartIndex,
                               textRun.TextLength,
                               new PointF(w.Left, w.Top),
                               new SizeF(w.Width, w.Height));
                }
                break;

                default:
                {
#if DEBUG
                    // w.OwnerBox.dbugPaintTextWordArea(g, offset, w);
#endif
                }
                break;
                }
            }


            innerCanvas.CurrentFont      = enterFont;
            innerCanvas.CurrentTextColor = enterColor;
        }
Пример #25
0
 void SetupStartHitPoint(CssBoxHitChain startChain, IFonts ifonts)
 {
     //find global location of start point
     HitInfo startHit = startChain.GetLastHit();
     //-----------------------------
     this.startHitRun = null;
     this.startHitRunCharIndex = 0;
     switch (startHit.hitObjectKind)
     {
         case HitObjectKind.Run:
             {
                 CssRun run = (CssRun)startHit.hitObject;
                 //-------------------------------------------------------
                 int sel_index;
                 int sel_offset;
                 run.FindSelectionPoint(ifonts,
                      startHit.localX,
                      out sel_index,
                      out sel_offset);
                 this.startHitRunCharIndex = sel_index;
                 //modify hitpoint
                 this.startHitHostLine = (CssLineBox)startChain.GetHitInfo(startChain.Count - 2).hitObject;
                 this.startLineBeginSelectionAtPixel = (int)(run.Left + sel_offset);
                 this.startHitRun = run;
             }
             break;
         case HitObjectKind.LineBox:
             {
                 this.startHitHostLine = (CssLineBox)startHit.hitObject;
                 this.startLineBeginSelectionAtPixel = startHit.localX;
                 //make global            
             }
             break;
         case HitObjectKind.CssBox:
             {
                 CssBox box = (CssBox)startHit.hitObject;
                 //find first nearest line at point   
                 CssLineBox startHitLine = FindNearestLine(box, startChain.RootGlobalY, 5);
                 this.startLineBeginSelectionAtPixel = 0;
                 if (startHitLine != null)
                 {
                     this.startHitHostLine = startHitLine;
                 }
                 else
                 {
                     //if not found?
                     this.startHitHostLine = null;
                 }
             }
             break;
         default:
             {
                 throw new NotSupportedException();
             }
     }
 }
Пример #26
0
        public static void SelectPartialFromStart(this CssLineBox lineBox, int endAtPx, CssRun endRun, int endRunIndex)
        {
            //from start of line to endAt

            lineBox.SelectionSegment = new SelectionSegment(0, endAtPx)
            {
                EndHitRun       = endRun,
                EndHitCharIndex = endRunIndex
            };
        }
Пример #27
0
        public static void SelectPartialToEnd(this CssLineBox lineBox, int startAtPx, CssRun startRun, int startRunIndex)
        {
            //from startAt to end of line

            lineBox.SelectionSegment = new SelectionSegment(startAtPx, (int)lineBox.CachedLineContentWidth - startAtPx)
            {
                StartHitRun       = startRun,
                StartHitCharIndex = startRunIndex
            };
        }
Пример #28
0
 internal static void SetHostLine(CssRun run, CssLineBox hostline)
 {
     run._hostline = hostline;
 }
Пример #29
0
        internal void AddHit(CssRun run, int x, int y)
        {
            //position x,y relate with (0,0) of its run

            hitInfoList.Add(new HitInfo(run, x, y));
        }
Пример #30
0
        /// <summary>
        /// Assigns words its width and height
        /// </summary>
        /// <param name="g"></param>
        public virtual void MeasureRunsSize(LayoutVisitor lay)
        {
            //measure once !
            if ((_boxCompactFlags & BoxFlags.LAY_RUNSIZE_MEASURE) != 0)
            {
                return;
            }
            //--------------------------------
            if (this.BackgroundImageBinder != null)
            {
                //this has background
                if (this.BackgroundImageBinder.State == BinderState.Unload)
                {
                    lay.RequestImage(this.BackgroundImageBinder, this);
                }
            }
            //--------------------------------
            if (this.RunCount > 0)
            {
                //find word spacing
                float       actualWordspacing = _actualWordSpacing;
                RequestFont actualFont        = this.ResolvedFont;


                float fontHeight = (actualFont.AscentInPixels - actualFont.DescentInPixels + actualFont.LineGapInPixels);
                fontHeight += 4; //TODO: why +4 ????***

                List <CssRun> tmpRuns = this.Runs;
                for (int i = tmpRuns.Count - 1; i >= 0; --i)
                {
                    CssRun run = tmpRuns[i];
                    run.Height = fontHeight;
                    //if this is newline then width =0 ***
                    switch (run.Kind)
                    {
                    case CssRunKind.Text:
                    {
                        CssTextRun textRun = (CssTextRun)run;
                        Size       ss      = lay.MeasureStringSize(CssBox.UnsafeGetTextBuffer(this),
                                                                   textRun.TextStartIndex,
                                                                   textRun.TextLength,
                                                                   actualFont);
                        run.SetSize(ss.Width, ss.Height);
                    }
                    break;

                    case CssRunKind.SingleSpace:
                    {
                        run.Width = actualWordspacing;
                    }
                    break;

                    case CssRunKind.Space:
                    {
                        //other space size
                        run.Width = actualWordspacing * ((CssTextRun)run).TextLength;
                    }
                    break;

                    case CssRunKind.LineBreak:
                    {
                        run.Width = 0;
                    }
                    break;
                    }
                }
            }
            _boxCompactFlags |= BoxFlags.LAY_RUNSIZE_MEASURE;
        }
Пример #31
0
        internal void PaintRuns(PaintVisitor p)
        {
            List <CssRun> tmpRuns = _runs;
            int           j       = tmpRuns.Count;

            if (j < 1)
            {
                return;
            }
            //-----------------------


            //iterate from each words
            CssBox      latestOwner = null;
            DrawBoard   innerCanvas = p.InnerDrawBoard;
            RequestFont enterFont   = innerCanvas.CurrentFont;
            Color       enterColor  = innerCanvas.CurrentTextColor;

            for (int i = 0; i < j; ++i)
            {
                //-----------------
#if DEBUG
                dbugCounter.dbugRunPaintCount++;
#endif
                //-----------------

                CssRun w = tmpRuns[i];
                switch (w.Kind)
                {
                case CssRunKind.SolidContent:
                {
#if DEBUG
                    //System.Diagnostics.Debug.WriteLine("ox,oy=" + p.CanvasOriginX + "," + p.CanvasOriginY);
                    //System.Diagnostics.Debug.WriteLine("clip=" + p.CurrentClipRect);
#endif

                    Rectangle currentClipRect = p.CurrentClipRect;
                    Rectangle wRect           = new Rectangle((int)w.Left, (int)w.Top, (int)w.Width, (int)w.Height);
                    wRect.Intersect(currentClipRect);
#if DEBUG
                    //System.Diagnostics.Debug.WriteLine("empty_clip=" + (wRect.Height == 0 || wRect.Width == 0));
#endif

                    if (wRect.Height != 0 && wRect.Width != 0)
                    {
                        w.OwnerBox.Paint(p, new RectangleF(w.Left, w.Top, w.Width, w.Height));
                    }
                }
                break;

                case CssRunKind.BlockRun:
                {
                    //Console.WriteLine("blockrun");
                    CssBlockRun blockRun = (CssBlockRun)w;
                    int         ox       = p.CanvasOriginX;
                    int         oy       = p.CanvasOriginY;
                    //p.SetCanvasOrigin(ox + (int)(blockRun.Left + blockRun.ContentBox.LocalX), oy + (int)blockRun.Top);
                    p.SetCanvasOrigin(ox + (int)(blockRun.Left), oy + (int)blockRun.Top);
                    blockRun.ContentBox.Paint(p);
                    p.SetCanvasOrigin(ox, oy);
                }
                break;

                case CssRunKind.Text:
                {
                    if (latestOwner != w.OwnerBox)
                    {
                        //change
                        latestOwner = w.OwnerBox;
                        //change font when change owner

                        p.InnerDrawBoard.CurrentFont      = latestOwner.ResolvedFont;
                        p.InnerDrawBoard.CurrentTextColor = latestOwner.ActualColor;
                    }

                    CssTextRun textRun = (CssTextRun)w;
                    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                               textRun.TextStartIndex,
                               textRun.TextLength,
                               new PointF(w.Left, w.Top),
                               new SizeF(w.Width, w.Height));


                    //RenderVxFormattedString formattedStr = CssTextRun.GetCachedFormatString(textRun);
                    //if (formattedStr == null)
                    //{
                    //    formattedStr = p.CreateRenderVx(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                    //                                textRun.TextStartIndex,
                    //                                textRun.TextLength);

                    //    CssTextRun.SetCachedFormattedString(textRun, formattedStr);
                    //}
                    //if (formattedStr != null)
                    //{
                    //    p.DrawText(formattedStr,
                    //                               new PointF(w.Left, w.Top),
                    //                               new SizeF(w.Width, w.Height));
                    //}
                    //else
                    //{
                    //    p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox),
                    //                               textRun.TextStartIndex,
                    //                               textRun.TextLength,
                    //                               new PointF(w.Left, w.Top),
                    //                               new SizeF(w.Width, w.Height));
                    //}
                }
                break;

                default:
                {
#if DEBUG
                    // w.OwnerBox.dbugPaintTextWordArea(g, offset, w);
#endif
                }
                break;
                }
            }


            innerCanvas.CurrentFont      = enterFont;
            innerCanvas.CurrentTextColor = enterColor;
        }
Пример #32
0
        public void CopyText(StringBuilder stbuilder)
        {
            //copy selected text to stbuilder
            //this version just copy a plain text
            int j = selectedLines.Count;

            for (int i = 0; i < j; ++i)
            {
                var selLine = selectedLines[i];
                var selSeg  = selLine.SelectionSegment;
                switch (selSeg.Kind)
                {
                case SelectionSegmentKind.Partial:
                {
                    var  startRun     = selSeg.StartHitRun;
                    var  endHitRun    = selSeg.EndHitRun;
                    bool autoFirstRun = false;
                    bool autoLastRun  = false;
                    if (startRun == null)
                    {
                        startRun     = selLine.GetFirstRun();
                        autoFirstRun = true;
                    }
                    if (endHitRun == null)
                    {
                        endHitRun   = selLine.GetLastRun();
                        autoLastRun = true;
                    }

                    if (startRun == endHitRun)
                    {
                        var rr = startRun as CssTextRun;
                        if (rr != null && this.startHitRunCharIndex >= 0)
                        {
                            var alltext = rr.Text;
                            var sub1    = alltext.Substring(this.startHitRunCharIndex, this.endHitRunCharIndex - this.startHitRunCharIndex);
                            stbuilder.Append(sub1);
                        }
                    }
                    else
                    {
                        int runCount = selLine.RunCount;
                        for (int n = 0; n < runCount; ++n)
                        {
                            //temp fix here!
                            //TODO: review this for other cssrun type
                            var rr = selLine.GetRun(n) as CssTextRun;
                            if (rr == null)
                            {
                                continue;
                            }
                            if (rr == startRun)
                            {
                                var alltext = rr.Text;
                                if (autoFirstRun)
                                {
                                    stbuilder.Append(alltext);
                                }
                                else
                                {
                                    if (this.startHitRunCharIndex >= 0)
                                    {
                                        var sub1 = alltext.Substring(this.startHitRunCharIndex);
                                        stbuilder.Append(sub1);
                                    }
                                }
                            }
                            else if (rr == endHitRun)
                            {
                                var alltext = rr.Text;
                                if (autoLastRun)
                                {
                                    stbuilder.Append(alltext);
                                }
                                else
                                {
                                    if (this.endHitRunCharIndex >= 0)
                                    {
                                        var sub1 = alltext.Substring(0, this.endHitRunCharIndex);
                                        stbuilder.Append(sub1);
                                    }
                                }
                                //stop
                                break;
                            }
                            else
                            {
                                stbuilder.Append(rr.Text);
                            }
                        }
                    }
                }
                break;

                default:
                {
                    int runCount = selLine.RunCount;
                    for (int n = 0; n < runCount; ++n)
                    {
                        var r = selLine.GetRun(n) as CssTextRun;
                        if (r != null)
                        {
                            stbuilder.Append(r.Text);
                        }
                    }
                }
                break;
                }

                if (i < j - 1)
                {
                    //if not lastline
                    stbuilder.AppendLine();
                }
            }
        }
Пример #33
0
        void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, IFonts ifonts)
        {
            //find global location of end point 
            HitInfo endHit = endChain.GetLastHit();
            int xposOnEndLine = 0;
            CssLineBox endline = null;
            int run_sel_offset = 0;
            //find endline first
            this.endHitRunCharIndex = 0;
            this.endHitRun = null;
            switch (endHit.hitObjectKind)
            {
                default:
                    {
                        throw new NotSupportedException();
                    }
                case HitObjectKind.Run:
                    {
                        CssRun endRun = (CssRun)endHit.hitObject;
                        //if (endRun.Text != null && endRun.Text.Contains("Jose"))
                        //{
                        //}

                        int run_sel_index;
                        endRun.FindSelectionPoint(ifonts,
                             endHit.localX,
                             out run_sel_index,
                             out run_sel_offset);
                        endline = endRun.HostLine;
                        xposOnEndLine = (int)(endRun.Left + run_sel_offset);
                        this.endHitRunCharIndex = run_sel_index;
                        this.endHitRun = endRun;
                    }
                    break;
                case HitObjectKind.LineBox:
                    {
                        endline = (CssLineBox)endHit.hitObject;
                        xposOnEndLine = endHit.localX;
                    }
                    break;
                case HitObjectKind.CssBox:
                    {
                        CssBox hitBox = (CssBox)endHit.hitObject;
                        endline = FindNearestLine(hitBox, endChain.RootGlobalY, 5);
                        xposOnEndLine = endHit.localX;
                    }
                    break;
            }

#if DEBUG
            if (xposOnEndLine == 0)
            {
            }
#endif

            //----------------------------------
            this.selectedLines = new List<CssLineBox>();
            if (startHitHostLine == endline)
            {
                this.selectedLines.Add(endline);
                startHitHostLine.Select(startLineBeginSelectionAtPixel, xposOnEndLine,
                        this.startHitRun, this.startHitRunCharIndex,
                        this.endHitRun, this.endHitRunCharIndex);
                return; //early exit here ***
            }
            //---------------------------------- 
            //select on different line 
            LineWalkVisitor lineWalkVisitor = null;
            int breakAtLevel;
            if (FindCommonGround(startChain, endChain, out breakAtLevel) && breakAtLevel > 0)
            {
                var hit1 = endChain.GetHitInfo(breakAtLevel).hitObject;
                var hitBlockRun = hit1 as CssBlockRun;
                //multiple select 
                //1. first part        
                if (hitBlockRun != null)
                {
                    startHitHostLine.Select(startLineBeginSelectionAtPixel, (int)hitBlockRun.Left,
                     this.startHitRun, this.startHitRunCharIndex,
                     this.endHitRun, this.endHitRunCharIndex);
                    selectedLines.Add(this.startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(hitBlockRun);
                }
                else
                {
                    startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
                    selectedLines.Add(this.startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
                }
            }
            else
            {
                startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
                selectedLines.Add(this.startHitHostLine);
                lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
            }

            lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY);
            lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) =>
            {
                switch (lineCoverage)
                {
                    case LineCoverage.EndLine:
                        {
                            //found end line  
                            linebox.SelectPartialFromStart(xposOnEndLine, this.endHitRun, this.endHitRunCharIndex);
                            selectedLines.Add(linebox);
                        }
                        break;
                    case LineCoverage.PartialLine:
                        {
                            linebox.SelectPartialFromStart((int)partialLineRun.Right, this.endHitRun, this.endHitRunCharIndex);
                            selectedLines.Add(linebox);
                        }
                        break;
                    case LineCoverage.FullLine:
                        {
                            //check if hitpoint is in the line area
                            linebox.SelectFull();
                            selectedLines.Add(linebox);
                        }
                        break;
                }
            });
        }
Пример #34
0
        public void CopyText(StringBuilder stbuilder)
        {
            //copy selected text to stbuilder 
            //this version just copy a plain text
            int j = selectedLines.Count;
            for (int i = 0; i < j; ++i)
            {
                var selLine = selectedLines[i];
                var selSeg = selLine.SelectionSegment;
                switch (selSeg.Kind)
                {
                    case SelectionSegmentKind.Partial:
                        {
                            var startRun = selSeg.StartHitRun;
                            var endHitRun = selSeg.EndHitRun;
                            bool autoFirstRun = false;
                            bool autoLastRun = false;
                            if (startRun == null)
                            {
                                startRun = selLine.GetFirstRun();
                                autoFirstRun = true;
                            }
                            if (endHitRun == null)
                            {
                                endHitRun = selLine.GetLastRun();
                                autoLastRun = true;
                            }

                            if (startRun == endHitRun)
                            {
                                var rr = startRun as CssTextRun;
                                if (this.startHitRunCharIndex >= 0)
                                {
                                    var alltext = rr.Text;
                                    var sub1 = alltext.Substring(this.startHitRunCharIndex, this.endHitRunCharIndex - this.startHitRunCharIndex);
                                    stbuilder.Append(sub1);
                                }
                            }
                            else
                            {
                                int runCount = selLine.RunCount;
                                for (int n = 0; n < runCount; ++n)
                                {
                                    //temp fix here!
                                    //TODO: review this for other cssrun type
                                    var rr = selLine.GetRun(n) as CssTextRun;
                                    if (rr == null)
                                    {
                                        continue;
                                    }
                                    if (rr == startRun)
                                    {
                                        var alltext = rr.Text;
                                        if (autoFirstRun)
                                        {
                                            stbuilder.Append(alltext);
                                        }
                                        else
                                        {
                                            if (this.startHitRunCharIndex >= 0)
                                            {
                                                var sub1 = alltext.Substring(this.startHitRunCharIndex);
                                                stbuilder.Append(sub1);
                                            }
                                        }
                                    }
                                    else if (rr == endHitRun)
                                    {
                                        var alltext = rr.Text;
                                        if (autoLastRun)
                                        {
                                            stbuilder.Append(alltext);
                                        }
                                        else
                                        {
                                            if (this.endHitRunCharIndex >= 0)
                                            {
                                                var sub1 = alltext.Substring(0, this.endHitRunCharIndex);
                                                stbuilder.Append(sub1);
                                            }
                                        }
                                        //stop
                                        break;
                                    }
                                    else
                                    {
                                        stbuilder.Append(rr.Text);
                                    }
                                }
                            }
                        }
                        break;
                    default:
                        {
                            int runCount = selLine.RunCount;
                            for (int n = 0; n < runCount; ++n)
                            {
                                var r = selLine.GetRun(n) as CssTextRun;
                                if (r != null)
                                {
                                    stbuilder.Append(r.Text);
                                }
                            }
                        }
                        break;
                }

                if (i < j - 1)
                {
                    //if not lastline
                    stbuilder.AppendLine();
                }
            }
        }
Пример #35
0
        /// <summary>
        /// Lets the linebox add the word an its box to their lists if necessary.
        /// </summary>
        /// <param name="run"></param>
        internal void AddRun(CssRun run)
        {
#if DEBUG
            if (this.dbugIsClosed)
            {
                throw new NotSupportedException();
            }
#endif
            //if (run is CssTextRun)
            //{ 
            //    CssTextRun textRun = (CssTextRun)run;
            //    if (textRun.Text.Contains("Cell"))
            //    {

            //    }
            //}
            this._runs.Add(run);//each word has only one owner linebox! 
            CssRun.SetHostLine(run, this);
        }
Пример #36
0
        internal void CopyText(StringBuilder stbuilder)
        {
            //copy selected text to stbuilder
            //this version just copy a plain text
            int j = _selectedLines.Count;

            for (int i = 0; i < j; ++i)
            {
                CssLineBox       selLine = _selectedLines[i];
                SelectionSegment selSeg  = selLine.SelectionSegment;
                switch (selSeg.Kind)
                {
                case SelectionSegmentKind.Partial:
                {
                    CssRun startRun     = selSeg.StartHitRun;
                    CssRun endHitRun    = selSeg.EndHitRun;
                    bool   autoFirstRun = false;
                    bool   autoLastRun  = false;
                    if (startRun == null)
                    {
                        startRun     = selLine.GetFirstRun();
                        autoFirstRun = true;
                    }
                    if (endHitRun == null)
                    {
                        endHitRun   = selLine.GetLastRun();
                        autoLastRun = true;
                    }

                    if (startRun == endHitRun)
                    {
                        if (startRun != null && _startHitRunCharIndex >= 0)
                        {
                            startRun.WriteContent(stbuilder, _startHitRunCharIndex, _endHitRunCharIndex - _startHitRunCharIndex);

                            //string alltext = rr.Text;
                            //string sub1 = alltext.Substring(_startHitRunCharIndex, _endHitRunCharIndex - _startHitRunCharIndex);
                            //stbuilder.Append(sub1);
                        }
                    }
                    else
                    {
                        int  runCount      = selLine.RunCount;
                        bool foundStartRun = false;
                        for (int n = 0; n < runCount; ++n)
                        {
                            //temp fix here!
                            //TODO: review this for other cssrun type

                            CssRun run = selLine.GetRun(n);

                            if (run == startRun)
                            {
                                foundStartRun = true;
                                if (autoFirstRun)
                                {
                                    run.WriteContent(stbuilder);
                                }
                                else
                                {
                                    if (_startHitRunCharIndex >= 0)
                                    {
                                        run.WriteContent(stbuilder, _startHitRunCharIndex);
                                    }
                                }
                            }
                            else if (run == endHitRun)
                            {
                                if (autoLastRun)
                                {
                                    run.WriteContent(stbuilder);
                                    //stbuilder.Append(alltext);
                                }
                                else
                                {
                                    if (_endHitRunCharIndex >= 0)
                                    {
                                        run.WriteContent(stbuilder, 0, _endHitRunCharIndex);
                                        //string sub1 = alltext.Substring(0, _endHitRunCharIndex);
                                        //stbuilder.Append(sub1);
                                    }
                                }
                                //stop
                                break;
                            }
                            else
                            {
                                if (foundStartRun)
                                {
                                    run.WriteContent(stbuilder);
                                    //stbuilder.Append(rr.Text);
                                }
                            }
                        }
                    }
                }
                break;

                default:
                {
                    int runCount = selLine.RunCount;
                    for (int n = 0; n < runCount; ++n)
                    {
                        CssRun run = selLine.GetRun(n);
                        run.WriteContent(stbuilder);
                        //CssTextRun r = run as CssTextRun;
                        //if (r != null)
                        //{
                        //    stbuilder.Append(r.Text);
                        //}
                        //else
                        //{

                        //}
                    }
                }
                break;
                }

                if (i < j - 1)
                {
                    //if not lastline
                    stbuilder.AppendLine();
                }
            }
        }
Пример #37
0
 internal static void SetHostLine(CssRun run, CssLineBox hostline)
 {
     run._hostline = hostline;
 }
Пример #38
0
 public static void Select(this CssLineBox lineBox, int startAtPx, int endAt,
     CssRun startRun, int startRunIndex,
     CssRun endRun, int endRunIndex)
 {
     lineBox.SelectionSegment = new SelectionSegment(startAtPx, endAt - startAtPx)
     {
         StartHitRun = startRun,
         StartHitCharIndex = startRunIndex,
         EndHitRun = endRun,
         EndHitCharIndex = endRunIndex
     };
 }
Пример #39
0
        /// <summary>
        /// Assigns words its width and height
        /// </summary>
        /// <param name="g"></param>
        public virtual void MeasureRunsSize(LayoutVisitor lay)
        {
            //measure once !
            if ((this._boxCompactFlags & BoxFlags.LAY_RUNSIZE_MEASURE) != 0)
            {
                return;
            }

            //--------------------------------
            if (this.BackgroundImageBinder != null)
            {
                //this has background
                if (this.BackgroundImageBinder.State == ImageBinderState.Unload)
                {
                    lay.RequestImage(this.BackgroundImageBinder, this);
                }
            }

            //--------------------------------
            if (this.RunCount > 0)
            {
                //find word spacing
                float actualWordspacing = this._actualWordSpacing;
                Font  actualFont        = this.ActualFont;
                var   fontInfo          = actualFont.FontInfo;
                float fontHeight        = fontInfo.LineHeight;

                var tmpRuns = this.Runs;
                for (int i = tmpRuns.Count - 1; i >= 0; --i)
                {
                    CssRun run = tmpRuns[i];
                    run.Height = fontHeight;
                    //if this is newline then width =0 ***
                    switch (run.Kind)
                    {
                    case CssRunKind.Text:
                    {
                        CssTextRun textRun = (CssTextRun)run;
                        run.Width = lay.MeasureStringWidth(
                            CssBox.UnsafeGetTextBuffer(this),
                            textRun.TextStartIndex,
                            textRun.TextLength,
                            actualFont);
                    }
                    break;

                    case CssRunKind.SingleSpace:
                    {
                        run.Width = actualWordspacing;
                    }
                    break;

                    case CssRunKind.Space:
                    {
                        //other space size
                        run.Width = actualWordspacing * ((CssTextRun)run).TextLength;
                    }
                    break;

                    case CssRunKind.LineBreak:
                    {
                        run.Width = 0;
                    }
                    break;
                    }
                }
            }
            this._boxCompactFlags |= BoxFlags.LAY_RUNSIZE_MEASURE;
        }
Пример #40
0
        void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, ITextService ifonts)
        {
            //find global location of end point
            HitInfo    endHit         = endChain.GetLastHit();
            int        xposOnEndLine  = 0;
            CssLineBox endline        = null;
            int        run_sel_offset = 0;

            //find endline first
            this.endHitRunCharIndex = 0;
            this.endHitRun          = null;
            switch (endHit.hitObjectKind)
            {
            default:
            {
                throw new NotSupportedException();
            }

            case HitObjectKind.Run:
            {
                CssRun endRun = (CssRun)endHit.hitObject;
                //if (endRun.Text != null && endRun.Text.Contains("Jose"))
                //{
                //}

                int run_sel_index;
                endRun.FindSelectionPoint(ifonts,
                                          endHit.localX,
                                          out run_sel_index,
                                          out run_sel_offset);
                endline                 = endRun.HostLine;
                xposOnEndLine           = (int)(endRun.Left + run_sel_offset);
                this.endHitRunCharIndex = run_sel_index;
                this.endHitRun          = endRun;
            }
            break;

            case HitObjectKind.LineBox:
            {
                endline       = (CssLineBox)endHit.hitObject;
                xposOnEndLine = endHit.localX;
            }
            break;

            case HitObjectKind.CssBox:
            {
                CssBox hitBox = (CssBox)endHit.hitObject;
                endline       = FindNearestLine(hitBox, endChain.RootGlobalY, 5);
                xposOnEndLine = endHit.localX;
            }
            break;
            }

#if DEBUG
            if (xposOnEndLine == 0)
            {
            }
#endif

            //----------------------------------
            this.selectedLines = new List <CssLineBox>();
            if (startHitHostLine == endline)
            {
                this.selectedLines.Add(endline);
                startHitHostLine.Select(startLineBeginSelectionAtPixel, xposOnEndLine,
                                        this.startHitRun, this.startHitRunCharIndex,
                                        this.endHitRun, this.endHitRunCharIndex);
                return; //early exit here ***
            }
            //----------------------------------
            //select on different line
            LineWalkVisitor lineWalkVisitor = null;
            int             breakAtLevel;
            if (FindCommonGround(startChain, endChain, out breakAtLevel) && breakAtLevel > 0)
            {
                var hit1        = endChain.GetHitInfo(breakAtLevel).hitObject;
                var hitBlockRun = hit1 as CssBlockRun;
                //multiple select
                //1. first part
                if (hitBlockRun != null)
                {
                    startHitHostLine.Select(startLineBeginSelectionAtPixel, (int)hitBlockRun.Left,
                                            this.startHitRun, this.startHitRunCharIndex,
                                            this.endHitRun, this.endHitRunCharIndex);
                    selectedLines.Add(this.startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(hitBlockRun);
                }
                else
                {
                    startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
                    selectedLines.Add(this.startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
                }
            }
            else
            {
                startHitHostLine.SelectPartialToEnd(startLineBeginSelectionAtPixel, this.startHitRun, this.startHitRunCharIndex);
                selectedLines.Add(this.startHitHostLine);
                lineWalkVisitor = new LineWalkVisitor(startHitHostLine);
            }

            lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY);
            lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) =>
            {
                switch (lineCoverage)
                {
                case LineCoverage.EndLine:
                    {
                        //found end line
                        linebox.SelectPartialFromStart(xposOnEndLine, this.endHitRun, this.endHitRunCharIndex);
                        selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.PartialLine:
                    {
                        linebox.SelectPartialFromStart((int)partialLineRun.Right, this.endHitRun, this.endHitRunCharIndex);
                        selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.FullLine:
                    {
                        //check if hitpoint is in the line area
                        linebox.SelectFull();
                        selectedLines.Add(linebox);
                    }
                    break;
                }
            });
        }
Пример #41
0
        void SetupEndHitPoint(CssBoxHitChain startChain, CssBoxHitChain endChain, ITextService textService)
        {
            //find global location of end point
            HitInfo    endHit        = endChain.GetLastHit();
            int        xposOnEndLine = 0;
            CssLineBox endline       = null;

            //find endline first
            _endHitRunCharIndex = 0;
            _endHitRun          = null;
            switch (endHit.hitObjectKind)
            {
            default:
            {
                throw new NotSupportedException();
            }

            case HitObjectKind.Run:
            {
                CssRun endRun = (CssRun)endHit.hitObject;
#if DEBUG
                //if (endRun.Text != null && endRun.Text.Contains("Jose"))
                //{
                //}
                if (endHit.localX > 23)
                {
                }
                System.Diagnostics.Debug.WriteLine(endHit.localX);
#endif
                endRun.FindSelectionPoint(textService,
                                          endHit.localX,
                                          out int run_sel_index,
                                          out int run_sel_offset);
                endline             = endRun.HostLine;
                xposOnEndLine       = (int)(endRun.Left + run_sel_offset);
                _endHitRunCharIndex = run_sel_index;

#if DEBUG
                System.Diagnostics.Debug.WriteLine(_endHitRunCharIndex);
#endif
                _endHitRun = endRun;
            }
            break;

            case HitObjectKind.LineBox:
            {
                endline       = (CssLineBox)endHit.hitObject;
                xposOnEndLine = endHit.localX;
            }
            break;

            case HitObjectKind.CssBox:
            {
                CssBox hitBox = (CssBox)endHit.hitObject;
                endline       = FindNearestLine(hitBox, endChain.RootGlobalY, 5);
                xposOnEndLine = endHit.localX;
            }
            break;
            }

#if DEBUG
            if (xposOnEndLine == 0)
            {
            }
#endif

            //----------------------------------
            _selectedLines = new List <CssLineBox>();
            if (_startHitHostLine == endline)
            {
                _selectedLines.Add(endline);
                _startHitHostLine.Select(_startLineBeginSelectionAtPixel, xposOnEndLine,
                                         _startHitRun, _startHitRunCharIndex,
                                         _endHitRun, _endHitRunCharIndex);
                return; //early exit here ***
            }
            //----------------------------------
            //select on different line
            LineWalkVisitor lineWalkVisitor = null;

            if (FindCommonGround(startChain, endChain, out int breakAtLevel) && breakAtLevel > 0)
            {
                CssBlockRun hitBlockRun = endChain.GetHitInfo(breakAtLevel).hitObject as CssBlockRun;
                //multiple select
                //1. first part
                if (hitBlockRun != null)
                {
                    _startHitHostLine.Select(_startLineBeginSelectionAtPixel, (int)hitBlockRun.Left,
                                             _startHitRun, _startHitRunCharIndex,
                                             _endHitRun, _endHitRunCharIndex);
                    _selectedLines.Add(_startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(hitBlockRun);
                }
                else
                {
                    _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex);
                    _selectedLines.Add(_startHitHostLine);
                    lineWalkVisitor = new LineWalkVisitor(_startHitHostLine);
                }
            }
            else
            {
                _startHitHostLine.SelectPartialToEnd(_startLineBeginSelectionAtPixel, _startHitRun, _startHitRunCharIndex);
                _selectedLines.Add(_startHitHostLine);
                lineWalkVisitor = new LineWalkVisitor(_startHitHostLine);
            }

            lineWalkVisitor.SetWalkTargetPosition(endChain.RootGlobalX, endChain.RootGlobalY);

#if DEBUG
            int dbugExpectedId = 1;
#endif
            lineWalkVisitor.Walk(endline, (lineCoverage, linebox, partialLineRun) =>
            {
#if DEBUG
                //System.Diagnostics.Debug.WriteLine("sel:" + linebox.dbugId);
                if (dbugExpectedId != linebox.dbugId)
                {
                }
                dbugExpectedId++;
#endif
                switch (lineCoverage)
                {
                case LineCoverage.EndLine:
                    {
                        //found end line
                        linebox.SelectPartialFromStart(xposOnEndLine, _endHitRun, _endHitRunCharIndex);
                        _selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.PartialLine:
                    {
                        linebox.SelectPartialFromStart((int)partialLineRun.Right, _endHitRun, _endHitRunCharIndex);
                        _selectedLines.Add(linebox);
                    }
                    break;

                case LineCoverage.FullLine:
                    {
                        //check if hitpoint is in the line area
                        linebox.SelectFull();
                        _selectedLines.Add(linebox);
                    }
                    break;
                }
            });
        }
Пример #42
0
        public static bool HitTest(CssBox box, float x, float y, CssBoxHitChain hitChain)
        {
#if DEBUG
            //if (box.ViewportY != 0 && hitChain.debugEventPhase == CssBoxHitChain.dbugEventPhase.MouseDown)
            //{
            //}
#endif
            //--------------------------------------
            bool  isPointInArea = box.IsPointInArea(x, y);
            float boxHitLocalX  = x - box.LocalX; //**
            float boxHitLocalY  = y - box.LocalY; //**
            //----------------------------------------------------------------------
            if (isPointInArea)
            {
                hitChain.AddHit(box, (int)boxHitLocalX, (int)boxHitLocalY);
            }

            //----------------------------------------------------------------------
            //enter children space -> offset with its viewport
            boxHitLocalX += box.ViewportX;
            boxHitLocalY += box.ViewportY;


            //check absolute layer first ***
            if (box.HasAbsoluteLayer)
            {
                hitChain.PushContextBox(box);
                foreach (CssBox absBox in box.GetAbsoluteChildBoxBackwardIter())
                {
                    if (HitTest(absBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //found hit
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
                hitChain.PopContextBox(box);
            }
            //----------------------------------------------------------------------
            if (!isPointInArea)
            {
                switch (box.CssDisplay)
                {
                case Css.CssDisplay.TableRow:
                {
                    foreach (CssBox childBox in box.GetChildBoxIter())
                    {
                        if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                        {
                            return(true);
                        }
                    }
                }
                break;
                }
                //exit
                return(false);
            }
            //----------------------------------------------------------------------
            //at here point is in the area***
            hitChain.PushContextBox(box);
            if (box.IsCustomCssBox)
            {
                //custom css box
                //return true= stop here
                if (box.CustomContentHitTest(boxHitLocalX, boxHitLocalY, hitChain))
                {
                    hitChain.PopContextBox(box);
                    return(true);
                }
            }

            if (box.LineBoxCount > 0)
            {
                bool foundSomeLine = false;
                foreach (CssLineBox lineBox in box.GetLineBoxIter())
                {
                    //line box not overlap
                    if (lineBox.HitTest(boxHitLocalX, boxHitLocalY))
                    {
                        foundSomeLine = true;
                        float lineBoxLocalY = boxHitLocalY - lineBox.CachedLineTop;
                        //2.
                        hitChain.AddHit(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);


                        CssRun foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)boxHitLocalX, (int)lineBoxLocalY);
                        //CssRun foundRun = BoxHitUtils.GetCssRunOnLocation(lineBox, (int)x, (int)y);
                        if (foundRun != null)
                        {
                            //3.
                            hitChain.AddHit(foundRun, (int)(boxHitLocalX - foundRun.Left), (int)lineBoxLocalY);
                            //4. go deeper for block run
                            if (foundRun.Kind == CssRunKind.BlockRun)
                            {
                                CssBlockRun blockRun = (CssBlockRun)foundRun;
                                CssLineBox  hostLine = blockRun.HostLine;
                                //adjust with hostline
                                HitTest(blockRun.ContentBox,
                                        (int)(boxHitLocalX + blockRun.ContentBox.LocalX - foundRun.Left),
                                        (int)(boxHitLocalY - hostLine.CachedLineTop),
                                        hitChain);
                            }
                        }
                        //found line box
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                    else if (foundSomeLine)
                    {
                        return(false);
                    }
                }
            }
            else
            {
                //iterate in child
                //foreach (var childBox in box.GetChildBoxIter())
                foreach (CssBox childBox in box.GetChildBoxBackwardIter())
                {
                    if (HitTest(childBox, boxHitLocalX, boxHitLocalY, hitChain))
                    {
                        //recursive
                        hitChain.PopContextBox(box);
                        return(true);
                    }
                }
            }
            hitChain.PopContextBox(box);
            return(true);
        }