private IkonComposite loadAtlas() { var atlasFile = new FileInfo(AtlasImagePath); var metadataFile = new FileInfo(AtlasIkonPath); var rootFolder = SettingsWinforms.Get.DataRootPath ?? ""; var extraSprites = new DirectoryInfo(rootFolder + SpritesPath). GetFiles(). Where(x => x.Name != atlasFile.Name && x.Name != metadataFile.Name). ToList(); IkonComposite ikonData; using (var ikonParser = new IkonParser(new StreamReader(rootFolder + AtlasIkonPath))) ikonData = ikonParser.ParseNext(AtlasTag).To <IkonComposite>(); using (var atlasImage = new Bitmap(rootFolder + AtlasImagePath)) { if (extraSprites.Any()) { #if DEBUG System.Diagnostics.Trace.WriteLine("Adding loose sprites to atlas: " + string.Join(" ", extraSprites.Select(x => x.Name))); #endif var atlasBuilder = new AtlasBuilder(ikonData, SpriteMargin, atlasImage.Size); using (Graphics g = Graphics.FromImage(atlasImage)) { g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None; foreach (var spriteFile in extraSprites) { using (var sprite = new Bitmap(spriteFile.FullName)) { var spriteRegion = atlasBuilder.Add(sprite.Size); g.DrawImage(sprite, spriteRegion); var textureCoords = new IkonArray { serializeSpriteCorner(spriteRegion.Left, spriteRegion.Top, atlasImage.Size), serializeSpriteCorner(spriteRegion.Right, spriteRegion.Top, atlasImage.Size), serializeSpriteCorner(spriteRegion.Right, spriteRegion.Bottom, atlasImage.Size), serializeSpriteCorner(spriteRegion.Left, spriteRegion.Bottom, atlasImage.Size) }; ikonData.Add(Path.GetFileNameWithoutExtension(spriteFile.Name), textureCoords); } } } } //TODO(later) move to atlas generator var atlasData = new ColorMap(atlasImage); for (int y = 0; y < atlasData.Height; y++) { for (int x = 0; x < atlasData.Width; x++) { if (atlasData[x, y].A == 0) { var colorSum = new Vector4(); var alphaSum = 0f; foreach (var color in atlasData.Subregion(x - 1, y - 1, x + 1, y + 1)) { colorSum += new Vector4(color.R, color.G, color.B, 1) * color.A; alphaSum += color.A; } if (alphaSum > 0) { colorSum /= alphaSum; atlasData[x, y] = new Color4(colorSum.X, colorSum.Y, colorSum.Z, 0); } } } } this.textureId = TextureUtils.CreateTexture(atlasData); this.Size = new Vector2(atlasImage.Width, atlasImage.Height); } return(ikonData); }
private void prepare(string text) { this.Initialize(); var missinCharacters = new HashSet <char>(); foreach (char c in text) { if (!this.characterInfos.ContainsKey(c) && !char.IsWhiteSpace(c)) { missinCharacters.Add(c); } } if (missinCharacters.Count == 0) { return; } foreach (char c in missinCharacters) { var path = new GraphicsPath(); path.AddString(c.ToString(), font.FontFamily, (int)font.Style, font.Size, new Point(0, 0), StringFormat.GenericTypographic); path.Flatten(); var contures = getContures(path).ToList(); var minX = (int)Math.Floor(path.PathPoints.Min(p => p.X)); var maxX = (int)Math.Ceiling(path.PathPoints.Max(p => p.X)); var minY = (int)Math.Floor(path.PathPoints.Min(p => p.Y)); var maxY = (int)Math.Ceiling(path.PathPoints.Max(p => p.Y)); path.Dispose(); var width = maxX - minX; var height = maxY - minY; var rect = this.textureBuilder.Add(new Size(width + SdfPadding * 2, height + SdfPadding * 2)); var distField = new double[rect.Size.Height, rect.Size.Width]; for (int y = 0; y < rect.Size.Height; y++) { for (int x = 0; x < rect.Size.Width; x++) { var fromP = new Vector2(x + minX - SdfPadding, y + minY - SdfPadding); var minDist = Math.Min(contures.Min(shape => shape.Distance(fromP)), SdfPadding); if (contures.Sum(shape => shape.RayHits(fromP)) % 2 != 0) { minDist *= -1; } distField[y, x] = -minDist / SdfPadding / 2 + 0.5; } } for (int y = 0; y < rect.Size.Height; y++) { for (int x = 0; x < rect.Size.Width; x++) { this.textureData[rect.X + x, rect.Y + y] = Color.FromArgb((int)(distField[y, x] * 255), 255, 255, 255); } } this.characterInfos[c] = new CharTextureInfo( rect, this.textureData.Width, this.textureData.Height, rect.Size.Width / font.Size, rect.Size.Height / font.Size, (minX + maxX) / font.Size / 2, -(minY + maxY) / font.Size / 2, maxX / font.Size, maxY / font.Size ); } TextureUtils.UpdateTexture(this.TextureId, this.textureData); }