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); } }
/// <summary> /// Inflate Shared Method /// </summary> /// /// <remarks> /// Produces a new RectangleF by inflating an existing /// RectangleF by the specified coordinate values. /// </remarks> public static RectangleF Inflate(RectangleF rect, float x, float y) { RectangleF ir = new RectangleF(rect.X, rect.Y, rect.Width, rect.Height); ir.Inflate(x, y); return ir; }
/// <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 AddRectangle(RectangleF rectF) { cmds.Add(PathCommand.Rect); points.Add(rectF.X); points.Add(rectF.Y); points.Add(rectF.Width); points.Add(rectF.Height); }
public void AddArc(RectangleF rectF, float startAngle, float sweepAngle) { cmds.Add(PathCommand.Arc); points.Add(rectF.X); points.Add(rectF.Y); points.Add(rectF.Width); points.Add(rectF.Height); points.Add(startAngle);//*** points.Add(sweepAngle);//*** }
/// <summary> /// Ceiling Shared Method /// </summary> /// /// <remarks> /// Produces a Rectangle structure from a RectangleF /// structure by taking the ceiling of the X, Y, Width, /// and Height properties. /// </remarks> public static Rectangle Ceiling(RectangleF value) { int x, y, w, h; checked { x = (int)Math.Ceiling(value.X); y = (int)Math.Ceiling(value.Y); w = (int)Math.Ceiling(value.Width); h = (int)Math.Ceiling(value.Height); } return new Rectangle(x, y, w, h); }
/// <summary> /// Draw the background image of the given box in the given rectangle.<br/> /// Handle background-repeat and background-position values. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="box">the box to draw its background image</param> /// <param name="imageLoadHandler">the handler that loads image to draw</param> /// <param name="rectangle">the rectangle to draw image in</param> public static void DrawBackgroundImage(Canvas g, CssBox box, ImageBinder imageBinder, RectangleF rectangle) { var image = imageBinder.Image; //temporary comment image scale code var imgSize = image.Size; //new Size(imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Width : imageLoadHandler.Rectangle.Width, // imageLoadHandler.Rectangle == Rectangle.Empty ? imageLoadHandler.Image.Height : imageLoadHandler.Rectangle.Height); // get the location by BackgroundPosition value var location = GetLocation(box.BackgroundPositionX, box.BackgroundPositionY, rectangle, imgSize); //var srcRect = imageLoadHandler.Rectangle == Rectangle.Empty // ? new Rectangle(0, 0, imgSize.Width, imgSize.Height) // : new Rectangle(imageLoadHandler.Rectangle.Left, imageLoadHandler.Rectangle.Top, imgSize.Width, imgSize.Height); var srcRect = new Rectangle(0, 0, image.Width, image.Height); // initial image destination rectangle var destRect = new Rectangle(location, imgSize); // need to clip so repeated image will be cut on rectangle var prevClip = g.CurrentClipRect; PixelFarm.Drawing.Rectangle copyRect = new PixelFarm.Drawing.Rectangle( (int)rectangle.X, (int)rectangle.Y, (int)rectangle.Width, (int)rectangle.Height); copyRect.Intersect(prevClip); g.SetClipRect(copyRect); switch (box.BackgroundRepeat) { case CssBackgroundRepeat.NoRepeat: g.DrawImage(image, new RectangleF(location, imgSize), new RectangleF(0, 0, image.Width, image.Height)); break; case CssBackgroundRepeat.RepeatX: DrawRepeatX(g, image, rectangle, srcRect, destRect, imgSize); break; case CssBackgroundRepeat.RepeatY: DrawRepeatY(g, image, rectangle, srcRect, destRect, imgSize); break; default: DrawRepeat(g, image, rectangle, srcRect, destRect, imgSize); break; } g.SetClipRect(prevClip); }
public PixelFarm.Drawing.RectangleF[] GetGlyphPos(char[] buffer, int start, int len, int x, int y) { if (innerGLbmp == null) { innerGLbmp = PixelFarm.Drawing.DrawingGL.GLBitmapTextureHelper.CreateBitmapTexture(this.textBoardBmp); } //create reference bmp float curX = x; float curY = y; //create destAndSrcArray PixelFarm.Drawing.RectangleF[] destAndSrcPairs = new PixelFarm.Drawing.RectangleF[len * 2]; int pp = 0; int endAt = start + len; for (int i = start; i < endAt; ++i) { //find map glyph PixelFarm.Drawing.RectangleF found; if (charMap.TryGetValue(buffer[i], out found)) { //dest destAndSrcPairs[pp] = new PixelFarm.Drawing.RectangleF(curX, curY, found.Width, found.Height); //src destAndSrcPairs[pp + 1] = found; curX += found.Width; } else { //draw missing glyph } pp += 2; } return(destAndSrcPairs); }
///// <summary> ///// Get cached solid brush instance for the given color. ///// </summary> ///// <param name="color">the color to get brush for</param> ///// <returns>brush instance</returns> //public static Brush GetSolidBrush(Color color) //{ // if (color == Color.White) // { // return Brushes.White; // } // else if (color == Color.Black) // { // return Brushes.Black; // } // else if (!IsColorVisible(color)) // { // return Brushes.Transparent; // } // else // { // Brush brush; // if (!_brushesCache.TryGetValue(color, out brush)) // { // _brushesCache[color] = brush = CurrentGraphicPlatform.CreateSolidBrush(color); // } // return brush; // } //} ///// <summary> ///// Get cached pen instance for the given color. ///// </summary> ///// <param name="color">the color to get pen for</param> ///// <returns>pen instance</returns> //public static Pen GetPen(GraphicPlatform p, Color color) //{ // Pen pen; // if (!_penCache.TryGetValue(color, out pen)) // { // pen = p.CreateSolidPen(color); // _penCache[color] = pen; // } // else // { // pen.Width = 1; // } // return pen; //} /// <summary> /// Draw image loading icon. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="r">the rectangle to draw icon in</param> public static void DrawImageLoadingIcon(Canvas g, RectangleF r) { g.DrawRectangle(Color.LightGray, r.Left + 3, r.Top + 3, 13, 14); var image = GetLoadImage(); g.DrawImage(image, new RectangleF(r.Left + 4, r.Top + 4, image.Width, image.Height)); }
/// <summary> /// Draw image failed to load icon. /// </summary> /// <param name="g">the device to draw into</param> /// <param name="r">the rectangle to draw icon in</param> public static void DrawImageErrorIcon(Canvas g, RectangleF r) { g.DrawRectangle(Color.LightGray, r.Left + 2, r.Top + 2, 15, 15); var image = GetErrorImage(); g.DrawImage(image, new RectangleF(r.Left + 3, r.Top + 3, image.Width, image.Height)); }
Rectangle GetSelectionRectArea() { if (selectedLines != null) { int j = selectedLines.Count; //first if (j > 0) { CssBox ownerCssBox = null; CssBox rootbox = null; float fx1 = 0, fy1 = 0; //left top RectangleF selArea = RectangleF.Empty; //if (j ==1) //{ //} for (int i = 0; i < j; ++i) { var line = selectedLines[i]; if (line.OwnerBox != ownerCssBox) { ownerCssBox = line.OwnerBox; rootbox = ownerCssBox.GetGlobalLocationRelativeToRoot(out fx1, out fy1); } if (i == 0) { selArea = new RectangleF(fx1, fy1 + line.CachedLineTop, line.CachedLineContentWidth, line.CacheLineHeight); } else { selArea = RectangleF.Union(selArea, new RectangleF(fx1, fy1 + line.CachedLineTop, line.CachedLineContentWidth, line.CacheLineHeight)); } } //if want to debug then send a big rect //Console.WriteLine(new Rectangle((int)selArea.X, (int)selArea.Y, (int)selArea.Width, (int)selArea.Height).ToString()); //return new Rectangle(0, 0, 800, 600); return new Rectangle((int)selArea.X, (int)selArea.Y, (int)selArea.Width, (int)selArea.Height); } } return Rectangle.Empty; }
public void DrawImage(GLBitmap bmp, PixelFarm.Drawing.RectangleF srcRect, float x, float y, float w, float h) { unsafe { var prevColor = this.strokeColor; this.StrokeColor = PixelFarm.Drawing.Color.White; //texture source coord 1= 100% of original width float *arr = stackalloc float[8]; float fullsrcW = bmp.Width; float fullsrcH = bmp.Height; if (this.canvasOrientation == Drawing.CanvasOrientation.LeftTop) { if (!bmp.IsInvert) { ////arr[0] = 0; arr[1] = 0; arr[0] = srcRect.Left / fullsrcW; arr[1] = (srcRect.Top + srcRect.Height) / fullsrcH; //arr[2] = 1; arr[3] = 0; arr[2] = srcRect.Right / fullsrcW; arr[3] = (srcRect.Top + srcRect.Height) / fullsrcH; //arr[4] = 1; arr[5] = 1; arr[4] = srcRect.Right / fullsrcW; arr[5] = srcRect.Top / fullsrcH; //arr[6] = 0; arr[7] = 1; arr[6] = srcRect.Left / fullsrcW; arr[7] = srcRect.Top / fullsrcH; } else { arr[0] = srcRect.Left / fullsrcW; arr[1] = srcRect.Top / fullsrcH; //arr[2] = 1; arr[3] = 1; arr[2] = srcRect.Right / fullsrcW; arr[3] = srcRect.Top / fullsrcH; //arr[4] = 1; arr[5] = 0; arr[4] = srcRect.Right / fullsrcW; arr[5] = srcRect.Bottom / fullsrcH; //arr[6] = 0; arr[7] = 0; arr[6] = srcRect.Left / fullsrcW; arr[7] = srcRect.Bottom / fullsrcH; } } else { if (bmp.IsInvert) { ////arr[0] = 0; arr[1] = 0; arr[0] = srcRect.Left / fullsrcW; arr[1] = (srcRect.Top + srcRect.Height) / fullsrcH; //arr[2] = 1; arr[3] = 0; arr[2] = srcRect.Right / fullsrcW; arr[3] = (srcRect.Top + srcRect.Height) / fullsrcH; //arr[4] = 1; arr[5] = 1; arr[4] = srcRect.Right / fullsrcW; arr[5] = srcRect.Top / fullsrcH; //arr[6] = 0; arr[7] = 1; arr[6] = srcRect.Left / fullsrcW; arr[7] = srcRect.Top / fullsrcH; } else { arr[0] = srcRect.Left / fullsrcW; arr[1] = srcRect.Top / fullsrcH; //arr[2] = 1; arr[3] = 1; arr[2] = srcRect.Right / fullsrcW; arr[3] = srcRect.Top / fullsrcH; //arr[4] = 1; arr[5] = 0; arr[4] = srcRect.Right / fullsrcW; arr[5] = srcRect.Bottom / fullsrcH; //arr[6] = 0; arr[7] = 0; arr[6] = srcRect.Left / fullsrcW; arr[7] = srcRect.Bottom / fullsrcH; } } GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, GetTextureId(bmp)); GL.EnableClientState(ArrayCap.TextureCoordArray); //*** GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, (IntPtr)arr); //------------------------------------------ //fill rect with texture FillRectWithTexture(x, y, w, h); GL.DisableClientState(ArrayCap.TextureCoordArray); GL.Disable(EnableCap.Texture2D); this.StrokeColor = prevColor; } }
/// <summary> /// Contains Method /// </summary> /// /// <remarks> /// Checks if a RectangleF lies entirely within this /// RectangleF. /// </remarks> public bool Contains(RectangleF rect) { return X <= rect.X && Right >= rect.Right && Y <= rect.Y && Bottom >= rect.Bottom; }
/// <summary> /// Contains Method /// </summary> /// /// <remarks> /// Checks if a RectangleF lies entirely within this /// RectangleF. /// </remarks> public bool Contains(RectangleF rect) { return(X <= rect.X && Right >= rect.Right && Y <= rect.Y && Bottom >= rect.Bottom); }
/// <summary> /// IntersectsWith Method /// </summary> /// /// <remarks> /// Checks if a RectangleF intersects with this one. /// </remarks> public bool IntersectsWith(RectangleF rect) { return(!((Left >= rect.Right) || (Right <= rect.Left) || (Top >= rect.Bottom) || (Bottom <= rect.Top))); }
private bool IntersectsWithInclusive(RectangleF r) { return !((Left > r.Right) || (Right < r.Left) || (Top > r.Bottom) || (Bottom < r.Top)); }
/// <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 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 }
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 }
public override void Paint(PaintVisitor p, RectangleF r) { var updateArea = new Rectangle((int)r.Left, (int)r.Top, (int)r.Width, (int)r.Height); int x = (int)updateArea.Left; int y = (int)updateArea.Top; var canvasPage = p.InnerCanvas; canvasPage.OffsetCanvasOrigin(x, y); updateArea.Offset(-x, -y); externalRun.RenderElement.DrawToThisCanvas(canvasPage, updateArea); canvasPage.OffsetCanvasOrigin(-x, -y); }
/// <summary> /// Intersect Method /// </summary> /// /// <remarks> /// Replaces the RectangleF with the intersection of itself /// and another RectangleF. /// </remarks> public void Intersect(RectangleF rect) { this = RectangleF.Intersect(this, rect); }
/// <summary> /// Creates a rounded rectangle using the specified corner radius /// </summary> /// <param name="rect">Rectangle to round</param> /// <param name="nwRadius">Radius of the north east corner</param> /// <param name="neRadius">Radius of the north west corner</param> /// <param name="seRadius">Radius of the south east corner</param> /// <param name="swRadius">Radius of the south west corner</param> /// <returns>GraphicsPath with the lines of the rounded rectangle ready to be painted</returns> public static GraphicsPath GetRoundRect(RectangleF rect, float nwRadius, float neRadius, float seRadius, float swRadius) { // NW-----NE // | | // | | // SW-----SE var path = new GraphicsPath(); nwRadius *= 2; neRadius *= 2; seRadius *= 2; swRadius *= 2; //NW ---- NE path.AddLine(rect.X + nwRadius, rect.Y, rect.Right - neRadius, rect.Y); //NE Arc if (neRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Right - neRadius, rect.Top, rect.Right, rect.Top + neRadius), -90, 90); } // NE // | // SE path.AddLine(rect.Right, rect.Top + neRadius, rect.Right, rect.Bottom - seRadius); //SE Arc if (seRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Right - seRadius, rect.Bottom - seRadius, rect.Right, rect.Bottom), 0, 90); } // SW --- SE path.AddLine(rect.Right - seRadius, rect.Bottom, rect.Left + swRadius, rect.Bottom); //SW Arc if (swRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Left, rect.Bottom - swRadius, rect.Left + swRadius, rect.Bottom), 90, 90); } // NW // | // SW path.AddLine(rect.Left, rect.Bottom - swRadius, rect.Left, rect.Top + nwRadius); //NW Arc if (nwRadius > 0f) { path.AddArc( RectangleF.FromLTRB(rect.Left, rect.Top, rect.Left + nwRadius, rect.Top + nwRadius), 180, 90); } path.CloseFigure(); return path; }
/// <summary> /// Truncate Shared Method /// </summary> /// /// <remarks> /// Produces a Rectangle structure from a RectangleF by /// truncating the X, Y, Width, and Height properties. /// </remarks> // LAMESPEC: Should this be floor, or a pure cast to int? public static Rectangle Truncate(RectangleF value) { int x, y, w, h; checked { x = (int)value.X; y = (int)value.Y; w = (int)value.Width; h = (int)value.Height; } return new Rectangle(x, y, w, h); }
private bool IntersectsWithInclusive(RectangleF r) { return(!((Left > r.Right) || (Right < r.Left) || (Top > r.Bottom) || (Bottom < r.Top))); }
/// <summary> /// IntersectsWith Method /// </summary> /// /// <remarks> /// Checks if a RectangleF intersects with this one. /// </remarks> public bool IntersectsWith(RectangleF rect) { return !((Left >= rect.Right) || (Right <= rect.Left) || (Top >= rect.Bottom) || (Bottom <= rect.Top)); }
void dbugAddToProperContainer(CssBox box) { var rectChild = new RectangleF(box.LocalX, box.LocalY, box.InnerContentWidth, box.InnerContentHeight); CssBox parent = box.ParentBox; bool found = false; while (parent != null) { var rectParent = new RectangleF(0, 0, parent.VisualWidth, parent.VisualHeight); if (rectParent.Contains(rectChild)) { found = true; //add to here float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; parent.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); parent.AppendToAbsoluteLayer(box); break; } else { rectChild.Offset(parent.LocalX, parent.LocalY); parent = parent.ParentBox; } } if (!found) { //add to root top float bfx, bfy; box.GetGlobalLocation(out bfx, out bfy); float rfx, rfy; this._rootBox.GetGlobalLocation(out rfx, out rfy); //diff float nx = bfx - rfx; float ny = bfy - rfy; box.SetLocation(nx, ny); this._rootBox.AppendToAbsoluteLayer(box); } }
internal void PaintDecoration(Canvas g, RectangleF rectangle, bool isFirst, bool isLast) { float y = 0f; switch (this.TextDecoration) { default: return; case Css.CssTextDecoration.Underline: { //TODO: correct this ... //var h = g.MeasureString(" ", ActualFont).Height; //float desc = FontsUtils.GetDescentPx(ActualFont); //y = (float)Math.Round(rectangle.Top + h - desc + 0.5); RequestFont afont = ResolvedFont; //PixelFarm.Drawing.Fonts.ActualFont ff = afont.ActualFont; var h = afont.SizeInPixels; float desc = (float)afont.DescentInPixels;// fontInfo.DescentPx; y = (float)Math.Round(rectangle.Top + h - desc); } break; case Css.CssTextDecoration.LineThrough: { y = rectangle.Top + rectangle.Height / 2f; } break; case Css.CssTextDecoration.Overline: { y = rectangle.Top; } break; } //y -= ActualPaddingBottom - ActualBorderBottomWidth; y -= (ActualPaddingBottom + ActualBorderBottomWidth); float x1 = rectangle.X; if (isFirst) { x1 += ActualPaddingLeft + ActualBorderLeftWidth; } float x2 = rectangle.Right; if (isLast) { x2 -= ActualPaddingRight + ActualBorderRightWidth; } var prevColor = g.StrokeColor; g.StrokeColor = ActualColor; g.DrawLine(x1, y, x2, y); g.StrokeColor = prevColor; }
/// <summary> /// Set rectangle for inset/outset border as it need diagonal connection to other borders. /// </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> /// <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> /// <returns>Beveled border path, null if there is no rounded corners</returns> static void SetInOutsetRectanglePoints(CssSide border, CssBox b, RectangleF r, bool isLineStart, bool isLineEnd, PointF[] _borderPts) { switch (border) { case CssSide.Top: _borderPts[0] = new PointF(r.Left, r.Top); _borderPts[1] = new PointF(r.Right, r.Top); _borderPts[2] = new PointF(r.Right, r.Top + b.ActualBorderTopWidth); _borderPts[3] = new PointF(r.Left, r.Top + b.ActualBorderTopWidth); if (isLineEnd) _borderPts[2].X -= b.ActualBorderRightWidth; if (isLineStart) _borderPts[3].X += b.ActualBorderLeftWidth; break; case CssSide.Right: _borderPts[0] = new PointF(r.Right - b.ActualBorderRightWidth, r.Top + b.ActualBorderTopWidth); _borderPts[1] = new PointF(r.Right, r.Top); _borderPts[2] = new PointF(r.Right, r.Bottom); _borderPts[3] = new PointF(r.Right - b.ActualBorderRightWidth, r.Bottom - b.ActualBorderBottomWidth); break; case CssSide.Bottom: _borderPts[0] = new PointF(r.Left, r.Bottom - b.ActualBorderBottomWidth); _borderPts[1] = new PointF(r.Right, r.Bottom - b.ActualBorderBottomWidth); _borderPts[2] = new PointF(r.Right, r.Bottom); _borderPts[3] = new PointF(r.Left, r.Bottom); if (isLineStart) _borderPts[0].X += b.ActualBorderLeftWidth; if (isLineEnd) _borderPts[1].X -= b.ActualBorderRightWidth; break; case CssSide.Left: _borderPts[0] = new PointF(r.Left, r.Top); _borderPts[1] = new PointF(r.Left + b.ActualBorderLeftWidth, r.Top + b.ActualBorderTopWidth); _borderPts[2] = new PointF(r.Left + b.ActualBorderLeftWidth, r.Bottom - b.ActualBorderBottomWidth); _borderPts[3] = new PointF(r.Left, r.Bottom); break; } }
/// <summary> /// Union Shared Method /// </summary> /// /// <remarks> /// Produces a new RectangleF from the union of 2 existing /// RectangleFs. /// </remarks> public static RectangleF Union(RectangleF a, RectangleF b) { return FromLTRB(Math.Min(a.Left, b.Left), Math.Min(a.Top, b.Top), Math.Max(a.Right, b.Right), Math.Max(a.Bottom, b.Bottom)); }
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> /// 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; }
/// <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); } } } }
public static void DrawBorder(CssSide border, PointF[] borderPts, Canvas g, CssBox box, Color solidColor, RectangleF rectangle) { SetInOutsetRectanglePoints(border, box, rectangle, true, true, borderPts); g.FillPolygon(solidColor, borderPts); }
public virtual void Paint(PaintVisitor p, RectangleF r) { }
public Figure(float[] coordXYs, PixelFarm.Drawing.RectangleF bounds) { this.coordXYs = coordXYs; _bounds = bounds; _hasBounds = true; }
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 }