/// <summary> /// Creates an unscaled bitmap catalog for the current scenario.</summary> /// <returns> /// The maximum number of animation frames for any single entity class. This value is at /// least one. Animation is only possible if it is greater than one.</returns> /// <remarks> /// <b>CreateCatalog</b> defines the <see cref="CatalogManager.TileCount"/>, <see /// cref="CatalogManager.RowCount"/>, and <see cref="CatalogManager.Catalog"/> properties. /// </remarks> private int CreateCatalog() { // count catalog tiles and set indices int frames; int countedTiles = CopyEntityClasses(false, out frames); this._catalogClasses = new EntityClass[countedTiles]; // create catalog bitmap CreateCatalog(countedTiles); Catalog.Lock(); Catalog.Clear(); TileCopyBuffer.Lock(); /* * The animation frame count may change when attempting to create tiles, * as entity classes whose tiles could not be created are mapped to the * "invalid" icon with its single frame. So we check only the tile count. */ // create catalog images int copiedTiles = CopyEntityClasses(true, out frames); Debug.Assert(countedTiles == copiedTiles, "Tile count changed"); TileCopyBuffer.Unlock(); Catalog.Unlock(); Catalog.Freeze(); // return max frame count return(frames); }
/// <summary> /// Draws the <see cref="Catalog"/> tile with the specified index to the <see /// cref="TileCopyBuffer"/>.</summary> /// <param name="index"> /// The tile index in the <see cref="Catalog"/> bitmap whose contents to draw.</param> /// <exception cref="ObjectDisposedException"> /// The <see cref="CatalogManager"/> object has been disposed of.</exception> /// <remarks> /// <b>DrawTile</b> draws the <see cref="Catalog"/> tile at the specified <paramref /// name="index"/> to the <see cref="TileCopyBuffer"/>. Any existing buffer contents are /// overwritten.</remarks> public void DrawTileToBuffer(int index) { if (IsDisposed) { ThrowHelper.ThrowObjectDisposedException(null); } // compute source rectangle RectI source = GetTileBounds(index); // copy catalog tile to buffer TileCopyBuffer.Lock(); TileCopyBuffer.Read(0, 0, Catalog, source); TileCopyBuffer.Unlock(); }
/// <summary> /// Copies the specified <see cref="ImageFrame"/> to the specified catalog tile.</summary> /// <param name="index"> /// The catalog tile index where to copy the specified <paramref name="frame"/>.</param> /// <param name="entry"> /// The <see cref="ImageStackEntry"/> whose <see cref="ImageStackEntry.Image"/> contains the /// specified <paramref name="frame"/>.</param> /// <param name="frame"> /// The <see cref="ImageFrame"/> specifying the <see cref="ImageFrame.Source"/> bitmap and /// the <see cref="ImageFrame.Bounds"/> to copy.</param> /// <returns> /// <c>true</c> if copying succeeded; otherwise, <c>false</c>.</returns> private bool CopyImageFrame(int index, ImageStackEntry entry, ImageFrame frame) { // retrieve image file bitmap WriteableBitmap bitmap = frame.Source.Value.Bitmap; if (bitmap == null) { return(false); } // check for invalid frame bounds RectI source = frame.Bounds; if (source.X < 0 || source.Y < 0 || source.Width < 1 || source.Height < 1 || source.X + source.Width > bitmap.Width || source.Y + source.Height > bitmap.Height) { return(false); } // get desired image scaling, unless disabled ImageScaling scalingX = ImageScaling.None, scalingY = ImageScaling.None; if (!entry.UseUnscaled) { scalingX = entry.Image.Value.ScalingX; scalingY = entry.Image.Value.ScalingY; } // determine bounds of catalog tile RectI target = GetTileBounds(index); RectI tileBounds = new RectI(0, 0, target.Width, target.Height); // draw frame with specified display parameters TileCopyBuffer.Clear(); ImageUtility.DrawFrame(TileCopyBuffer, null, tileBounds, bitmap, source, scalingX, scalingY, entry.ColorShift, entry.Offset, entry.ScalingVector); // perform alpha blending with catalog bitmap Catalog.Overlay(target.X, target.Y, TileCopyBuffer, tileBounds); return(true); }
/// <summary> /// Draws the <see cref="Catalog"/> tile with the specified index.</summary> /// <param name="context"> /// The <see cref="DrawingContext"/> for the drawing.</param> /// <param name="index"> /// The tile index in the <see cref="Catalog"/> bitmap whose contents to draw.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="context"/> is a null reference.</exception> /// <exception cref="ObjectDisposedException"> /// The <see cref="CatalogManager"/> object has been disposed of.</exception> /// <remarks><para> /// <b>DrawTile</b> draws the <see cref="Catalog"/> tile at the specified <paramref /// name="index"/> to pixel location (1,1) within the specified <paramref name="context"/>. /// </para><para> /// The tile is clipped by and surrounded with the <see cref="RegularPolygon"/> outline of /// an <see cref="PolygonGrid.Element"/> in the current <see cref="MapGrid"/>. /// </para></remarks> public void DrawTile(DrawingContext context, int index) { if (IsDisposed) { ThrowHelper.ThrowObjectDisposedException(null); } if (context == null) { ThrowHelper.ThrowArgumentNullException("context"); } // compute source & target rectangles RectI source = GetTileBounds(index); Rect target = new Rect(1, 1, source.Width, source.Height); // copy catalog tile to buffer TileCopyBuffer.Lock(); TileCopyBuffer.Read(0, 0, Catalog, source); TileCopyBuffer.Unlock(); // get scaled polygonal outline, centered on tile PointD offset = new PointD((source.Width + 2) / 2.0, (source.Height + 2) / 2.0); var geometry = new PathGeometry() { Figures = { MapGrid.Element.ToFigure(offset) } }; geometry.Freeze(); // draw catalog tile, clipped to polygonal region context.PushClip(geometry); context.DrawImage(TileCopyBuffer, target); context.Pop(); // draw black polygon outline context.DrawGeometry(null, new Pen(Brushes.Black, 1.0), geometry); }