public static void Paint(CssBox box, PaintVisitor p) { #if DEBUG dbugCounter.dbugBoxPaintCount++; #endif if (box._isVisible) { //offset if (box._mayHasViewport) { if (box.ViewportX != 0 || box.ViewportY != 0) { int enter_canvas_X = p.CanvasOriginX; int enter_canvas_Y = p.CanvasOriginY; p.SetCanvasOrigin(enter_canvas_X - box.ViewportX, enter_canvas_Y - box.ViewportY); box.PaintImp(p); p.SetCanvasOrigin(enter_canvas_X, enter_canvas_Y);//restore } else { box.PaintImp(p); } } else { box.PaintImp(p); } } }
public void Paint(PaintVisitor p) { #if DEBUG //if (__aa_dbugId == 5) //{ //} dbugCounter.dbugBoxPaintCount++; #endif if (_isVisible) { //offset if (_mayHasViewport) { p.OffsetCanvasOrigin(-this.ViewportX, -this.ViewportY); PaintImp(p); p.OffsetCanvasOrigin(this.ViewportX, this.ViewportY); } else { PaintImp(p); } } }
/// <summary> /// Draws all the border of the box with respect to style, width, etc. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="box">the box to draw borders for</param> /// <param name="rect">the bounding rectangle to draw in</param> /// <param name="isFirst">is it the first rectangle of the element</param> /// <param name="isLast">is it the last rectangle of the element</param> public static void DrawBoxBorders(PaintVisitor p, CssBox box, RectangleF rect, bool isFirst, bool isLast) { if (rect.Width > 0 && rect.Height > 0) { if (box.BorderTopVisible) { DrawBorder(CssSide.Top, box, p, rect, isFirst, isLast); } if (isFirst && box.BorderLeftVisible) { DrawBorder(CssSide.Left, box, p, rect, true, isLast); } if (box.BorderBottomVisible) { DrawBorder(CssSide.Bottom, box, p, rect, isFirst, isLast); } if (isLast && box.BorderRightVisible) { DrawBorder(CssSide.Right, box, p, rect, isFirst, true); } } }
public void PerformPaint(PaintVisitor p) { if (_rootBox == null) { return; } p.PushContaingBlock(_rootBox); #if DEBUG p.dbugEnableLogRecord = false; p.dbugResetLogRecords(); #endif _rootBox.Paint(p); p.PopContainingBlock(); #if DEBUG if (p.dbugEnableLogRecord) { //var logs = p.logRecords; //System.Text.StringBuilder stbuilder = new System.Text.StringBuilder(); //foreach (var str in logs) //{ // stbuilder.AppendLine(str); //} //System.IO.File.AppendAllText("drawLogs.txt", stbuilder.ToString()); } #endif }
internal void PaintBackgroundAndBorder(PaintVisitor p) { //iterate each strip //if (_bottomUpBoxStrips == null) //{ // return; //} for (int i = _bottomUpBoxStrips.Length - 1; i >= 0; --i) { PartialBoxStrip strip = _bottomUpBoxStrips[i]; CssBox stripOwner = strip.owner; if (!stripOwner.HasVisibleBgColor) { continue; } //----------------------------------------------------------------- RectangleF stripArea = strip.Bound; bool isFirstLine, isLastLine; CssBox.GetSplitInfo(stripOwner, this, out isFirstLine, out isLastLine); stripOwner.PaintBackground(p, stripArea, isFirstLine, isLastLine); //if (stripOwner.CssDisplay != Css.CssDisplay.TableCell // && stripOwner.HasSomeVisibleBorder) //{ // p.PaintBorders(stripOwner, stripArea, isFirstLine, isLastLine); //} } }
internal void dbugPaintRuns(PaintVisitor p) { if (!PaintVisitor.dbugDrawWireFrame) { return; } //linebox float x1 = 0; float y1 = 0; float x2 = x1 + this.CachedLineContentWidth; float y2 = y1 + this.CacheLineHeight; //draw diagonal p.dbugDrawDiagonalBox(Color.Blue, x1, y1, x2, y2); //g.DrawRectangle(Pens.Blue, // this.OwnerBox.LocationX, // this.CachedLineTop, // this.CachedLineContentWidth, // this.CacheLineHeight); //foreach (var strip in _boxStrips.Values) //{ // var bound = strip.Bound; // bound.Offset(offset); // dbugDrawDiagnalBox(g, Pens.Green, bound.X, bound.Y, bound.Right, bound.Bottom); //} //return; foreach (CssRun w in _runs) { p.DrawRectangle(Color.DeepPink, w.Left, w.Top, w.Width, w.Height); //p.dbugDrawDiagonalBox(Color.DeepPink, w.Left, w.Top, w.Width, w.Height); } p.FillRectangle(Color.Red, 0, 0, 5, 5); }
internal static PaintVisitor GetSharedPaintVisitor(HtmlVisualRoot htmlVisualRoot, DrawBoard canvas) { PaintVisitor painter = (s_paintVisitorStock.Count == 0) ? new PaintVisitor() : s_paintVisitorStock.Dequeue(); painter.Bind(htmlVisualRoot, canvas); return(painter); }
public void dbugPaint(PaintVisitor p, RectangleF r) { if (!PaintVisitor.dbugDrawWireFrame) { return; } // var htmlE = CssBox.UnsafeGetController(this); if (htmlE == null) { //anonymous box //Font f = new Font("tahoma", 10); //p.Gfx.DrawString(this.__aa_dbugId.ToString(), f, System.Drawing.Color.Black, // new PointF(r.Left + 10, r.Top + 10), new SizeF(r.Width, r.Height)); //f.Dispose(); p.dbugDrawDiagonalBox(Color.Gray, r.Left, r.Top, r.Right, r.Bottom); } else { Color color = Color.Green; switch (this._cssDisplay) { case Css.CssDisplay.TableCell: color = Color.OrangeRed; break; } p.dbugDrawDiagonalBox(color, r.Left, r.Top, r.Right, r.Bottom); } }
public void Paint(PaintVisitor p) { #if DEBUG //if (__aa_dbugId == 5) //{ //} dbugCounter.dbugBoxPaintCount++; #endif if (_isVisible) { //offset if (_mayHasViewport) { if (ViewportX != 0 || ViewportY != 0) { int enter_canvas_X = p.CanvasOriginX; int enter_canvas_Y = p.CanvasOriginY; p.SetCanvasOrigin(enter_canvas_X - ViewportX, enter_canvas_Y - ViewportY); PaintImp(p); p.SetCanvasOrigin(enter_canvas_X, enter_canvas_Y);//restore } else { PaintImp(p); } } else { PaintImp(p); } } }
/// <summary> /// Paints the fragment /// </summary> /// <param name="g">the device to draw to</param> protected override void PaintImp(PaintVisitor p) { #if DEBUG p.dbugEnterNewContext(this, PaintVisitor.PaintVisitorContextName.Init); #endif Color bgColorHint = p.CurrentSolidBackgroundColorHint;//save var rect = new RectangleF(0, 0, this.VisualWidth, this.VisualHeight); if (rect.Height > 2 && RenderUtils.IsColorVisible(ActualBackgroundColor)) { p.FillRectangle(ActualBackgroundColor, rect.Left, rect.Top, rect.Width, rect.Height); } if (rect.Height > 1) { p.PaintBorders(this, rect); } else { p.PaintBorder(this, CssSide.Top, this.BorderTopColor, rect); } p.CurrentSolidBackgroundColorHint = bgColorHint;//restore #if DEBUG p.dbugExitContext(); #endif }
public void Paint(CssBox box, PaintVisitor p) { p.FillRectangle(this.Color, box.LocalX + this.HBoxShadowOffset, box.LocalY + this.VBoxShadowOffset, box.VisualWidth, box.VisualHeight); }
internal void PaintDecoration(PaintVisitor p) { for (int i = _bottomUpBoxStrips.Length - 1; i >= 0; --i) { PartialBoxStrip strip = _bottomUpBoxStrips[i]; CssBox ownerBox = strip.owner; CssBox.GetSplitInfo(ownerBox, this, out bool isFirstLine, out bool isLastLine); ownerBox.PaintDecoration(p.InnerDrawBoard, strip.Bounds, isFirstLine, isLastLine); } }
/// <summary> /// Paints the fragment /// </summary> /// <param name="g">the device to draw to</param> protected override void PaintImp(PaintVisitor p) { // load image iff it is in visible rectangle //1. single image can't be splited #if DEBUG p.dbugEnterNewContext(this, PaintVisitor.PaintVisitorContextName.Init); #endif Paint(p, new RectangleF(0, 0, this.VisualWidth, this.VisualHeight)); #if DEBUG p.dbugExitContext(); #endif }
internal void PaintDecoration(PaintVisitor p) { //if (_bottomUpBoxStrips == null) //{ // return; //} for (int i = _bottomUpBoxStrips.Length - 1; i >= 0; --i) { var strip = _bottomUpBoxStrips[i]; CssBox ownerBox = strip.owner; bool isFirstLine, isLastLine; CssBox.GetSplitInfo(ownerBox, this, out isFirstLine, out isLastLine); ownerBox.PaintDecoration(p.InnerCanvas, strip.Bound, isFirstLine, isLastLine); } }
internal static PaintVisitor GetSharedPainter(HtmlContainer htmlCont, Canvas canvas) { PaintVisitor painter = null; if (painterStock.Count == 0) { painter = new PaintVisitor(); } else { painter = painterStock.Dequeue(); } painter.Bind(htmlCont, canvas); return painter; }
protected override void DrawBoxContent(DrawBoard canvas, Rectangle updateArea) { //TODO: review here, // if (_myHtmlCont == null) { return; } _myHtmlCont.CheckDocUpdate(); DrawBoard cpuDrawBoard = null; if (PreferSoftwareRenderer && canvas.IsGpuDrawBoard && (cpuDrawBoard = canvas.GetCpuBlitDrawBoard()) != null) { //TODO: review this again *** //test built-in 'shared' software rendering surface cpuDrawBoard.Clear(Color.White); PaintVisitor painter = PaintVisitorStock.GetSharedPaintVisitor(_myHtmlCont, cpuDrawBoard); painter.SetViewportSize(this.Width, this.Height); #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif _myHtmlCont.PerformPaint(painter); PaintVisitorStock.ReleaseSharedPaintVisitor(painter); //then copy from cpu to gpu canvas.BlitFrom(cpuDrawBoard, X, Y, this.Width, this.Height, 0, 0); } else { PaintVisitor painter = PaintVisitorStock.GetSharedPaintVisitor(_myHtmlCont, canvas); painter.SetViewportSize(this.Width, this.Height); #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif _myHtmlCont.PerformPaint(painter); PaintVisitorStock.ReleaseSharedPaintVisitor(painter); } }
internal static PaintVisitor GetSharedPaintVisitor(HtmlVisualRoot htmlVisualRoot, DrawBoard canvas) { PaintVisitor painter = null; if (s_paintVisitorStock.Count == 0) { painter = new PaintVisitor(); } else { painter = s_paintVisitorStock.Dequeue(); } painter.Bind(htmlVisualRoot, canvas); return(painter); }
internal static PaintVisitor GetSharedPainter(HtmlContainer htmlCont, DrawBoard canvas) { PaintVisitor painter = null; if (painterStock.Count == 0) { painter = new PaintVisitor(); } else { painter = painterStock.Dequeue(); } painter.Bind(htmlCont, canvas); return(painter); }
public void PaintSelection(PaintVisitor p, CssLineBox line) { if (this.Kind == SelectionSegmentKind.FullLine) { p.FillRectangle(Color.LightGray, 0, 0, line.CachedLineContentWidth, line.CacheLineHeight); } else { p.FillRectangle( Color.LightGray, this.BeginAtPx, 0, this.WidthPx, (int)line.CacheLineHeight); } }
protected override void DrawBoxContent(DrawBoard canvas, Rectangle updateArea) { //TODO: review here, // if (myHtmlCont == null) { return; } myHtmlCont.CheckDocUpdate(); PaintVisitor painter = PainterStock.GetSharedPainter(this.myHtmlCont, canvas); painter.SetViewportSize(this.Width, this.Height); #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif myHtmlCont.PerformPaint(painter); PainterStock.ReleaseSharedPainter(painter); }
public void Paint(PaintVisitor p) { #if DEBUG dbugCounter.dbugBoxPaintCount++; #endif if (this._isVisible) { //offset if (this.mayHasViewport) { p.OffsetCanvasOrigin(-this.ViewportX, -this.ViewportY); PaintImp(p); p.OffsetCanvasOrigin(this.ViewportX, this.ViewportY); } else { PaintImp(p); } } }
public void PerformPaint(PaintVisitor p) { if (_rootBox == null) { return; } p.PushContaingBlock(_rootBox); #if DEBUG p.dbugEnableLogRecord = false; p.dbugResetLogRecords(); dbugPaintN++; #endif _rootBox.Paint(p); p.PopContainingBlock(); #if DEBUG if (p.dbugEnableLogRecord) { } #endif }
protected override void PaintImp(PaintVisitor p) { #if DEBUG p.dbugEnterNewContext(this, PaintVisitor.PaintVisitorContextName.Init); #endif var g = p.InnerCanvas; var prevMode = g.SmoothingMode; g.SmoothingMode = SmoothingMode.AntiAlias; //render this svg var cnode = this.SvgSpec.GetFirstNode(); while (cnode != null) { cnode.Value.Paint(p); cnode = cnode.Next; } g.SmoothingMode = prevMode; #if DEBUG p.dbugExitContext(); #endif }
void DrawWithTempTransitionImage(PaintVisitor p, RectangleF r) { Image img; if ((img = (Image)_tmpTransitionImgBinder.LocalImage) != null) //assign and test { if (this.VisualWidth != 0) { //TODO: review here if (_imgRun.ImageRectangle == Rectangle.Empty) { p.DrawImage(img, r.Left, r.Top, this.VisualWidth, this.VisualHeight); } else { p.DrawImage(img, _imgRun.ImageRectangle); } } else { if (_imgRun.ImageRectangle == Rectangle.Empty) { p.DrawImage(img, r.Left, r.Top, img.Width, img.Height); } else { p.DrawImage(img, _imgRun.ImageRectangle); } } } }
public virtual void Paint(PaintVisitor p) { }
public override void Paint(PaintVisitor p) { if (this.strokeColor.A > 0 && this.ActualStrokeWidth > 0) { p.DrawPath(myCachedPath, this.strokeColor, this.ActualStrokeWidth); } }
/// <summary> /// Makes a border path for rounded borders.<br/> /// To support rounded dotted/dashed borders we need to use arc in the border path.<br/> /// Return null if the border is not rounded.<br/> /// </summary> /// <param name="border">Desired border</param> /// <param name="b">Box which the border corresponds</param> /// <param name="r">the rectangle the border is enclosing</param> /// <returns>Beveled border path, null if there is no rounded corners</returns> static GraphicsPath GetRoundedBorderPath(PaintVisitor p, CssSide border, CssBox b, RectangleF r) { GraphicsPath path = null; switch (border) { case CssSide.Top: if (b.ActualCornerNW > 0 || b.ActualCornerNE > 0) { path = new GraphicsPath(); if (b.ActualCornerNW > 0) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth / 2); } if (b.ActualCornerNE > 0) { path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); } else { path.AddLine(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2); } } break; case CssSide.Bottom: if (b.ActualCornerSW > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerSE > 0) { path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - .1f); } if (b.ActualCornerSW > 0) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2 + .1f, r.Bottom - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2); } } break; case CssSide.Right: if (b.ActualCornerNE > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerNE > 0 && b.BorderTopStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2 + .1f); } if (b.ActualCornerSE > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerSE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2 - .1f, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2); } } break; case CssSide.Left: if (b.ActualCornerNW > 0 || b.ActualCornerSW > 0) { path = new GraphicsPath(); if (b.ActualCornerSW > 0 && b.BorderTopStyle >= CssBorderStyle.Visible) //(b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden)) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2 - .1f); } if (b.ActualCornerNW > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2 + .1f, r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2); } } break; } return(path); }
public override void Paint(PaintVisitor p) { p.UseCurrentContext = true; p.CurrentContextFillColor = spec.ActualColor; p.CurrentContextPenColor = spec.StrokeColor; p.CurrentContextPenWidth = this.ActualStrokeWidth; var node = this.GetFirstNode(); while (node != null) { node.Value.Paint(p); node = node.Next; } p.UseCurrentContext = false; }
static PaintVisitor GetSharedPainter(LayoutFarm.HtmlBoxes.HtmlContainer htmlCont, PixelFarm.Drawing.Canvas canvas) { PaintVisitor painter = null; if (painterStock.Count == 0) { painter = new PaintVisitor(); } else { painter = painterStock.Dequeue(); } painter.Bind(htmlCont, canvas); return painter; }
protected virtual void PaintImp(PaintVisitor p) { //if (this.dbugMark2 == 10 || this.dbugMark2 == 12) //{ //} 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 //----------------------------------------------- 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 (this._renderBGAndBorder) { RectangleF bound = new RectangleF(0, 0, this.VisualWidth, this.VisualHeight); PaintBackground(p, bound, true, true); if (this.HasSomeVisibleBorder) { p.PaintBorders(this, bound, true, true); } #if DEBUG dbugPaint(p, bound); #endif } //--------------------------------------------- if (this.LineBoxCount > 0) { float viewport_top = p.ViewportTop; float viewport_bottom = p.ViewportBottom; int drawState = 0; var c_lineNode = this._clientLineBoxes.First; while (c_lineNode != null) { CssLineBox line = c_lineNode.Value; if (line.CachedLineBottom >= viewport_top && line.CachedLineTop <= viewport_bottom) { #if DEBUG dbugCounter.dbugLinePaintCount++; #endif drawState = 1;//drawing in viewport area int cX = p.CanvasOriginX; int cy = p.CanvasOriginY; p.SetCanvasOrigin(cX, cy + (int)line.CachedLineTop); //1. line.PaintBackgroundAndBorder(p); if (line.SelectionSegment != null) { line.SelectionSegment.PaintSelection(p, line); } //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 = this._aa_boxes.GetFirstLinkedNode(); while (node != null) { CssBox b = node.Value; if (b.CssDisplay == Css.CssDisplay.None) { 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)) { b.Paint(p); } p.PopLocalClipArea(); } else { b.Paint(p); } node = node.Next; } p.SetCanvasOrigin(ox, oy); p.PopContainingBlock(); } else { //if not int ox = p.CanvasOriginX; int oy = p.CanvasOriginY; var node = this._aa_boxes.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); } } //------------------------------------------ //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; var node = this._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); box.Paint(p); p.SetCanvasOrigin(ox, oy); } p.PopContainingBlock(); p.PushLocalClipArea(latestClipRect.Width, latestClipRect.Height);//push back } p.ExitCurrentLatePaintContext(); //must! , if (hasPrevClip) { p.PopLocalClipArea(); } #if DEBUG p.dbugExitContext(); #endif }
internal static void ReleaseSharedPaintVisitor(PaintVisitor p) { p.UnBind(); s_paintVisitorStock.Enqueue(p); }
internal void dbugPaintRuns(PaintVisitor p) { if (!PaintVisitor.dbugDrawWireFrame) { return; } //linebox float x1 = 0; float y1 = 0; float x2 = x1 + this.CachedLineContentWidth; float y2 = y1 + this.CacheLineHeight; //draw diagonal p.dbugDrawDiagonalBox(Color.Blue, x1, y1, x2, y2); //g.DrawRectangle(Pens.Blue, // this.OwnerBox.LocationX, // this.CachedLineTop, // this.CachedLineContentWidth, // this.CacheLineHeight); //foreach (var strip in this._boxStrips.Values) //{ // var bound = strip.Bound; // bound.Offset(offset); // dbugDrawDiagnalBox(g, Pens.Green, bound.X, bound.Y, bound.Right, bound.Bottom); //} //return; foreach (CssRun w in this._runs) { p.DrawRectangle(Color.DeepPink, w.Left, w.Top, w.Width, w.Height); //p.dbugDrawDiagonalBox(Color.DeepPink, w.Left, w.Top, w.Width, w.Height); } p.FillRectangle(Color.Red, 0, 0, 5, 5); }
public override void Paint(PaintVisitor p) { Canvas g = p.InnerCanvas; if (fillColor.A > 0) { p.FillPath(_path, this.fillColor); } //--------------------------------------------------------- if (this.ImageBinder != null) { //--------------------------------------------------------- //Because we need external image resource , so ... //use render technique like CssBoxImage **** //--------------------------------------------------------- RectangleF r = new RectangleF(this.ActualX, this.ActualY, this.ActualWidth, this.ActualHeight); bool tryLoadOnce = false; EVAL_STATE: switch (this.ImageBinder.State) { case ImageBinderState.Unload: { //async request image if (!tryLoadOnce) { p.RequestImageAsync(_imgRun.ImageBinder, this._imgRun, this); //retry again tryLoadOnce = true; goto EVAL_STATE; } } break; case ImageBinderState.Loading: { //RenderUtils.DrawImageLoadingIcon(g, r); } break; case ImageBinderState.Loaded: { Image img; if ((img = _imgRun.ImageBinder.Image) != null) { if (_imgRun.ImageRectangle == Rectangle.Empty) { g.DrawImage(img, r); } else { // g.DrawImage(img, _imgRun.ImageRectangle); } } else { RenderUtils.DrawImageLoadingIcon(g, r); if (r.Width > 19 && r.Height > 19) { g.DrawRectangle(Color.LightGray, r.X, r.Y, r.Width, r.Height); } } } break; case ImageBinderState.NoImage: { } break; case ImageBinderState.Error: { RenderUtils.DrawImageErrorIcon(g, r); } break; } } //--------------------------------------------------------- if (this.strokeColor.A > 0 && this.ActualStrokeWidth > 0) { p.DrawPath(_path, strokeColor, ActualStrokeWidth); } }
/// <summary> /// Paints the fragment /// </summary> /// <param name="g">the device to draw to</param> protected override void PaintImp(PaintVisitor p) { #if DEBUG p.dbugEnterNewContext(this, PaintVisitor.PaintVisitorContextName.Init); #endif var rect = new RectangleF(0, 0, this.VisualWidth, this.VisualHeight); if (rect.Height > 2 && RenderUtils.IsColorVisible(ActualBackgroundColor)) { p.FillRectangle(ActualBackgroundColor, rect.X, rect.Y, rect.Width, rect.Height); } if (rect.Height > 1) { p.PaintBorders(this, rect); } else { p.PaintBorder(this, CssSide.Top, this.BorderTopColor, rect); } #if DEBUG p.dbugExitContext(); #endif }
internal void PaintBackgroundAndBorder(PaintVisitor p) { //iterate each strip //if (_bottomUpBoxStrips == null) //{ // return; //} for (int i = _bottomUpBoxStrips.Length - 1; i >= 0; --i) { var strip = _bottomUpBoxStrips[i]; var stripOwner = strip.owner; if (!stripOwner.HasVisibleBgColor) { continue; } //----------------------------------------------------------------- var stripArea = strip.Bound; bool isFirstLine, isLastLine; CssBox.GetSplitInfo(stripOwner, this, out isFirstLine, out isLastLine); stripOwner.PaintBackground(p, stripArea, isFirstLine, isLastLine); //if (stripOwner.CssDisplay != Css.CssDisplay.TableCell // && stripOwner.HasSomeVisibleBorder) //{ // p.PaintBorders(stripOwner, stripArea, isFirstLine, isLastLine); //} } }
public virtual void Paint(PaintVisitor p, RectangleF r) { }
public override void Paint(PaintVisitor p, RectangleF rect) { PaintBackground(p, rect, true, true); if (this.HasSomeVisibleBorder) { p.PaintBorders(this, rect, true, true); } //--------------------------------------------------------- RectangleF r = _imgRun.Rectangle; r.Height -= ActualBorderTopWidth + ActualBorderBottomWidth + ActualPaddingTop + ActualPaddingBottom; r.Y += ActualBorderTopWidth + ActualPaddingTop; r.X = (float)Math.Floor(r.X); r.Y = (float)Math.Floor(r.Y); bool tryLoadOnce = false; EVAL_STATE: switch (_imgRun.ImageBinder.State) { case ImageBinderState.Unload: { //async request image if (!tryLoadOnce) { p.RequestImageAsync(_imgRun.ImageBinder, this._imgRun, this); //retry again tryLoadOnce = true; goto EVAL_STATE; } } break; case ImageBinderState.Loading: { //RenderUtils.DrawImageLoadingIcon(g, r); } break; case ImageBinderState.Loaded: { Image img; if ((img = (Image)_imgRun.ImageBinder.Image) != null) { if (_imgRun.ImageRectangle == Rectangle.Empty) { p.DrawImage(img, r.Left, r.Top, img.Width, img.Height); } else { p.DrawImage(img, _imgRun.ImageRectangle); } } else { RenderUtils.DrawImageLoadingIcon(p.InnerCanvas, r); if (r.Width > 19 && r.Height > 19) { p.DrawRectangle(Color.LightGray, r.X, r.Y, r.Width, r.Height); } } } break; case ImageBinderState.NoImage: { } break; case ImageBinderState.Error: { RenderUtils.DrawImageErrorIcon(p.InnerCanvas, r); } break; } //#if DEBUG // p.FillRectangle(Color.Red, rect.X, rect.Y, rect.Width, rect.Height); //#endif }
protected override void RenderClientContent(DrawBoard d, UpdateArea updateArea) { //TODO: review here, if (_myHtmlVisualRoot == null) { return; } bool useBackbuffer = d.IsGpuDrawBoard; //useBackbuffer = false; //... TODO: review here, check doc update here? _myHtmlVisualRoot.CheckDocUpdate(); if (useBackbuffer) { PaintVisitor painter = PaintVisitorStock.GetSharedPaintVisitor(_myHtmlVisualRoot, d); if (_builtInBackBuffer == null) { _builtInBackBuffer = painter.CreateOffscreenDrawBoard(this.Width, this.Height); } #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif if (!_builtInBackBuffer.IsValid) { //painter.FillRectangle(Color.Red, 0, 0, 100, 100);//debug //painter.DrawText(i.ToString().ToCharArray(), 0, 1, new PointF(0, 0), new SizeF(100, 100)); //debug float backupViewportW = painter.ViewportWidth; //backup float backupViewportH = painter.ViewportHeight; //backup painter.EnterNewDrawboardBuffer(_builtInBackBuffer); //*** switch to builtInBackbuffer painter.SetViewportSize(this.Width, this.Height); if (!_hasAccumRect) { _invalidateRect = new Rectangle(0, 0, Width, Height); } #if DEBUG //System.Diagnostics.Debug.WriteLine("inv_rect:" + _invalidateRect + "," + painter.ToString()); #endif if (painter.PushLocalClipArea( _invalidateRect.Left, _invalidateRect.Top, _invalidateRect.Width, _invalidateRect.Height)) { #if DEBUG //for debug , test clear with random color //another useful technique to see latest clear area frame-by-frame => use random color //painter.Clear(ColorEx.dbugGetRandomColor()); painter.Clear(Color.White); #else painter.Clear(Color.White); #endif _myHtmlVisualRoot.PerformPaint(painter); painter.PopLocalClipArea(); } // _builtInBackBuffer.IsValid = true; _hasAccumRect = false; painter.ExitCurrentDrawboardBuffer(); //*** switch back painter.SetViewportSize(backupViewportW, backupViewportH); //restore viewport size } painter.DrawImage(_builtInBackBuffer.GetImage(), 0, 0, this.Width, this.Height); PaintVisitorStock.ReleaseSharedPaintVisitor(painter); } #if DEBUG else if (dbugPreferSoftwareRenderer && d.IsGpuDrawBoard) { //TODO: review this again *** //test built-in 'shared' software rendering surface DrawBoard cpuDrawBoard = null; if ((cpuDrawBoard = d.GetCpuBlitDrawBoard()) != null) { cpuDrawBoard.Clear(Color.White); PaintVisitor painter = PaintVisitorStock.GetSharedPaintVisitor(_myHtmlVisualRoot, cpuDrawBoard); painter.SetViewportSize(this.Width, this.Height); #if DEBUG painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif _myHtmlVisualRoot.PerformPaint(painter); PaintVisitorStock.ReleaseSharedPaintVisitor(painter); //then copy from cpu to gpu d.BlitFrom(cpuDrawBoard, X, Y, this.Width, this.Height, 0, 0); } } #endif else { PaintVisitor painter = PaintVisitorStock.GetSharedPaintVisitor(_myHtmlVisualRoot, d); painter.SetViewportSize(this.Width, this.Height); #if DEBUG //System.Diagnostics.Debug.WriteLine(">> 500x500"); painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); //for debug , test clear with random color //another useful technique to see latest clear area frame-by-frame => use random color //painter.Clear(Color.FromArgb(255, dbugRandom.Next(0, 255), dbugRandom.Next(0, 255), dbugRandom.Next(0, 255))); #endif #if DEBUG //System.Diagnostics.Debug.WriteLine("inv_rect:" + _invalidateRect + "," + painter.ToString()); #endif //painter.SetClipRect(new Rectangle(0, 0, 200, 200)); _myHtmlVisualRoot.PerformPaint(painter); #if DEBUG //System.Diagnostics.Debug.WriteLine("<< 500x500"); //painter.dbugDrawDiagonalBox(Color.Blue, this.X, this.Y, this.Width, this.Height); #endif PaintVisitorStock.ReleaseSharedPaintVisitor(painter); } }
/// <summary> /// Paints the background of the box /// </summary> /// <param name="g">the device to draw into</param> /// <param name="rect">the bounding rectangle to draw in</param> /// <param name="isFirst">is it the first rectangle of the element</param> /// <param name="isLast">is it the last rectangle of the element</param> internal void PaintBackground(PaintVisitor p, RectangleF rect, bool isFirst, bool isLast) { //return; //if (this.dbugMark1 > 0) //{ // Console.WriteLine(this.dbugMark1); // if ((this.dbugMark1 % 2) == 0) // { // } // else // { // } //} if (!this.HasVisibleBgColor) { return; } if (rect.Width > 0 && rect.Height > 0) { Brush brush = null; bool dispose = false; if (BackgroundGradient != Color.Transparent) { //use bg gradient brush = LinearGradientBrush.CreateLinearGradientBrush(rect, ActualBackgroundColor, ActualBackgroundGradient, ActualBackgroundGradientAngle); dispose = true; } else if (RenderUtils.IsColorVisible(ActualBackgroundColor)) { brush = new SolidBrush(this.ActualBackgroundColor); dispose = true; } Canvas g = p.InnerCanvas; SmoothingMode smooth = g.SmoothingMode; if (brush != null) { // atodo: handle it correctly (tables background) // if (isLast) // rectangle.Width -= ActualWordSpacing + CssUtils.GetWordEndWhitespace(ActualFont); GraphicsPath roundrect = null; bool hasSomeRoundCorner = this.HasSomeRoundCorner; if (hasSomeRoundCorner) { roundrect = RenderUtils.GetRoundRect( rect, ActualCornerNW, ActualCornerNE, ActualCornerSE, ActualCornerSW); } if (!p.AvoidGeometryAntialias && hasSomeRoundCorner) { g.SmoothingMode = SmoothingMode.AntiAlias; } if (roundrect != null) { g.FillPath(brush, roundrect); } else { g.FillRectangle(brush, (float)Math.Ceiling(rect.X), (float)Math.Ceiling(rect.Y), rect.Width, rect.Height); } g.SmoothingMode = smooth; if (roundrect != null) roundrect.Dispose(); if (dispose) brush.Dispose(); } if (isFirst) { var bgImageBinder = this.BackgroundImageBinder; if (bgImageBinder != null && bgImageBinder.Image != null) { BackgroundImagePaintHelper.DrawBackgroundImage(g, this, bgImageBinder, rect); } } } }
internal void PaintRuns(PaintVisitor p) { //iterate from each words CssBox latestOwner = null; var innerCanvas = p.InnerCanvas; var enterFont = innerCanvas.CurrentFont; var enterColor = innerCanvas.CurrentTextColor; var tmpRuns = this._runs; int j = tmpRuns.Count; 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, 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.InnerCanvas.CurrentFont = latestOwner.ResolvedFont; p.InnerCanvas.CurrentTextColor = latestOwner.ActualColor; } CssTextRun textRun = (CssTextRun)w; var wordPoint = new PointF(w.Left, w.Top); p.DrawText(CssBox.UnsafeGetTextBuffer(w.OwnerBox), textRun.TextStartIndex, textRun.TextLength, wordPoint, new SizeF(w.Width, w.Height)); } break; default: { #if DEBUG // w.OwnerBox.dbugPaintTextWordArea(g, offset, w); #endif } break; } } //--- //exit if (j > 0) { innerCanvas.CurrentFont = enterFont; innerCanvas.CurrentTextColor = enterColor; } }
public override void Paint(PaintVisitor p) { if (fillColor.A > 0) { p.FillPath(this.myCachedPath, this.fillColor); } if (this.strokeColor.A > 0) { p.DrawPath(this.myCachedPath, this.strokeColor, this.ActualStrokeWidth); } }
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; }
/// <summary> /// Draw specific border (top/bottom/left/right) with the box data (style/width/rounded).<br/> /// </summary> /// <param name="borderSide">desired border to draw</param> /// <param name="box">the box to draw its borders, contain the borders data</param> /// <param name="g">the device to draw into</param> /// <param name="rect">the rectangle the border is enclosing</param> /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param> /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param> static void DrawBorder(CssSide borderSide, CssBox box, PaintVisitor p, RectangleF rect, bool isLineStart, bool isLineEnd) { float actualBorderWidth; Color borderColor; CssBorderStyle style; GetBorderBorderDrawingInfo(box, borderSide, out style, out borderColor, out actualBorderWidth); DrawBoard g = p.InnerDrawBoard; if (box.HasSomeRoundCorner) { GraphicsPath borderPath = GetRoundedBorderPath(p, borderSide, box, rect); if (borderPath != null) { // rounded border need special path var smooth = g.SmoothingMode; if (!p.AvoidGeometryAntialias && box.HasSomeRoundCorner) { g.SmoothingMode = SmoothingMode.AntiAlias; } p.DrawPath(borderPath, borderColor, actualBorderWidth); //using (var pen = GetPen(p.Platform, style, borderColor, actualBorderWidth)) //using (borderPath) //{ // g.DrawPath(pen, borderPath); //} g.SmoothingMode = smooth; } } else { // non rounded border switch (style) { case CssBorderStyle.Inset: case CssBorderStyle.Outset: { // inset/outset border needs special rectangle PointF[] borderPnts = new PointF[4]; SetInOutsetRectanglePoints(borderSide, box, rect, isLineStart, isLineEnd, borderPnts); g.FillPolygon(borderColor, borderPnts); } break; default: { // solid/dotted/dashed border draw as simple line //using (var pen = GetPen(p.Platform, style, borderColor, actualBorderWidth)) //{ var prevColor = g.StrokeColor; g.StrokeColor = borderColor; float prevStrokeW = g.StrokeWidth; g.StrokeWidth = actualBorderWidth; //s_simpleRectBorderBuilder.SetBorderWidth( // box.ActualBorderLeftWidth, // box.ActualBorderTopWidth, // box.ActualBorderRightWidth, // box.ActualBorderBottomWidth // ); //s_simpleRectBorderBuilder.BuildOverRefBounds( // rect.Left, // rect.Top, // rect.Width, // rect.Height, // s_reusableBorderCoords); switch (borderSide) { case CssSide.Top: g.DrawLine((float)Math.Ceiling(rect.Left), rect.Top + box.ActualBorderTopWidth / 2, rect.Right - 1, rect.Top + box.ActualBorderTopWidth / 2); break; case CssSide.Left: g.DrawLine(rect.Left + box.ActualBorderLeftWidth / 2, (float)Math.Ceiling(rect.Top), rect.Left + box.ActualBorderLeftWidth / 2, (float)Math.Floor(rect.Bottom)); break; case CssSide.Bottom: g.DrawLine((float)Math.Ceiling(rect.Left), rect.Bottom - box.ActualBorderBottomWidth / 2, rect.Right - 1, rect.Bottom - box.ActualBorderBottomWidth / 2); break; case CssSide.Right: g.DrawLine(rect.Right - box.ActualBorderRightWidth / 2, (float)Math.Ceiling(rect.Top), rect.Right - box.ActualBorderRightWidth / 2, (float)Math.Floor(rect.Bottom)); break; } g.StrokeWidth = prevStrokeW; g.StrokeColor = prevColor; } break; } } }
/// <summary> /// Makes a border path for rounded borders.<br/> /// To support rounded dotted/dashed borders we need to use arc in the border path.<br/> /// Return null if the border is not rounded.<br/> /// </summary> /// <param name="border">Desired border</param> /// <param name="b">Box which the border corresponds</param> /// <param name="r">the rectangle the border is enclosing</param> /// <returns>Beveled border path, null if there is no rounded corners</returns> static GraphicsPath GetRoundedBorderPath(PaintVisitor p, CssSide border, CssBox b, RectangleF r) { GraphicsPath path = null; switch (border) { case CssSide.Top: if (b.ActualCornerNW > 0 || b.ActualCornerNE > 0) { path = new GraphicsPath(); if (b.ActualCornerNW > 0) path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); else path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth / 2); if (b.ActualCornerNE > 0) path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); else path.AddLine(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2); } break; case CssSide.Bottom: if (b.ActualCornerSW > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerSE > 0) path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); else path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2 - .1f); if (b.ActualCornerSW > 0) path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); else path.AddLine(r.Left + b.ActualBorderLeftWidth / 2 + .1f, r.Bottom - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualBorderBottomWidth / 2); } break; case CssSide.Right: if (b.ActualCornerNE > 0 || b.ActualCornerSE > 0) { path = new GraphicsPath(); if (b.ActualCornerNE > 0 && b.BorderTopStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerNE * 2 - b.ActualBorderRightWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNE * 2, b.ActualCornerNE * 2, 270f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2, r.Right - b.ActualBorderRightWidth / 2, r.Top + b.ActualCornerNE + b.ActualBorderTopWidth / 2 + .1f); } if (b.ActualCornerSE > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Right - b.ActualCornerSE * 2 - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSE * 2, b.ActualCornerSE * 2, 0f, 90f); } else { path.AddLine(r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2 - .1f, r.Right - b.ActualBorderRightWidth / 2, r.Bottom - b.ActualCornerSE - b.ActualBorderBottomWidth / 2); } } break; case CssSide.Left: if (b.ActualCornerNW > 0 || b.ActualCornerSW > 0) { path = new GraphicsPath(); if (b.ActualCornerSW > 0 && b.BorderTopStyle >= CssBorderStyle.Visible)//(b.BorderTopStyle == CssConstants.None || b.BorderTopStyle == CssConstants.Hidden)) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW * 2 - b.ActualBorderBottomWidth / 2, b.ActualCornerSW * 2, b.ActualCornerSW * 2, 90f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2, r.Left + b.ActualBorderLeftWidth / 2, r.Bottom - b.ActualCornerSW - b.ActualBorderBottomWidth / 2 - .1f); } if (b.ActualCornerNW > 0 && b.BorderBottomStyle >= CssBorderStyle.Visible) { path.AddArc(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualBorderTopWidth / 2, b.ActualCornerNW * 2, b.ActualCornerNW * 2, 180f, 90f); } else { path.AddLine(r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2 + .1f, r.Left + b.ActualBorderLeftWidth / 2, r.Top + b.ActualCornerNW + b.ActualBorderTopWidth / 2); } } break; } return path; }
public override void Paint(PaintVisitor p) { if (this.strokeColor.A > 0) { p.DrawLine( this.actualX1, this.actualY1, this.actualX2, this.actualY2, this.StrokeColor, this.ActualStrokeWidth); } }
/// <summary> /// Draw specific border (top/bottom/left/right) with the box data (style/width/rounded).<br/> /// </summary> /// <param name="borderSide">desired border to draw</param> /// <param name="box">the box to draw its borders, contain the borders data</param> /// <param name="g">the device to draw into</param> /// <param name="rect">the rectangle the border is enclosing</param> /// <param name="isLineStart">Specifies if the border is for a starting line (no bevel on left)</param> /// <param name="isLineEnd">Specifies if the border is for an ending line (no bevel on right)</param> static void DrawBorder(CssSide borderSide, CssBox box, PaintVisitor p, RectangleF rect, bool isLineStart, bool isLineEnd) { float actualBorderWidth; Color borderColor; CssBorderStyle style; GetBorderBorderDrawingInfo(box, borderSide, out style, out borderColor, out actualBorderWidth); Canvas g = p.InnerCanvas; if (box.HasSomeRoundCorner) { GraphicsPath borderPath = GetRoundedBorderPath(p, borderSide, box, rect); if (borderPath != null) { // rounded border need special path var smooth = g.SmoothingMode; if (!p.AvoidGeometryAntialias && box.HasSomeRoundCorner) { g.SmoothingMode = SmoothingMode.AntiAlias; } p.DrawPath(borderPath, borderColor, actualBorderWidth); //using (var pen = GetPen(p.Platform, style, borderColor, actualBorderWidth)) //using (borderPath) //{ // g.DrawPath(pen, borderPath); //} g.SmoothingMode = smooth; } } else { // non rounded border switch (style) { case CssBorderStyle.Inset: case CssBorderStyle.Outset: { // inset/outset border needs special rectangle PointF[] borderPnts = new PointF[4]; SetInOutsetRectanglePoints(borderSide, box, rect, isLineStart, isLineEnd, borderPnts); g.FillPolygon(borderColor, borderPnts); } break; default: { // solid/dotted/dashed border draw as simple line //using (var pen = GetPen(p.Platform, style, borderColor, actualBorderWidth)) //{ var prevColor = g.StrokeColor; g.StrokeColor = borderColor; float prevStrokeW = g.StrokeWidth; g.StrokeWidth = actualBorderWidth; switch (borderSide) { case CssSide.Top: g.DrawLine((float)Math.Ceiling(rect.Left), rect.Top + box.ActualBorderTopWidth / 2, rect.Right - 1, rect.Top + box.ActualBorderTopWidth / 2); break; case CssSide.Left: g.DrawLine(rect.Left + box.ActualBorderLeftWidth / 2, (float)Math.Ceiling(rect.Top), rect.Left + box.ActualBorderLeftWidth / 2, (float)Math.Floor(rect.Bottom)); break; case CssSide.Bottom: g.DrawLine((float)Math.Ceiling(rect.Left), rect.Bottom - box.ActualBorderBottomWidth / 2, rect.Right - 1, rect.Bottom - box.ActualBorderBottomWidth / 2); break; case CssSide.Right: g.DrawLine(rect.Right - box.ActualBorderRightWidth / 2, (float)Math.Ceiling(rect.Top), rect.Right - box.ActualBorderRightWidth / 2, (float)Math.Floor(rect.Bottom)); break; } g.StrokeWidth = prevStrokeW; g.StrokeColor = prevColor; } break; } } }
/// <summary> /// Paints the background of the box /// </summary> /// <param name="g">the device to draw into</param> /// <param name="rect">the bounding rectangle to draw in</param> /// <param name="isFirst">is it the first rectangle of the element</param> /// <param name="isLast">is it the last rectangle of the element</param> internal void PaintBackground(PaintVisitor p, RectangleF rect, bool isFirst, bool isLast) { //return; //if (this.dbugMark1 > 0) //{ // Console.WriteLine(this.dbugMark1); // if ((this.dbugMark1 % 2) == 0) // { // } // else // { // } //} if (!this.HasVisibleBgColor) { return; } if (rect.Width > 0 && rect.Height > 0) { Brush brush = null; bool dispose = false; if (BackgroundGradient != Color.Transparent) { //use bg gradient brush = LinearGradientBrush.CreateLinearGradientBrush(rect, ActualBackgroundColor, ActualBackgroundGradient, ActualBackgroundGradientAngle); dispose = true; } else if (RenderUtils.IsColorVisible(ActualBackgroundColor)) { brush = new SolidBrush(this.ActualBackgroundColor); dispose = true; } DrawBoard g = p.InnerCanvas; SmoothingMode smooth = g.SmoothingMode; if (brush != null) { // atodo: handle it correctly (tables background) // if (isLast) // rectangle.Width -= ActualWordSpacing + CssUtils.GetWordEndWhitespace(ActualFont); GraphicsPath roundrect = null; bool hasSomeRoundCorner = this.HasSomeRoundCorner; if (hasSomeRoundCorner) { roundrect = RenderUtils.GetRoundRect(rect, ActualCornerNW, ActualCornerNE, ActualCornerSE, ActualCornerSW); } if (!p.AvoidGeometryAntialias && hasSomeRoundCorner) { g.SmoothingMode = SmoothingMode.AntiAlias; } if (roundrect != null) { g.FillPath(brush, roundrect); } else { g.FillRectangle(brush, (float)Math.Ceiling(rect.X), (float)Math.Ceiling(rect.Y), rect.Width, rect.Height); } g.SmoothingMode = smooth; if (roundrect != null) { roundrect.Dispose(); } if (dispose) { brush.Dispose(); } } if (isFirst) { var bgImageBinder = this.BackgroundImageBinder; if (bgImageBinder != null && bgImageBinder.Image != null) { BackgroundImagePaintHelper.DrawBackgroundImage(g, this, bgImageBinder, rect); } } } }
internal static void ReleaseSharedPainter(PaintVisitor p) { p.UnBind(); painterStock.Enqueue(p); }