Ejemplo n.º 1
0
        protected virtual void PaintImp(PaintVisitor p)
        {
#if DEBUG
            //if (__aa_dbugId == 6)
            //{

            //}
            //if (this.dbugMark2 == 10 || this.dbugMark2 == 12)
            //{
            //}
#endif


            Css.CssDisplay display = this.CssDisplay;
            //
            if (display == Css.CssDisplay.TableCell &&
                this.EmptyCells == Css.CssEmptyCell.Hide &&
                this.IsSpaceOrEmpty)
            {
                return;
            }


#if DEBUG
            p.dbugEnterNewContext(this, PaintVisitor.PaintVisitorContextName.Init);
#endif
            Color prevBgColorHint = p.CurrentSolidBackgroundColorHint;
            //-----------------------------------------------
            bool       hasPrevClip = false;
            RectangleF prevClip    = RectangleF.Empty;
            p.EnterNewLatePaintContext();
            //---------------------------------------------
            //if (display != Css.CssDisplay.Inline ||
            //    this.Position == Css.CssPosition.Absolute ||
            //    this.Position == Css.CssPosition.Fixed)
            if (_renderBGAndBorder)
            {
                RectangleF bounds = new RectangleF(0, 0, this.VisualWidth, this.VisualHeight);
                PaintBackground(p, bounds, true, true);
                if (this.HasSomeVisibleBorder)
                {
                    p.PaintBorders(this, bounds, true, true);
                }
#if DEBUG
                dbugPaint(p, bounds);
#endif
            }

            //---------------------------------------------
            if (this.LineBoxCount > 0)
            {
                float viewport_top    = p.ViewportTop;
                float viewport_bottom = p.ViewportBottom;
                int   drawState       = 0;
                var   c_lineNode      = _clientLineBoxes.First;
                while (c_lineNode != null)
                {
                    CssLineBox line = c_lineNode.Value;
                    if (line.CachedLineBottom >= viewport_top &&
                        line.CachedLineTop <= viewport_bottom)
                    {
                        Rectangle currentClipRect = p.CurrentClipRect;
                        drawState = 1;//drawing in viewport area
#if DEBUG
                        //System.Diagnostics.Debug.WriteLine("clip_rect:" + currentClipRect);
                        dbugCounter.dbugLinePaintCount++;
#endif

                        int cX    = p.CanvasOriginX;
                        int cy    = p.CanvasOriginY;
                        int newCy = cy + (int)line.CachedLineTop;

                        if (newCy <= (cy + currentClipRect.Bottom) &&
                            newCy + line.CacheLineHeight >= (cy + currentClipRect.Top))
                        {
                            p.SetCanvasOrigin(cX, newCy);
                            //1.
                            line.PaintBackgroundAndBorder(p);

                            SelectionSegment selSegment = line.SelectionSegment;
                            if (selSegment != null)
                            {
                                switch (selSegment.Kind)
                                {
                                case SelectionSegmentKind.FullLine:
                                {
                                    Color prevColor2 = p.CurrentSolidBackgroundColorHint;        //save2
                                    p.CurrentSolidBackgroundColorHint = p.CssBoxSelectionColor;

                                    selSegment.PaintSelection(p, line);

                                    line.PaintRuns(p);

                                    p.CurrentSolidBackgroundColorHint = prevColor2;         //restore2
                                }
                                break;

                                case SelectionSegmentKind.PartialBegin:
                                case SelectionSegmentKind.SingleLine:
                                case SelectionSegmentKind.PartialEnd:
                                {
                                    //TODO: review here again***
                                    //partial line

                                    //[A]
                                    line.PaintRuns(p);         //normal line
                                                               //-----

                                    //[B]
                                    //selection part with clip rect

                                    Color prevColor2 = p.CurrentSolidBackgroundColorHint;        //save2
                                    //p.CurrentSolidBackgroundColorHint = prevBgColorHint;


                                    int xpos = selSegment.BeginAtPx;
                                    int w    = selSegment.WidthPx;

                                    Rectangle clipRect = p.CurrentClipRect;
                                    p.SetClipArea(xpos, 0, w, (int)line.CacheLineHeight);
                                    selSegment.PaintSelection(p, line);

                                    p.CurrentSolidBackgroundColorHint = p.CssBoxSelectionColor;

                                    line.PaintRuns(p);
                                    p.SetClipArea(clipRect.X, clipRect.Top, clipRect.Width, clipRect.Height); //restore

                                    p.CurrentSolidBackgroundColorHint = prevColor2;                           //restore2
                                }
                                break;
                                }
                            }
                            else
                            {
                                //2.

                                line.PaintRuns(p);
                            }


                            //3.
                            line.PaintDecoration(p);
#if DEBUG
                            line.dbugPaintRuns(p);
#endif

                            p.SetCanvasOrigin(cX, cy);//back
                        }
                    }
                    else if (drawState == 1)
                    {
                        //outof viewport -> break
                        break;
                    }

                    //----------------------------------------
                    c_lineNode = c_lineNode.Next;
                }
            }
            else
            {
                if (this.HasContainingBlockProperty)
                {
                    p.PushContaingBlock(this);
                    int ox   = p.CanvasOriginX;
                    int oy   = p.CanvasOriginY;
                    var node = _aa_boxes.GetFirstLinkedNode();
                    while (node != null)
                    {
                        CssBox b = node.Value;
                        if (b.CssDisplay == Css.CssDisplay.None || b.IsAddedToAbsoluteLayer)
                        {
                            node = node.Next;
                            continue;
                        }
                        else if (b.IsOutOfFlowBox)
                        {
                            //
                            p.AddToLatePaintList(b);
                            node = node.Next;
                            continue;
                        }
                        //move to left-top of client box
                        p.SetCanvasOrigin(ox + (int)b.LocalX, oy + (int)b.LocalY);
                        if (b._decorator != null)
                        {
                            b._decorator.Paint(b, p);
                        }

                        if (b.HasClipArea)
                        {
                            if (p.PushLocalClipArea(b.VisualWidth, b.VisualHeight))
                            {
                                CssBox.Paint(b, p);
                                p.PopLocalClipArea();
                            }
                        }
                        else
                        {
                            CssBox.Paint(b, p);
                        }

                        node = node.Next;
                    }
                    p.SetCanvasOrigin(ox, oy);
                    p.PopContainingBlock();
                }
                else
                {
                    //if not
                    int ox   = p.CanvasOriginX;
                    int oy   = p.CanvasOriginY;
                    var node = _aa_boxes.GetFirstLinkedNode();
                    while (node != null)
                    {
                        CssBox b = node.Value;
                        if (b.CssDisplay == Css.CssDisplay.None || b.IsAddedToAbsoluteLayer)
                        {
                            node = node.Next;
                            continue;
                        }
                        p.SetCanvasOrigin(ox + (int)b.LocalX, oy + (int)b.LocalY);

                        CssBox.Paint(b, p);
                        node = node.Next;
                    }
                    p.SetCanvasOrigin(ox, oy);
                }
            }
            //------------------------------------------
            //debug
            //var clientLeft = this.ClientLeft;
            //g.DrawRectangle(Pens.GreenYellow, 0, 0, 5, 10);
            //g.DrawRectangle(Pens.HotPink, this.ClientRight - 5, 0, 5, 10);
            //------------------------------------------

            if (this.HasAbsoluteLayer)
            {
                p.PushContaingBlock(this);
                int ox = p.CanvasOriginX;
                int oy = p.CanvasOriginY;
                int j  = _absPosLayer.Count;
                for (int i = 0; i < j; ++i)
                {
                    CssBox b = _absPosLayer.GetBox(i);
                    if (b.CssDisplay == Css.CssDisplay.None)
                    {
                        continue;
                    }
                    p.SetCanvasOrigin(ox + (int)b.LocalX, oy + (int)b.LocalY);
                    CssBox.Paint(b, p);
                }
                //var node = _absPosLayer.GetFirstLinkedNode();
                //while (node != null)
                //{
                //    CssBox b = node.Value;
                //    if (b.CssDisplay == Css.CssDisplay.None)
                //    {
                //        node = node.Next;
                //        continue;
                //    }
                //    p.SetCanvasOrigin(ox + (int)b.LocalX, oy + (int)b.LocalY);
                //    b.Paint(p);
                //    node = node.Next;
                //}
                p.SetCanvasOrigin(ox, oy);
                p.PopContainingBlock();
            }

            if (p.LatePaintItemCount > 0)
            {
                //late paint -> floatBox
                Rectangle latestClipRect = p.CurrentClipRect;
                p.PopLocalClipArea(); //temp
                p.PushContaingBlock(this);
                int j  = p.LatePaintItemCount;
                int ox = p.CanvasOriginX;
                int oy = p.CanvasOriginY;
                for (int i = 0; i < j; ++i)
                {
                    CssBox box = p.GetLatePaintItem(i);
                    if (box.CssDisplay == Css.CssDisplay.None)
                    {
                        continue;
                    }
                    p.SetCanvasOrigin(ox + (int)box.LocalX, oy + (int)box.LocalY);
                    CssBox.Paint(box, p);
                    p.SetCanvasOrigin(ox, oy);
                }
                p.PopContainingBlock();
                p.PushLocalClipArea(latestClipRect.Width, latestClipRect.Height);//push back
            }
            p.ExitCurrentLatePaintContext();
            //must! ,
            if (hasPrevClip)
            {
                p.PopLocalClipArea();
            }

            p.CurrentSolidBackgroundColorHint = prevBgColorHint;


#if DEBUG
            p.dbugExitContext();
#endif
        }