public void Invalidate(PdnRegion region) { foreach (Rectangle rect in region.GetRegionScansReadOnlyInt()) { Invalidate(rect); } }
/// <summary> /// Renders only the portions of the document that have changed (been Invalidated) since /// the last call to this function. /// </summary> /// <param name="args">Contains information used to control where rendering occurs.</param> /// <returns>true if any rendering was done (the update list was non-empty), false otherwise</returns> public bool Update(RenderArgs dst) { if (disposed) { throw new ObjectDisposedException("Document"); } Rectangle[] updateRects; int updateRectsLength; updateRegion.GetArrayReadOnly(out updateRects, out updateRectsLength); if (updateRectsLength == 0) { return(false); } PdnRegion region = Utility.RectanglesToRegion(updateRects, 0, updateRectsLength); Rectangle[] rectsOriginal = region.GetRegionScansReadOnlyInt(); Rectangle[] rectsToUse; // Special case where we're drawing 1 big rectangle: split it up! // This case happens quite frequently, but we don't want to spend a lot of // time analyzing any other case that is more complicated. if (rectsOriginal.Length == 1 && rectsOriginal[0].Height > 1) { Rectangle[] rectsNew = new Rectangle[Processor.LogicalCpuCount]; Utility.SplitRectangle(rectsOriginal[0], rectsNew); rectsToUse = rectsNew; } else { rectsToUse = rectsOriginal; } int cpuCount = Processor.LogicalCpuCount; for (int i = 0; i < cpuCount; ++i) { int start = (i * rectsToUse.Length) / cpuCount; int end = ((i + 1) * rectsToUse.Length) / cpuCount; UpdateScansContext usc = new UpdateScansContext(this, dst, rectsToUse, start, end - start); if (i == cpuCount - 1) { // Reuse this thread for the last job -- no sense creating a new thread. usc.UpdateScans(usc); } else { threadPool.QueueUserWorkItem(new WaitCallback(usc.UpdateScans), usc); } } this.threadPool.Drain(); Validate(); return(true); }
public void Set(PdnRegion region, bool newValue) { foreach (Rectangle rect in region.GetRegionScansReadOnlyInt()) { Set(rect, newValue); } }
/// <summary> /// Causes the layer to render a given region of interest (roi) to the given destination surface. /// </summary> /// <param name="args">Contains information about which objects to use for rendering</param> /// <param name="roi">The region to be rendered.</param> public void Render(RenderArgs args, PdnRegion roi) { Rectangle roiBounds = roi.GetBoundsInt(); if (!IsInBounds(roiBounds)) { throw new ArgumentOutOfRangeException("roi"); } Rectangle[] rects = roi.GetRegionScansReadOnlyInt(); RenderImpl(args, rects); }
/// <summary> /// Constructs an IrregularSurface by copying the given region-of-interest from an Image. /// </summary> /// <param name="source">The Surface to copy pixels from.</param> /// <param name="roi">Defines the Region from which to copy pixels from the Image.</param> public IrregularSurface(Surface source, PdnRegion roi) { PdnRegion roiClipped = (PdnRegion)roi.Clone(); roiClipped.Intersect(source.Bounds); Rectangle[] rects = roiClipped.GetRegionScansReadOnlyInt(); this.placedSurfaces = new ArrayList(rects.Length); foreach (Rectangle rect in rects) { this.placedSurfaces.Add(new PlacedSurface(source, rect)); } this.region = roiClipped; }
/// <summary> /// Invalidates a portion of the document. The given region is then tagged /// for rerendering during the next call to Update. /// </summary> /// <param name="roi">The region of interest to be invalidated.</param> public void Invalidate(PdnRegion roi) { Dirty = true; foreach (Rectangle rect in roi.GetRegionScansReadOnlyInt()) { rect.Intersect(this.Bounds); updateRegion.Add(rect); if (!rect.IsEmpty) { InvalidateEventArgs iea = new InvalidateEventArgs(rect); OnInvalidated(iea); } } }
protected override void OnPaint(PaintEventArgs e) { if (this.surface != null) { PdnRegion clipRegion = null; Rectangle[] rects = this.realUpdateRects; if (rects == null) { clipRegion = new PdnRegion(e.Graphics.Clip, true); clipRegion.Intersect(e.ClipRectangle); rects = clipRegion.GetRegionScansReadOnlyInt(); } if (this.justPaintWhite > 0) { PdnGraphics.FillRectangles(e.Graphics, Color.White, rects); } else { foreach (Rectangle rect in rects) { if (e.Graphics.IsVisible(rect)) { PaintEventArgs2 e2 = new PaintEventArgs2(e.Graphics, rect); OnPaintImpl(e2); } } } if (clipRegion != null) { clipRegion.Dispose(); clipRegion = null; } } if (this.justPaintWhite > 0) { --this.justPaintWhite; } base.OnPaint(e); }
public static PdnGraphicsPath FromRegion(PdnRegion region) { Rectangle[] scans = region.GetRegionScansReadOnlyInt(); if (scans.Length == 1) { PdnGraphicsPath path = new PdnGraphicsPath(); path.AddRectangle(scans[0]); path.CloseFigure(); return(path); } else { Rectangle bounds = region.GetBoundsInt(); BitVector2D stencil = new BitVector2D(bounds.Width, bounds.Height); for (int i = 0; i < scans.Length; ++i) { Rectangle rect = scans[i]; rect.X -= bounds.X; rect.Y -= bounds.Y; stencil.SetUnchecked(rect, true); } PdnGraphicsPath path = PathFromStencil(stencil, new Rectangle(0, 0, stencil.Width, stencil.Height)); using (Matrix matrix = new Matrix()) { matrix.Reset(); matrix.Translate(bounds.X, bounds.Y); path.Transform(matrix); } return(path); } }
public void Apply(Surface surface, PdnRegion roi) { Apply(surface, roi.GetRegionScansReadOnlyInt()); }
public static PdnGraphicsPath FromRegions(PdnRegion lhs, CombineMode combineMode, PdnRegion rhs) { Rectangle lhsBounds = lhs.GetBoundsInt(); Rectangle rhsBounds = rhs.GetBoundsInt(); int left = Math.Min(lhsBounds.Left, rhsBounds.Left); int top = Math.Min(lhsBounds.Top, rhsBounds.Top); int right = Math.Max(lhsBounds.Right, rhsBounds.Right); int bottom = Math.Max(lhsBounds.Bottom, rhsBounds.Bottom); Rectangle bounds = Rectangle.FromLTRB(left, top, right, bottom); BitVector2D stencil = new BitVector2D(bounds.Width, bounds.Height); Rectangle[] lhsScans = lhs.GetRegionScansReadOnlyInt(); Rectangle[] rhsScans = rhs.GetRegionScansReadOnlyInt(); switch (combineMode) { case CombineMode.Complement: case CombineMode.Intersect: case CombineMode.Replace: throw new ArgumentException("combineMode can't be Complement, Intersect, or Replace"); default: break; } for (int i = 0; i < lhsScans.Length; ++i) { Rectangle rect = lhsScans[i]; rect.X -= bounds.X; rect.Y -= bounds.Y; stencil.SetUnchecked(rect, true); } for (int i = 0; i < rhsScans.Length; ++i) { Rectangle rect = rhsScans[i]; rect.X -= bounds.X; rect.Y -= bounds.Y; switch (combineMode) { case CombineMode.Xor: stencil.InvertUnchecked(rect); break; case CombineMode.Union: stencil.SetUnchecked(rect, true); break; case CombineMode.Exclude: stencil.SetUnchecked(rect, false); break; } } PdnGraphicsPath path = PathFromStencil(stencil, new Rectangle(0, 0, stencil.Width, stencil.Height)); using (Matrix matrix = new Matrix()) { matrix.Reset(); matrix.Translate(bounds.X, bounds.Y); path.Transform(matrix); } return(path); }