public DrawCallColor(Color color, Texture fontTexture, Rectangle targetRect, Rectangle fontSolidRect) { FontTexture = fontTexture; FontSolidRect = fontSolidRect; TargetRect = targetRect; BoxColor = color; }
/// <summary> /// /// </summary> /// <param name="cell">The glyph to be drawn.</param> /// <param name="targetRect">Where on the <see cref="Host.Global.SharedSpriteBatch"/> the glyph should be drawn.</param> /// <param name="font">The font to use when drawing the glyph.</param> /// <param name="drawBackground">When <see langword="true"/>, draws the <see cref="ColoredGlyph.Background"/> color for the glyph; otherwise <see langword="false"/>.</param> public DrawCallCell(SadConsole.ColoredGlyph cell, Rectangle targetRect, IFont font, bool drawBackground) { Font = font; TargetRect = targetRect; Cell = cell; DrawBackground = drawBackground; }
/// <summary> /// Keeps the text view data in sync with this surface. /// </summary> protected virtual void ResetArea() { if (data == null) { return; } if (viewArea.Left + viewArea.Width > data.Width || viewArea.Top + viewArea.Height > data.Height) { throw new ArgumentOutOfRangeException("RenderArea", "Area is out of range of the surface"); } renderArea = new Rectangle(0, 0, viewArea.Width, viewArea.Height); renderRects = new Rectangle[viewArea.Width * viewArea.Height]; cells = new Cell[viewArea.Width * viewArea.Height]; int index = 0; for (int y = 0; y < viewArea.Height; y++) { for (int x = 0; x < viewArea.Width; x++) { renderRects[index] = font.GetRenderRect(x, y); RenderCells[index] = data[(y + viewArea.Top) * data.Width + (x + viewArea.Left)]; index++; } } cells = RenderCells; AbsoluteArea = new Rectangle(0, 0, viewArea.Width * font.Size.X, viewArea.Height * font.Size.Y); }
/// <summary> /// Creates a new surface view from an existing surface. /// </summary> /// <param name="surface">The source cell data.</param> /// <param name="area">The area of the text surface.</param> public TextSurfaceView(ITextSurfaceRendered surface, Rectangle area) : base(area.Width, area.Height, surface.Font) { data = surface; DefaultBackground = surface.DefaultBackground; DefaultForeground = surface.DefaultForeground; base.font = surface.Font; base.width = surface.Width; base.height = surface.Height; this.originalArea = area; this.cells = data.Cells; base.width = area.Width; base.height = area.Height; RenderRects = new Rectangle[area.Width * area.Height]; RenderCells = new Cell[area.Width * area.Height]; int index = 0; for (int y = 0; y < area.Height; y++) { for (int x = 0; x < area.Width; x++) { RenderRects[index] = Font.GetRenderRect(x, y); RenderCells[index] = base.cells[(y + area.Top) * surface.Width + (x + area.Left)]; index++; } } cells = RenderCells; AbsoluteArea = new Rectangle(0, 0, area.Width * Font.Size.X, area.Height * Font.Size.Y); }
/// <summary> /// Builds the <see cref="GlyphIndexRects"/> array based on the current font settings. /// </summary> public void ConfigureRects() { GlyphIndexRects = new Rectangle[Rows * Columns]; for (int i = 0; i < GlyphIndexRects.Length; i++) { var cx = i % Columns; var cy = i / Columns; if (GlyphPadding != 0) { GlyphIndexRects[i] = new Rectangle((cx * GlyphWidth) + ((cx + 1) * GlyphPadding), (cy * GlyphHeight) + ((cy + 1) * GlyphPadding), GlyphWidth, GlyphHeight); } else { GlyphIndexRects[i] = new Rectangle(cx * GlyphWidth, cy * GlyphHeight, GlyphWidth, GlyphHeight); } #if SFML // rects are used differently with SFML GlyphIndexRects[i].Width = GlyphIndexRects[i].Left + GlyphIndexRects[i].Width; GlyphIndexRects[i].Height = GlyphIndexRects[i].Top + GlyphIndexRects[i].Height; #endif } }
/// <summary> /// Creates a new surface view from an existing surface. /// </summary> /// <param name="surface">The source cell data.</param> /// <param name="area">The area of the text surface.</param> public TextSurfaceView(ITextSurfaceRendered surface, Rectangle area) { data = surface; DefaultBackground = surface.DefaultBackground; DefaultForeground = surface.DefaultForeground; font = surface.Font; ViewArea = area; }
/// <summary> /// Creates a serialized object from an existing <see cref="TextSurfaceView"/>. /// </summary> /// <param name="surface">The surface to serialize.</param> public Serialized(TextSurfaceView surfaceView) { Area = surfaceView.originalArea; FontName = surfaceView.font.Name; FontMultiple = surfaceView.font.SizeMultiple; DefaultBackground = surfaceView.DefaultBackground; DefaultForeground = surfaceView.DefaultForeground; Tint = surfaceView.Tint; }
public virtual void Render(SpriteBatch batch, Font font, Rectangle renderArea) { #if SFML batch.DrawCell(CursorRenderCell, renderArea, font.SolidGlyphRectangle, Color.Transparent, font); #elif MONOGAME batch.Draw(font.FontImage, renderArea, font.GlyphIndexRects[font.SolidGlyphIndex], CursorRenderCell.ActualBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.6f); batch.Draw(font.FontImage, renderArea, font.GlyphIndexRects[CursorRenderCell.ActualGlyphIndex], CursorRenderCell.ActualForeground, 0f, Vector2.Zero, SpriteEffects.None, 0.7f); #endif }
public Rectangle GetRenderRect(int x, int y) { Rectangle rect = new Rectangle(x * Size.X, y * Size.Y, Size.X, Size.Y); #if SFML // SFML handles rects for rendering differnetly rect.Width = rect.Left + rect.Width; rect.Height = rect.Top + rect.Height; #endif return(rect); }
/// <summary> /// Resets all of the rects of the animation based on <see cref="UsePixelPositioning"/> and if <see cref="RepositionRects"/> is true. /// </summary> /// <param name="position">The position of the game object.</param> /// <param name="force">When true, always repositions rects.</param> protected void UpdateRects(Point position, bool force = false) { if (repositionRects || force) { var width = Animation.Width; var height = Animation.Height; var font = Animation.Font; Point offset; var rects = new Rectangle[width * height]; if (repositionRects && usePixelPositioning) { offset = position + renderOffset - new Point(animation.Center.X * font.Size.X, animation.Center.Y * font.Size.Y); } else if (repositionRects) { offset = position + renderOffset - animation.Center; offset = new Point(offset.X * font.Size.X, offset.Y * font.Size.Y); } else { offset = new Point(); } #if SFML AbsoluteArea = new Rectangle(offset.X, offset.Y, (width * font.Size.X) + offset.X, (height * font.Size.Y) + offset.Y); #elif MONOGAME AbsoluteArea = new Rectangle(offset.X, offset.Y, width * font.Size.X, height * font.Size.Y); #endif int index = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { #if SFML rects[index] = new Rectangle(x * font.Size.X + offset.X, y * font.Size.Y + offset.Y, font.Size.X + (x * font.Size.X + offset.X), font.Size.Y + (y * font.Size.Y + offset.Y)); #elif MONOGAME rects[index] = new Rectangle(x * font.Size.X + offset.X, y * font.Size.Y + offset.Y, font.Size.X, font.Size.Y); #endif index++; } } RenderRects = rects; } }
/// <summary> /// Draws a single cell using the specified SpriteBatch. /// </summary> /// <param name="batch">Rendering batch.</param> /// <param name="drawingRectangle">Where on the sreen to draw the cell, in pixels.</param> /// <param name="font">Font used to draw the cell.</param> public void Render(SpriteBatch batch, Rectangle drawingRectangle, Font font) { #if SFML batch.DrawCell(this, drawingRectangle, font.SolidGlyphRectangle, Color.Transparent, font); #elif MONOGAME if (ActualBackground != Color.Transparent) { batch.Draw(font.FontImage, drawingRectangle, font.GlyphIndexRects[font.SolidGlyphIndex], ActualBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.3f); } if (ActualForeground != Color.Transparent) { batch.Draw(font.FontImage, drawingRectangle, font.GlyphIndexRects[ActualGlyphIndex], ActualForeground, 0f, Vector2.Zero, ActualSpriteEffect, 0.4f); } #endif }
public virtual void Draw(ITextSurface surface, Rectangle area) { string value = Item.ToString(); if (value.Length < area.Width) { value += new string(' ', area.Width - value.Length); } else if (value.Length > area.Width) { value = value.Substring(0, area.Width); } var editor = new SurfaceEditor(surface); editor.Print(area.Left, area.Top, value, _currentAppearance); _isDirty = false; }
/// <summary> /// Fills the specified area. /// </summary> /// <param name="area">The area to fill.</param> /// <param name="foreground">Foregorund of every cell. If null, skips.</param> /// <param name="background">Foregorund of every cell. If null, skips.</param> /// <param name="glyph">Glyph of every cell. If null, skips.</param> /// <param name="spriteEffect">Sprite effect of every cell. If null, skips.</param> public Cell[] Fill(Rectangle area, Color?foreground, Color?background, int?glyph, SpriteEffects?spriteEffect = null) { // Check for valid rect Rectangle consoleArea = new Rectangle(0, 0, textSurface.Width, textSurface.Height); if (consoleArea.Contains(area)) { var cells = new Cell[consoleArea.Width * consoleArea.Height]; int cellIndex = 0; for (int x = area.Left; x < area.Left + area.Width; x++) { for (int y = area.Top; y < area.Top + area.Height; y++) { Cell cell = textSurface[y * textSurface.Width + x]; if (glyph.HasValue) { cell.GlyphIndex = glyph.Value; } if (background.HasValue) { cell.Background = background.Value; } if (foreground.HasValue) { cell.Foreground = foreground.Value; } if (spriteEffect.HasValue) { cell.SpriteEffect = spriteEffect.Value; } cells[cellIndex] = cell; cellIndex++; } } return(cells); } return(new Cell[] { }); }
/// <summary> /// Keeps the text view data in sync with this surface. /// </summary> protected virtual void ResetArea() { RenderRects = new Rectangle[area.Width * area.Height]; RenderCells = new Cell[area.Width * area.Height]; int index = 0; for (int y = 0; y < area.Height; y++) { for (int x = 0; x < area.Width; x++) { RenderRects[index] = font.GetRenderRect(x, y); RenderCells[index] = cells[(y + area.Top) * width + (x + area.Left)]; index++; } } // TODO: Optimization by calculating AbsArea and seeing if it's diff from current, if so, don't create new RenderRects AbsoluteArea = new Rectangle(0, 0, area.Width * font.Size.X, area.Height * font.Size.Y); }
public override void Draw(ITextSurface surface, Rectangle area) { if (Item is Color || Item is Tuple <Color, Color, string> ) { var editor = new SurfaceEditor(surface); string value = new string(' ', area.Width - 2); CellAppearance cellLook = _currentAppearance.Clone(); if (Item is Color) { cellLook.Background = (Color)Item; editor.Print(area.Left + 1, area.Top, value, cellLook); } else { cellLook.Foreground = ((Tuple <Color, Color, string>)Item).Item2; cellLook.Background = ((Tuple <Color, Color, string>)Item).Item1; value = ((Tuple <Color, Color, string>)Item).Item3.Align(HorizontalAlignment.Left, area.Width - 2); editor.Print(area.Left + 1, area.Top, value, cellLook); } editor.Print(area.Left, area.Top, " ", _currentAppearance); editor.Print(area.Left + area.Width - 1, area.Top, " ", _currentAppearance); if (IsSelected) { editor.SetGlyph(area.Left, area.Top, 16); editor.SetGlyph(area.Left + area.Width - 1, area.Top, 17); } IsDirty = false; } else { base.Draw(surface, area); } }
static extern void sfSprite_SetSubRect(IntPtr This, IntRect Rect);
/// <summary> /// Creates a new text surface with the specified width, height, and initial set of cell data. /// </summary> /// <param name="width">The width of the surface.</param> /// <param name="height">THe height of the surface.</param> /// <param name="font">The font used with rendering.</param> /// <param name="initialCells"></param> public TextSurface(int width, int height, Cell[] initialCells, Font font) : base(width, height, initialCells) { area = new Rectangle(0, 0, width, height); Font = font; }
/// <summary> /// Creates a new text surface with the specified width and height. /// </summary> /// <param name="width">The width of the surface.</param> /// <param name="height">THe height of the surface.</param> /// <param name="font">The font used with rendering.</param> public TextSurface(int width, int height, Font font) : base(width, height) { area = new Rectangle(0, 0, width, height); Font = font; }
//////////////////////////////////////////////////////////// /// <summary> /// Copy pixels from another image onto this one. /// This function does a slow pixel copy and should only /// be used at initialization time /// </summary> /// <param name="source">Source image to copy</param> /// <param name="destX">X coordinate of the destination position</param> /// <param name="destY">Y coordinate of the destination position</param> /// <param name="sourceRect">Sub-rectangle of the source image to copy</param> //////////////////////////////////////////////////////////// public void Copy(Image source, uint destX, uint destY, IntRect sourceRect) { sfImage_CopyImage(This, source.This, destX, destY, sourceRect); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Loads a texture /// </summary> /// /// <param name="filename">Filename of the image to load</param> /// <param name="sprite">The sprite object to store the loaded image</param> /// <param name="rect">Load only this part of the image.</param> /// /// The second time you call this function with the same filename, the previously loaded image will be reused. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void GetTexture(string filename, Impl.Sprite sprite, SFML.Graphics.IntRect rect = new SFML.Graphics.IntRect()) { // Look if we already had this image ImageMapData data; if (m_ImageMap.TryGetValue(filename, out data)) { // Loop all our textures to find the one containing the image foreach (Impl.Texture tex in data.data) { // Only reuse the texture when the exact same part of the image is used if ((tex.rect.Left == rect.Left) && (tex.rect.Top == rect.Top) && (tex.rect.Width == rect.Width) && (tex.rect.Height == rect.Height)) { // The texture is now used at multiple places ++(tex.users); // We already have the texture, so pass the data sprite.texture = tex; // Set the texture in the sprite sprite.sprite.Texture = tex.texture; return; } } } else // The image doesn't exist yet { data = new ImageMapData(); data.data = new List <Impl.Texture> (); m_ImageMap.Add(filename, data); } // Add new data to the list Impl.Texture texture = new Impl.Texture(); sprite.texture = texture; sprite.texture.image = data.image; sprite.texture.rect = rect; data.data.Add(texture); // Load the image if (Global.ResourceManager == null) { sprite.texture.image = new SFML.Graphics.Image(filename); } else { if (Global.ResourceManager.GetObject(filename) is byte[]) { byte[] raw = Global.ResourceManager.GetObject(filename) as byte[]; MemoryStream mem = new MemoryStream(raw); sprite.texture.image = new SFML.Graphics.Image(mem); } else if (Global.ResourceManager.GetObject(filename) is System.Drawing.Image) { System.Drawing.Image raw = Global.ResourceManager.GetObject(filename) as System.Drawing.Image; MemoryStream mem = new MemoryStream(); // Copy the image to the Stream raw.Save(mem, raw.RawFormat); // Copy stream into new memory stream - prevents an AccessViolationException mem = new MemoryStream(mem.ToArray()); sprite.texture.image = new SFML.Graphics.Image(mem); } } // Create a texture from the image if ((rect.Left == 0) && (rect.Top == 0) && (rect.Width == 0) && (rect.Height == 0)) { sprite.texture.texture = new SFML.Graphics.Texture(sprite.texture.image); } else { sprite.texture.texture = new SFML.Graphics.Texture(sprite.texture.image, rect); } // Set the texture in the sprite sprite.sprite.Texture = sprite.texture.texture; // Set the other members of the data sprite.texture.filename = filename; sprite.texture.users = 1; }
static extern IntPtr sfTexture_createFromImage(IntPtr image, ref IntRect area);
static extern void sfShape_setTextureRect(IntPtr CPointer, IntRect Rect);
public static bool Matches(this IntRect self, SadRogueRectangle other) => self.Left == other.X && self.Top == other.Y && self.Width == other.Width && self.Height == other.Height;
public static SadRogueRectangle ToRectangle(this IntRect self) => new SadRogueRectangle(self.Left, self.Top, self.Width - self.Left, self.Height - self.Top);
static extern IntPtr sfTexture_createFromMemory(IntPtr data, ulong size, ref IntRect area);
static extern void sfImage_CopyImage(IntPtr This, IntPtr Source, uint DestX, uint DestY, IntRect SourceRect);
static extern bool sfImage_CopyScreen(IntPtr This, IntPtr Window, IntRect SourceRect);
//////////////////////////////////////////////////////////// /// <summary> /// Create the image from the current contents of the /// given window /// </summary> /// <param name="window">Window to capture</param> /// <param name="sourceRect">Sub-rectangle of the screen to copy</param> /// <returns>True if copy has been successful</returns> //////////////////////////////////////////////////////////// public bool CopyScreen(RenderWindow window, IntRect sourceRect) { return(sfImage_CopyScreen(This, window.This, sourceRect)); }
unsafe static extern void sfImage_UpdatePixels(IntPtr This, Color *Pixels, IntRect Rectangle);
static extern FloatRect sfTexture_getTexCoords(IntPtr texture, IntRect rectangle);