public static FromLTRB ( float left, float top, float right, float bottom ) : |
||
left | float | |
top | float | |
right | float | |
bottom | float | |
return |
// Re-calculate the extents of a region private static void CalculateExtents(Region reg) { if (reg.rects.Length == 0) { reg.extent = RectangleF.Empty; return; } /* Since rectStart is the first rectangle in the region, it must have the * smallest top and since rectEnd is the last rectangle in the region, * it must have the largest bottom, because of banding. */ RectangleF rectStart = reg.rects[0]; float left = rectStart.Left; float top = rectStart.Top; RectangleF rectEnd = reg.rects[reg.rects.Length - 1]; float right = rectEnd.Right; float bottom = rectEnd.Bottom; for (int i = 0; i < reg.rects.Length; i++) { RectangleF rect = reg.rects[i]; if (rect.Left < left) { left = rect.Left; } if (rect.Right > right) { right = rect.Right; } } reg.extent = RectangleF.FromLTRB(left, top, right, bottom); }
private static void UnionOverlapBandsMerge(Region reg, ref int r, Region regNew, ref int nextRectangle, float top, float bottom) { bool addNew = false; RectangleF rRect = reg.rects[r]; if (nextRectangle == 0) { addNew = true; } else { RectangleF rect = regNew.rects[nextRectangle - 1]; if (nextRectangle != 0 && rect.Top == top && rect.Bottom == bottom && rect.Right >= rRect.Left) { if (rect.Right < rRect.Right) { regNew.rects[nextRectangle - 1] = RectangleF.FromLTRB(rect.Left, rect.Top, rRect.Right, rect.Bottom); } } else { addNew = true; } } if (addNew) { AllocateSpace(regNew, nextRectangle); regNew.rects[nextRectangle] = RectangleF.FromLTRB(rRect.Left, top, rRect.Right, bottom); nextRectangle++; } r++; }
void Issue119(PaintEventArgs e) { Text = "Issue 119 Demo"; const float z = 80; var m = GetType().Assembly; var t = new OpenFontReader().Read (m.GetManifestResourceStream (Array.Find(m.GetManifestResourceNames(), n => n.EndsWith("otf")))); t.UpdateAllCffGlyphBounds(); var c = t.CalculateScaleToPixelFromPointSize(z); var b = new B(t); var r = new SampleWinForms.GlyphTranslatorToGdiPath(); var g = t.GetGlyphByName("radical.v4"); var o = g.Bounds; var k = R.FromLTRB(o.XMin * c, o.YMin * c, o.XMax * c, o.YMax * c); b.BuildFromGlyph(g, z); b.ReadShapes(r); e.Graphics.ScaleTransform(1, -1); e.Graphics.TranslateTransform(0, -Height / 2.5f); e.Graphics.FillRectangle(Pens.Red.Brush, k.X, k.Y, k.Width, k.Height); e.Graphics.DrawRectangle(Pens.Blue, k.X, k.Y, t.GetHAdvanceWidthFromGlyphIndex(g.GlyphIndex) * c, k.Height); e.Graphics.FillPath(Pens.Black.Brush, r.ResultGraphicsPath); e.Graphics.ResetTransform(); e.Graphics.DrawString("Blue = GetHAdvanceWidthFromGlyphIndex,\nRed = Glyph.Bounds of radical.v4", Font, Pens.Black.Brush, 0, 0); }
public RectangleF ToVisualCoord(Rectangle2 area) { PointF start = ToVisualCoord(area.Start); PointF end = ToVisualCoord(area.End); return(RectangleF.FromLTRB(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Max(start.X, end.X), Math.Max(start.Y, end.Y))); }
/// <summary>Returns a <see cref="T:System.Drawing.RectangleF" /> structure that represents the intersection of two rectangles. If there is no intersection, and empty <see cref="T:System.Drawing.RectangleF" /> is returned.</summary> /// <param name="a">A rectangle to intersect. </param> /// <param name="b">A rectangle to intersect. </param> /// <returns>A third <see cref="T:System.Drawing.RectangleF" /> structure the size of which represents the overlapped area of the two specified rectangles.</returns> // Token: 0x0600074D RID: 1869 RVA: 0x00010DC4 File Offset: 0x0000EFC4 public static RectangleF Intersect(RectangleF a, RectangleF b) { if (!a.IntersectsWithInclusive(b)) { return(RectangleF.Empty); } return(RectangleF.FromLTRB(Math.Max(a.Left, b.Left), Math.Max(a.Top, b.Top), Math.Min(a.Right, b.Right), Math.Min(a.Bottom, b.Bottom))); }
/* Deal with non-overlapping band for subtraction. Any parts from * region 2 we discard. Anything from region 1 we add to the region. */ private static void SubtractNonOverlapBands(Region regNew, ref int nextRectangle, Region reg, int r, int rEnd, float top, float bottom) { while (r != rEnd) { AllocateSpace(regNew, nextRectangle); RectangleF rect = reg.rects[r]; regNew.rects[nextRectangle++] = RectangleF.FromLTRB(rect.Left, top, rect.Right, bottom); r++; } }
public RectangleF[] GetRegionScans(Matrix matrix) { //HACK: this is temporary and will not work on transforms with shear. RectangleF[] newRects = new RectangleF[rects.Length]; for (int i = 0; i < newRects.Length; i++) { RectangleF r = rects[i]; float ox, oy, or, ob; matrix.TransformPoint(r.X, r.Y, out ox, out oy); matrix.TransformPoint(r.Right, r.Bottom, out or, out ob); newRects[i] = RectangleF.FromLTRB(ox, oy, or, ob); } return(newRects); }
/* Handle a non-overlapping band for the union operation. Just * Adds the rectangles into the region. Doesn't have to check for * subsumption or anything. * nextRectangle is incremented and the final rectangles overwritten * with the rectangles we're passed. */ private static void UnionNonOverlapBands(Region regNew, ref int nextRectangle, Region reg, int rect, int rectEnd, float top, float bottom) { int nextRect = nextRectangle; while (rect != rectEnd) { AllocateSpace(regNew, nextRectangle); RectangleF curRect = reg.rects[rect]; regNew.rects[nextRect] = RectangleF.FromLTRB(curRect.Left, top, curRect.Right, bottom); nextRectangle += 1; nextRect++; rect++; } }
/// <summary> /// Returns the bounds of the given point cloud. /// </summary> public static RectangleF GetBounds(this PointF[] points) { if (points.Length > 0) { var top = points.Min(p => p.Y); var bottom = points.Max(p => p.Y); var left = points.Min(p => p.X); var right = points.Max(p => p.X); return(RectangleF.FromLTRB(left, top, right, bottom)); } else { return(RectangleF.Empty); } }
/// <summary> /// Returns the bounds of the given rectangle cloud. /// </summary> public static RectangleF GetBounds(this IEnumerable <RectangleF> bounds) { var minTopLeft = new Vector2(float.MaxValue, float.MaxValue); var maxBottomRight = new Vector2(float.MinValue, float.MinValue); foreach (var r in bounds) { minTopLeft = Vector2.Min(minTopLeft, new Vector2(r.Left, r.Top)); maxBottomRight = Vector2.Max(maxBottomRight, new Vector2(r.Right, r.Bottom)); } if (minTopLeft.X != float.MaxValue) { return(RectangleF.FromLTRB(minTopLeft.X, minTopLeft.Y, maxBottomRight.X, maxBottomRight.Y)); } return(RectangleF.Empty); }
void Issue120(PaintEventArgs e) { Text = "Issue 120 demo"; const float z = 20; var m = GetType().Assembly; var t = new OpenFontReader().Read (m.GetManifestResourceStream (Array.Find(m.GetManifestResourceNames(), n => n.EndsWith("otf")))); t.UpdateAllCffGlyphBounds(); var c = t.CalculateScaleToPixelFromPointSize(z); var b = new B(t); var r = new SampleWinForms.GlyphTranslatorToGdiPath(); var i = 1; e.Graphics.DrawString("Point size = " + z, Font, Brushes.Black, 0, 0); e.Graphics.ScaleTransform(1, -1); e.Graphics.TranslateTransform(0, -Height / 1.5f); var f = (Action <string>)(n => { var g = t.GetGlyphByName(n); var o = g.Bounds; var k = R.FromLTRB(o.XMin * c, o.YMin * c, o.XMax * c, o.YMax * c); b.BuildFromGlyph(g, z); b.ReadShapes(r); e.Graphics.FillPath(Brushes.Black, r.ResultGraphicsPath); e.Graphics.DrawRectangle(Pens.Blue, k.X, k.Y, k.Width, k.Height); var a = e.Graphics.Save(); e.Graphics.ResetTransform(); e.Graphics.DrawString($"{n} - X: {k.X}, Y: {k.Y}, W: {k.Width}, H: {k.Height}", Font, Brushes.Black, 0, Font.Height * i); i++; e.Graphics.Restore(a); e.Graphics.TranslateTransform(k.Right, 0); }); f("radical"); f("radical.v1"); f("radical.v2"); f("radical.v3"); f("radical.v4"); f("slash.v6"); f("slash.v7"); f("backslash.v6"); f("backslash.v7"); f("fraction.v6"); f("fraction.v7"); }
/// <summary> /// Returns the bounds of the given rectangle cloud. /// </summary> public static RectangleF GetBounds(this IEnumerable <RectangleF> bounds) { var cachedBounds = bounds.ToArray(); if (cachedBounds.Length > 0) { var top = cachedBounds.Min(b => b.Top); var bottom = cachedBounds.Max(b => b.Bottom); var left = cachedBounds.Min(b => b.Left); var right = cachedBounds.Max(b => b.Right); return(RectangleF.FromLTRB(left, top, right, bottom)); } else { return(RectangleF.Empty); } }
/// <summary> /// Returns the bounds of the given point cloud. /// </summary> public static RectangleF GetBounds(this IEnumerable <PointF> points) { var cachedPoints = points.ToArray(); if (cachedPoints.Length > 0) { var top = cachedPoints.Min(p => p.Y); var bottom = cachedPoints.Max(p => p.Y); var left = cachedPoints.Min(p => p.X); var right = cachedPoints.Max(p => p.X); return(RectangleF.FromLTRB(left, top, right, bottom)); } else { return(RectangleF.Empty); } }
/// <summary> /// Returns the bounds of the given point cloud. /// </summary> public static RectangleF GetBounds(this IEnumerable <PointF> points) { var min = new Vector2(float.MaxValue, float.MaxValue); var max = new Vector2(float.MinValue, float.MinValue); foreach (var p in points) { var v = new Vector2(p.X, p.Y); min = Vector2.Min(min, v); max = Vector2.Max(max, v); } if (min.X != float.MaxValue) { return(RectangleF.FromLTRB(min.X, min.Y, max.X, max.Y)); } return(RectangleF.Empty); }
/* Handle an overlapping band for REGION_Intersect. * Rectangles may be added to the region. */ private static void IntersectOverlapBands(Region regNew, ref int nextRectangle, Region reg1, int r1, int r1End, Region reg2, int r2, int r2End, float top, float bottom) { float left, right; while (r1 != r1End && r2 != r2End) { RectangleF rect1 = reg1.rects[r1]; RectangleF rect2 = reg2.rects[r2]; left = Math_Max(rect1.Left, rect2.Left); right = Math_Min(rect1.Right, rect2.Right); /* * If there's any overlap between the two rectangles, add that * overlap to the new region. * There's no need to check for subsumption because the only way * such a need could arise is if some region has two rectangles * right next to each other. Since that should never happen... */ if (left < right) { AllocateSpace(regNew, nextRectangle); regNew.rects[nextRectangle++] = RectangleF.FromLTRB(left, top, right, bottom); } /* * Need to advance the pointers. Shift the one that extends * to the right the least, since the other still has a chance to * overlap with that region's next rectangle, if you see what I mean. */ if (rect1.Right < rect2.Right) { r1++; } else if (rect2.Right < rect1.Right) { r2++; } else { r1++; r2++; } } }
protected override void OnPaintSelection(PaintEventArgs e) { var texture = VisibleTexture; // Determine relevant area Vector2 start = FromVisualCoord(new PointF()); Vector2 end = FromVisualCoord(new PointF() + ClientSize); start = Vector2.Min(texture.Image.Size, Vector2.Max(new Vector2(0), start)); end = Vector2.Min(texture.Image.Size, Vector2.Max(new Vector2(0), end)); int bumpTileStartX = (int)Math.Floor(start.X / LevelTexture.BumpMappingGranularity); int bumpTileStartY = (int)Math.Floor(start.Y / LevelTexture.BumpMappingGranularity); int bumpTileEndX = (int)Math.Ceiling(end.X / LevelTexture.BumpMappingGranularity); int bumpTileEndY = (int)Math.Ceiling(end.Y / LevelTexture.BumpMappingGranularity); // Draw bumpmaps using (Font bumpFont = new Font(Font.FontFamily, _bumpStringSize * _bumpProportion * LevelTexture.BumpMappingGranularity * Math.Min(100, ViewScale))) for (int y = bumpTileStartY; y <= bumpTileEndY; ++y) { for (int x = bumpTileStartX; x <= bumpTileEndX; ++x) { if (x < 0 || x >= texture.BumpMappingWidth || y < 0 || y >= texture.BumpMappingHeight) { continue; } BumpMappingLevel bump = texture.GetBumpMapLevel(x, y); Vector2 tileStartTexCoord = new Vector2(x, y) * LevelTexture.BumpMappingGranularity; PointF tileStart = ToVisualCoord(tileStartTexCoord); PointF tileEnd = ToVisualCoord(tileStartTexCoord + new Vector2(LevelTexture.BumpMappingGranularity)); PointF descStart = new PointF(tileStart.X, tileStart.Y * _bumpProportion + tileEnd.Y * (1 - _bumpProportion)); RectangleF descArea = RectangleF.FromLTRB(descStart.X, descStart.Y, tileEnd.X, tileEnd.Y); e.Graphics.FillRectangle(_bumpBrushes[(int)bump], descArea); if (ViewScale > 6) { e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; } e.Graphics.DrawString(bump.ToString(), bumpFont, Brushes.Black, descArea, new StringFormat(StringFormatFlags.NoWrap) { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); RectangleF tileArea = RectangleF.FromLTRB(tileStart.X, tileStart.Y, tileEnd.X, tileEnd.Y); e.Graphics.DrawRectangle(Pens.White, tileArea); } } // Fill covered tiles Vector2 p0 = SelectedTexture.TexCoord0 / LevelTexture.FootStepSoundGranularity; Vector2 p1 = SelectedTexture.TexCoord1 / LevelTexture.FootStepSoundGranularity; Vector2 p2 = SelectedTexture.TexCoord2 / LevelTexture.FootStepSoundGranularity; Vector2 p3 = SelectedTexture.TexCoord3 / LevelTexture.FootStepSoundGranularity; int xMin = (int)Math.Min(Math.Min(Math.Min(p0.X, p1.X), p2.X), p3.X); int xMax = (int)Math.Max(Math.Max(Math.Max(p0.X, p1.X), p2.X), p3.X); int yMin = (int)Math.Min(Math.Min(Math.Min(p0.Y, p1.Y), p2.Y), p3.Y); int yMax = (int)Math.Max(Math.Max(Math.Max(p0.Y, p1.Y), p2.Y), p3.Y); PointF selStart = ToVisualCoord(new Vector2(xMin, yMin) * LevelTexture.FootStepSoundGranularity); PointF selEnd = ToVisualCoord(new Vector2(xMax, yMax) * LevelTexture.FootStepSoundGranularity); RectangleF selArea = RectangleF.FromLTRB(selStart.X, selStart.Y, selEnd.X, selEnd.Y); e.Graphics.FillRectangle(_coverBrush, selArea); base.OnPaintSelection(e); }
/* Attempt to merge the rects in the current band with those in the * previous one. Used only by RegionOperation. * Results: The new index for the previous band. * * If coalescing takes place: * - rectangles in the previous band will have their bottom fields * altered. * - nextRectangle will be decreased. */ private static int CoalesceRegion(Region reg, ref int nextRectangle, int prevStart, /* Index of start of previous band */ int curStart /* Index of start of current band */ ) { int curNumRects; /* Number of rectangles in current band */ int regEnd = nextRectangle; /* End of region */ int prevRect = prevStart; /* Current rect in previous band */ int prevNumRects = curStart - prevStart; /* Number of rectangles in previous band */ int curRect = curStart; /* Current rect in current band */ float bandtop = reg.rects[curRect].Top; /* top coordinate for current band */ /* Figure out how many rectangles are in the current band. Have to do * this because multiple bands could have been added in REGION_RegionOp * at the end when one region has been exhausted. */ for (curNumRects = 0; curRect != regEnd && reg.rects[curRect].Top == bandtop; curNumRects++) { curRect++; } if (curRect != regEnd) { /* * If more than one band was added, we have to find the start * of the last band added so the next coalescing job can start * at the right place... (given when multiple bands are added, * this may be pointless -- see above). */ regEnd--; while (reg.rects[regEnd - 1].Top == reg.rects[regEnd].Top) { regEnd--; } curStart = regEnd; regEnd = nextRectangle; } if (curNumRects == prevNumRects && curNumRects != 0) { curRect -= curNumRects; /* * The bands may only be coalesced if the bottom of the previous * matches the top scanline of the current. */ if (reg.rects[prevRect].Bottom == reg.rects[curRect].Top) { /* * Make sure the bands have rects in the same places. This * assumes that rects have been added in such a way that they * cover the most area possible. I.e. two rects in a band must * have some horizontal space between them. */ do { if (reg.rects[prevRect].Left != reg.rects[curRect].Left || reg.rects[prevRect].Right != reg.rects[curRect].Right) { /* * The bands don't line up so they can't be coalesced. */ return(curStart); } prevRect++; curRect++; prevNumRects -= 1; }while (prevNumRects != 0); nextRectangle -= curNumRects; curRect -= curNumRects; prevRect -= curNumRects; /* * The bands may be merged, so set the bottom of each rect * in the previous band to that of the corresponding rect in * the current band. */ do { RectangleF previousRectangle = reg.rects[prevRect]; reg.rects[prevRect] = RectangleF.FromLTRB(previousRectangle.Left, previousRectangle.Top, previousRectangle.Right, reg.rects[curRect].Bottom); prevRect++; curRect++; curNumRects -= 1; }while (curNumRects != 0); /* * If only one band was added to the region, we have to backup * curStart to the start of the previous band. * * If more than one band was added to the region, copy the * other bands down. The assumption here is that the other bands * came from the same region as the current one and no further * coalescing can be done on them since it's all been done * already... curStart is already in the right place. */ if (curRect == regEnd) { curStart = prevStart; } else { do { reg.rects[prevRect++] = reg.rects[curRect++]; }while (curRect != regEnd); } } } return(curStart); }
public IEnumerable <RectangleF> GetRegionScans(Matrix dcTransform) { return(new RectangleF[] { RectangleF.FromLTRB(base.Bounds.Left, base.Bounds.Top, base.Bounds.Right, base.Bounds.Bottom) }); }
/* Overlapping band subtraction. x1 is the left-most point not yet checked */ private static void SubtractOverlapBands(Region regNew, ref int nextRectangle, Region reg1, int r1, int r1End, Region reg2, int r2, int r2End, float top, float bottom) { float left = reg1.rects[r1].Left; RectangleF rect1 = Rectangle.Empty; RectangleF rect2 = Rectangle.Empty; if (r1 != r1End) { rect1 = reg1.rects[r1]; } if (r2 != r2End) { rect2 = reg2.rects[r2]; } while (r1 != r1End && r2 != r2End) { if (rect2.Right <= left) { // Subtrahend missed the boat: go to next subtrahend. r2++; if (r2 != r2End) { rect2 = reg2.rects[r2]; } } else if (rect2.Left <= left) { // Subtrahend preceeds minuend: nuke left edge of minuend. left = rect2.Right; if (left >= rect1.Right) { /* Minuend completely covered: advance to next minuend and * reset left fence to edge of new minuend. */ r1++; if (r1 != r1End) { rect1 = reg1.rects[r1]; left = rect1.Left; } } else { /* Subtrahend now used up since it doesn't extend beyond * minuend */ r2++; if (r2 != r2End) { rect2 = reg2.rects[r2]; } } } else if (rect2.Left < rect1.Right) { /* Left part of subtrahend covers part of minuend: add uncovered * part of minuend to region and skip to next subtrahend. */ AllocateSpace(regNew, nextRectangle); regNew.rects[nextRectangle++] = RectangleF.FromLTRB(left, top, rect2.Left, bottom); left = rect2.Right; if (left >= rect1.Right) { // Minuend used up: advance to new... r1++; if (r1 != r1End) { rect1 = reg1.rects[r1]; left = rect1.Left; } } else { // Subtrahend used up r2++; if (r2 != r2End) { rect2 = reg2.rects[r2]; } } } else { // Minuend used up: add any remaining piece before advancing. if (rect1.Right > left) { AllocateSpace(regNew, nextRectangle); regNew.rects[nextRectangle++] = RectangleF.FromLTRB(left, top, rect1.Right, bottom); } r1++; if (r1 != r1End) { rect1 = reg1.rects[r1]; left = rect1.Left; } } } // Add remaining minuend rectangles to region. while (r1 != r1End) { AllocateSpace(regNew, nextRectangle); regNew.rects[nextRectangle++] = RectangleF.FromLTRB(left, top, rect1.Right, bottom); r1++; if (r1 != r1End) { rect1 = reg1.rects[r1]; left = rect1.Left; } } }
protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.IntersectClip(new RectangleF(new PointF(), ClientSize - new SizeF(_scrollSizeTotal, _scrollSizeTotal))); // Only proceed if texture is actually available if (VisibleTexture?.IsAvailable ?? false) { PointF drawStart = ToVisualCoord(new Vector2(0.0f, 0.0f)); PointF drawEnd = ToVisualCoord(new Vector2(VisibleTexture.Image.Width, VisibleTexture.Image.Height)); RectangleF drawArea = RectangleF.FromLTRB(drawStart.X, drawStart.Y, drawEnd.X, drawEnd.Y); // Draw background using (var textureBrush = new TextureBrush(Properties.Resources.misc_TransparentBackground)) e.Graphics.FillRectangle(textureBrush, drawArea); // Switch interpolation based on current view scale if (ViewScale >= 1.0) { e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; } else { e.Graphics.InterpolationMode = InterpolationMode.Bicubic; } // Draw image VisibleTexture.Image.GetTempSystemDrawingBitmap(tempBitmap => { // System.Drawing being silly, it draws the first row of pixels only half, so everything would be shifted // To work around it, we have to do some silly coodinate changes :/ e.Graphics.DrawImage(tempBitmap, new RectangleF(drawArea.X, drawArea.Y, drawArea.Width + 0.5f * ViewScale, drawArea.Height + 0.5f * ViewScale), new RectangleF(-0.5f, -0.5f, tempBitmap.Width + 0.5f, tempBitmap.Height + 0.5f), GraphicsUnit.Pixel); }); OnPaintSelection(e); } else { string notifyMessage; if (string.IsNullOrEmpty(VisibleTexture?.Path)) { notifyMessage = "Click here to load new texture file."; } else { string fileName = PathC.GetFileNameWithoutExtensionTry(VisibleTexture?.Path) ?? ""; if (PathC.IsFileNotFoundException(VisibleTexture?.LoadException)) { notifyMessage = "Texture file '" + fileName + "' was not found!\n"; } else { notifyMessage = "Unable to load texture from file '" + fileName + "'.\n"; } notifyMessage += "Click here to choose a replacement.\n\n"; notifyMessage += "Path: " + (_editor.Level.Settings.MakeAbsolute(VisibleTexture?.Path) ?? ""); } RectangleF textArea = ClientRectangle; textArea.Size -= new SizeF(_scrollSizeTotal, _scrollSizeTotal); using (var b = new SolidBrush(Colors.DisabledText)) e.Graphics.DrawString(notifyMessage, Font, b, textArea, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); } // Draw borders using (Pen pen = new Pen(Colors.GreySelection, 1.0f)) e.Graphics.DrawRectangle(pen, new RectangleF(0, 0, ClientSize.Width - _scrollSizeTotal - 1, ClientSize.Height - _scrollSizeTotal - 1)); }
protected override void OnPaintSelection(PaintEventArgs e) { var texture = VisibleTexture; // Determine relevant area Vector2 start = FromVisualCoord(new PointF()); Vector2 end = FromVisualCoord(new PointF() + ClientSize); start = Vector2.Min(texture.Image.Size, Vector2.Max(new Vector2(0), start)); end = Vector2.Min(texture.Image.Size, Vector2.Max(new Vector2(0), end)); int soundTileStartX = (int)Math.Floor(start.X / LevelTexture.FootStepSoundGranularity); int soundTileStartY = (int)Math.Floor(start.Y / LevelTexture.FootStepSoundGranularity); int soundTileEndX = (int)Math.Ceiling(end.X / LevelTexture.FootStepSoundGranularity); int soundTileEndY = (int)Math.Ceiling(end.Y / LevelTexture.FootStepSoundGranularity); // Draw texture sounds using (Font textureSoundFont = new Font(Font.FontFamily, _textureSoundStringSize * _textureSoundProportion * LevelTexture.FootStepSoundGranularity * Math.Min(100, ViewScale))) for (int y = soundTileStartY; y <= soundTileEndY; ++y) { for (int x = soundTileStartX; x <= soundTileEndX; ++x) { if (x < 0 || x >= texture.FootStepSoundWidth || y < 0 || y >= texture.FootStepSoundHeight) { continue; } TextureFootStepSound sound = texture.GetFootStepSound(x, y); Brush soundBrush = _textureSoundBrushes[(int)sound]; Vector2 tileStartTexCoord = new Vector2(x, y) * LevelTexture.FootStepSoundGranularity; PointF tileStart = ToVisualCoord(tileStartTexCoord); PointF tileEnd = ToVisualCoord(tileStartTexCoord + new Vector2(LevelTexture.FootStepSoundGranularity)); PointF descStart = new PointF(tileStart.X, tileStart.Y * _textureSoundProportion + tileEnd.Y * (1 - _textureSoundProportion)); RectangleF descArea = RectangleF.FromLTRB(descStart.X, descStart.Y, tileEnd.X, tileEnd.Y); e.Graphics.FillRectangle(soundBrush, descArea); if (ViewScale > 6) { e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; } e.Graphics.DrawString(sound.ToString(), textureSoundFont, Brushes.Black, descArea, _textureSoundStringFormat); RectangleF tileArea = RectangleF.FromLTRB(tileStart.X, tileStart.Y, tileEnd.X, tileEnd.Y); e.Graphics.DrawRectangle(Pens.White, tileArea); } } // Fill covered tiles Vector2 p0 = SelectedTexture.TexCoord0 / LevelTexture.FootStepSoundGranularity; Vector2 p1 = SelectedTexture.TexCoord1 / LevelTexture.FootStepSoundGranularity; Vector2 p2 = SelectedTexture.TexCoord2 / LevelTexture.FootStepSoundGranularity; Vector2 p3 = SelectedTexture.TexCoord3 / LevelTexture.FootStepSoundGranularity; int xMin = (int)Math.Min(Math.Min(Math.Min(p0.X, p1.X), p2.X), p3.X); int xMax = (int)Math.Max(Math.Max(Math.Max(p0.X, p1.X), p2.X), p3.X); int yMin = (int)Math.Min(Math.Min(Math.Min(p0.Y, p1.Y), p2.Y), p3.Y); int yMax = (int)Math.Max(Math.Max(Math.Max(p0.Y, p1.Y), p2.Y), p3.Y); PointF selStart = ToVisualCoord(new Vector2(xMin, yMin) * LevelTexture.FootStepSoundGranularity); PointF selEnd = ToVisualCoord(new Vector2(xMax, yMax) * LevelTexture.FootStepSoundGranularity); RectangleF selArea = RectangleF.FromLTRB(selStart.X, selStart.Y, selEnd.X, selEnd.Y); e.Graphics.FillRectangle(_coverBrush, selArea); // TODO: disabled for now /*ConservativeRasterizer.RasterizeQuadUniquely( * SelectedTexture.TexCoord0 / LevelTexture.FootStepSoundGranularity, * SelectedTexture.TexCoord1 / LevelTexture.FootStepSoundGranularity, * SelectedTexture.TexCoord2 / LevelTexture.FootStepSoundGranularity, * SelectedTexture.TexCoord3 / LevelTexture.FootStepSoundGranularity, * (startX, startY, endX, endY) => * { * PointF tileStart = ToVisualCoord(new Vector2(startX, startY) * LevelTexture.FootStepSoundGranularity); * PointF tileEnd = ToVisualCoord(new Vector2(endX, endY) * LevelTexture.FootStepSoundGranularity); * RectangleF tileArea = RectangleF.FromLTRB(tileStart.X, tileStart.Y, tileEnd.X, tileEnd.Y); * e.Graphics.FillRectangle(_coverBrush, tileArea); * });*/ base.OnPaintSelection(e); }
void Issue118(PaintEventArgs e) { Text = "Issue 118 Demo"; const string s = "0123456789"; const float z = 80; const bool f = true; var m = GetType().Assembly; var t = new OpenFontReader().Read (m.GetManifestResourceStream (Array.Find(m.GetManifestResourceNames(), n => n.EndsWith("otf")))); t.UpdateAllCffGlyphBounds(); var c = t.CalculateScaleToPixelFromPointSize(z); var l = new GlyphLayout { Typeface = t }; var q = new GlyphLayout { Typeface = t }; l.Layout(s.ToCharArray(), 0, s.Length); var p = l.ResultUnscaledGlyphPositions; var b = new B(t); var r = new SampleWinForms.GlyphTranslatorToGdiPath(); var h = Pens.Black.Brush; var u = Pens.Blue; var v = Pens.Red; const bool _ = true; var j = true; using (var g = e.Graphics) { if (f) { g.ScaleTransform(1, -1); g.TranslateTransform(0, -Height / 2); } for (var i = 0; i < s.Length; i++, j ^= true) { var o = q.LayoutAndMeasureString(new[] { s[i] }, 0, 1, z); var n = p.GetGlyph(i, out var x, out var y, out var w); var a = g.Save(); var d = t.GetGlyphByIndex(n).Bounds; var k = R.FromLTRB(d.XMin * c, d.YMin * c, d.XMax * c, d.YMax * c); g.TranslateTransform(x * c, y * c); b.Build(s[i], z); b.ReadShapes(r); r.ResultGraphicsPath.CloseFigure(); g.FillPath(h, r.ResultGraphicsPath); if (_ || j) { g.DrawRectangle(u, 0, 0, o.width, o.ascending - o.descending); } if (_ || !j) { g.DrawRectangle(v, k.X, k.Y, k.Width, k.Height); } g.Restore(a); g.TranslateTransform(w * c, 0); } g.ResetTransform(); g.DrawString("Blue = LayoutAndMeasureString, Red = Glyph.Bounds", Font, h, 0, 0); } }
/// <summary>Creates the smallest possible third rectangle that can contain both of two rectangles that form a union.</summary> /// <param name="a">A rectangle to union. </param> /// <param name="b">A rectangle to union. </param> /// <returns>A third <see cref="T:System.Drawing.RectangleF" /> structure that contains both of the two rectangles that form the union.</returns> // Token: 0x0600074F RID: 1871 RVA: 0x00010E48 File Offset: 0x0000F048 public static RectangleF Union(RectangleF a, RectangleF b) { return(RectangleF.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))); }