diff --git a/Controllers/LockerImageController.cs b/Controllers/LockerImageController.cs index 1a08fe8..63d837b 100644 --- a/Controllers/LockerImageController.cs +++ b/Controllers/LockerImageController.cs @@ -93,8 +93,7 @@ private async Task GenerateImage(Locker locker) var resize = (int)(50 * uiResizingFactor); using var drawIconPaint = new SKPaint(); drawIconPaint.IsAntialias = true; - drawIconPaint.FilterQuality = SKFilterQuality.High; - canvas.DrawBitmap(iconBitmap, SKRect.Create(50, 50, resize, resize), drawIconPaint); + canvas.DrawBitmap(iconBitmap, SKRect.Create(50, 50, resize, resize), SKSamplingOptions.Default, drawIconPaint); using var splitPaint = new SKPaint(); splitPaint.IsAntialias = true; @@ -106,16 +105,16 @@ private async Task GenerateImage(Locker locker) splitPaint); using var namePaint = new SKPaint(); + using var namePaintFont = new SKFont(); namePaint.IsAntialias = true; namePaint.Color = SKColors.White; - namePaint.Typeface = segoeFont; - namePaint.TextSize = nameFontSize; - namePaint.FilterQuality = SKFilterQuality.Medium; + namePaintFont.Typeface = segoeFont; + namePaintFont.Size = nameFontSize; - canvas.DrawAlignedText(locker.PlayerName, new SKPoint(50 + resize + splitWidth * 3, 58), namePaint); + canvas.DrawAlignedText(locker.PlayerName, new SKPoint(50 + resize + splitWidth * 3, 58), namePaintFont, namePaint); using var discordBoxBitmap = await ImageUtils.GenerateDiscordBox(assets, locker.UserName, uiResizingFactor); - canvas.DrawBitmap(discordBoxBitmap, imageInfo.Width - 50 - discordBoxBitmap.Width, 39); + canvas.DrawBitmap(discordBoxBitmap, imageInfo.Width - 50 - discordBoxBitmap.Width, 39, SKSamplingOptions.Default); var column = 0; var row = 0; @@ -124,7 +123,7 @@ private async Task GenerateImage(Locker locker) canvas.DrawBitmap( item.Image, 50 + 256 * column + 25 * column, - 50 + nameFontSize + 50 + row * 313 + row * 25); + 50 + nameFontSize + 50 + row * 313 + row * 25, SKSamplingOptions.Default); column++; if (column != columns) continue; column = 0; @@ -134,7 +133,7 @@ private async Task GenerateImage(Locker locker) // Load Footer.svg file as a stream using var footerBitmap = await GenerateFooter(uiResizingFactor); canvas.DrawBitmap(footerBitmap, (imageInfo.Width - footerBitmap.Width) / 2.0f, - imageInfo.Height - (footerSpace + footerBitmap.Height) / 2.0f); + imageInfo.Height - (footerSpace + footerBitmap.Height) / 2.0f, SKSamplingOptions.Default); return bitmap; } @@ -201,7 +200,7 @@ await Parallel.ForEachAsync(locker.Items, options, async (item, token) => fileExists = false; try { - itemImage = itemImageRaw.Resize(new SKImageInfo(256, 256), SKFilterQuality.Medium); + itemImage = itemImageRaw.Resize(new SKImageInfo(256, 256), new SKSamplingOptions(SKFilterMode.Linear)); } finally { @@ -250,24 +249,24 @@ private async Task GenerateItemCard(LockerItem lockerItem, SKBitmap? i var rarityBackground = await assets.GetBitmap($"Assets/Images/Locker/RarityBackgrounds/{lockerItem.Rarity}.png"); - canvas.DrawBitmap(rarityBackground, SKPoint.Empty); + canvas.DrawBitmap(rarityBackground, SKPoint.Empty, SKSamplingOptions.Default); if (itemImage is not null) { - canvas.DrawBitmap(itemImage, SKPoint.Empty); + canvas.DrawBitmap(itemImage, SKPoint.Empty, SKSamplingOptions.Default); } else { using var questionmarkPaint = new SKPaint(); + using var questionmarkPaintFont = new SKFont(); questionmarkPaint.IsAntialias = true; questionmarkPaint.Color = SKColors.White; - questionmarkPaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); - questionmarkPaint.TextSize = 256.0f; - questionmarkPaint.TextAlign = SKTextAlign.Center; + questionmarkPaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); + questionmarkPaintFont.Size = 256.0f; canvas.DrawAlignedText( "?", - imageInfo.Rect, + imageInfo.Rect, questionmarkPaintFont, questionmarkPaint, SKTextAlign.Center, VerticalTextAlignment.Center); @@ -277,54 +276,54 @@ private async Task GenerateItemCard(LockerItem lockerItem, SKBitmap? i ? await assets.GetBitmap($"Assets/Images/Locker/Source/{lockerItem.SourceType}.png") : null; using var overlayImage = ImageUtils.GenerateItemCardOverlay(imageInfo.Width, typeIcon); - canvas.DrawBitmap(overlayImage, new SKPoint(0, imageInfo.Height - overlayImage.Height)); + canvas.DrawBitmap(overlayImage, new SKPoint(0, imageInfo.Height - overlayImage.Height), SKSamplingOptions.Default); using var rarityStripe = ImageUtils.GenerateRarityStripe(imageInfo.Width, SKColor.Parse(lockerItem.RarityColor)); canvas.DrawBitmap(rarityStripe, - new SKPoint(0, imageInfo.Height - overlayImage.Height - rarityStripe.Height + 5)); + new SKPoint(0, imageInfo.Height - overlayImage.Height - rarityStripe.Height + 5), SKSamplingOptions.Default); // TODO: Fix Transparency issues var fortniteFont = await assets.GetFont("Assets/Fonts/Fortnite.ttf"); // don't dispose using var namePaint = new SKPaint(); + using var namePaintFont = new SKFont(); namePaint.IsAntialias = true; - namePaint.TextSize = 18.0f; + namePaintFont.Size = 18.0f; namePaint.Color = SKColors.White; - namePaint.Typeface = fortniteFont; - namePaint.TextAlign = SKTextAlign.Center; + namePaintFont.Typeface = fortniteFont; canvas.DrawAlignedText( lockerItem.Name, - new SKPoint(bitmap.Width / 2f, bitmap.Height - 59), + new SKPoint(bitmap.Width / 2f, bitmap.Height - 59), namePaintFont, namePaint, SKTextAlign.Center); using var descriptionPaint = new SKPaint(); + using var descriptionPaintFont = new SKFont(); descriptionPaint.IsAntialias = true; - descriptionPaint.TextSize = 15.0f; + descriptionPaintFont.Size = 15.0f; descriptionPaint.Color = SKColor.Parse(lockerItem.RarityColor); - descriptionPaint.Typeface = fortniteFont; - descriptionPaint.TextAlign = SKTextAlign.Center; + descriptionPaintFont.Typeface = fortniteFont; canvas.DrawAlignedText( lockerItem.Description, - new SKPoint(bitmap.Width / 2f, bitmap.Height - 42), + new SKPoint(bitmap.Width / 2f, bitmap.Height - 42), descriptionPaintFont, descriptionPaint, SKTextAlign.Center); using var sourcePaint = new SKPaint(); + using var sourcePaintFont = new SKFont(); sourcePaint.IsAntialias = true; - sourcePaint.TextSize = 15.0f; + sourcePaintFont.Size = 15.0f; sourcePaint.Color = SKColors.White; - sourcePaint.Typeface = fortniteFont; - sourcePaint.TextAlign = SKTextAlign.Right; + sourcePaintFont.Typeface = fortniteFont; var fontOffset = lockerItem.SourceType == SourceType.Other ? 10 : 42; canvas.DrawAlignedText( lockerItem.Source, - new SKPoint(bitmap.Width - fontOffset, bitmap.Height - 7), + new SKPoint(bitmap.Width - fontOffset, bitmap.Height - 7), sourcePaintFont, sourcePaint, SKTextAlign.Right, VerticalTextAlignment.Bottom); @@ -337,16 +336,16 @@ private async Task GenerateFooter(float resizeFactor) var poppinsFont = await assets.GetFont("Assets/Fonts/Poppins.ttf"); // don't dispose using var textPaint = new SKPaint(); + using var textPaintFont = new SKFont(); textPaint.IsAntialias = true; - textPaint.TextSize = 40.0f * resizeFactor; + textPaintFont.Size = 40.0f * resizeFactor; textPaint.Color = SKColors.White; - textPaint.Typeface = poppinsFont; + textPaintFont.Typeface = poppinsFont; //var text = "EasyFnStats.com".ToUpper(); const string text = "EASYFNSTATS.COM"; - var textBounds = new SKRect(); - textPaint.MeasureText(text, ref textBounds); + textPaintFont.MeasureText(text, out var textBounds, textPaint); var imageInfo = new SKImageInfo((int)((50 + 10 + 5 + 10) * resizeFactor + textBounds.Width), (int)(50 * resizeFactor)); @@ -357,8 +356,7 @@ private async Task GenerateFooter(float resizeFactor) using var drawLogoPaint = new SKPaint(); drawLogoPaint.IsAntialias = true; - drawLogoPaint.FilterQuality = SKFilterQuality.High; - canvas.DrawBitmap(logoBitmap, SKRect.Create(0, 0, imageInfo.Height, imageInfo.Height), drawLogoPaint); + canvas.DrawBitmap(logoBitmap, SKRect.Create(0, 0, imageInfo.Height, imageInfo.Height), SKSamplingOptions.Default, drawLogoPaint); var splitR = 3 * resizeFactor; @@ -370,7 +368,7 @@ private async Task GenerateFooter(float resizeFactor) canvas.DrawAlignedText( text, - new SKPoint((50 + 10 + 5 + 10) * resizeFactor, imageInfo.Height / 2f), + new SKPoint((50 + 10 + 5 + 10) * resizeFactor, imageInfo.Height / 2f), textPaintFont, textPaint, verticalAlignment: VerticalTextAlignment.Center); diff --git a/Controllers/ShopImageController.cs b/Controllers/ShopImageController.cs index 1195ed1..912bff8 100644 --- a/Controllers/ShopImageController.cs +++ b/Controllers/ShopImageController.cs @@ -229,25 +229,25 @@ private async Task GenerateShopImage(Shop shop, SKBitmap templateBitma { using var backgroundImagePaint = new SKPaint(); backgroundImagePaint.IsAntialias = true; - backgroundImagePaint.FilterQuality = SKFilterQuality.Medium; canvas.Save(); canvas.ClipRoundRect(new SKRoundRect(imageInfo.Rect, 50), antialias: true); - canvas.DrawBitmap(backgroundBitmap, imageInfo.Rect, backgroundImagePaint); + canvas.DrawBitmap(backgroundBitmap, imageInfo.Rect, SKSamplingOptions.Default, backgroundImagePaint); canvas.Restore(); } - canvas.DrawBitmap(templateBitmap, 0, 0); + canvas.DrawBitmap(templateBitmap, 0, 0, SKSamplingOptions.Default); if (shop is { CreatorCode: not null, CreatorCodeTitle: not null }) { using var shopTitlePaint = new SKPaint(); + using var shopTitlePaintFont = new SKFont(); shopTitlePaint.IsAntialias = true; - shopTitlePaint.TextSize = TITLE_FONT_SIZE; - shopTitlePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); + shopTitlePaintFont.Size = TITLE_FONT_SIZE; + shopTitlePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); - var shopTitleWidth = shopTitlePaint.MeasureText(shop.Title); + var shopTitleWidth = shopTitlePaintFont.MeasureText(shop.Title, shopTitlePaint); var maxBoxWidth = imageInfo.Width - 3 * HORIZONTAL_PADDING - shopTitleWidth; @@ -255,12 +255,12 @@ private async Task GenerateShopImage(Shop shop, SKBitmap templateBitma { using var creatorCodeBoxBitmap = await GenerateCreatorCodeBox(shop.CreatorCodeTitle, shop.CreatorCode, maxBoxWidth); - canvas.DrawBitmap(creatorCodeBoxBitmap, imageInfo.Width - 100 - creatorCodeBoxBitmap.Width, 100); + canvas.DrawBitmap(creatorCodeBoxBitmap, imageInfo.Width - 100 - creatorCodeBoxBitmap.Width, 100, SKSamplingOptions.Default); } var adBannerBitmap = await assets.GetBitmap("Assets/Images/Shop/ad_banner.png"); // don't dispose canvas.DrawBitmap(adBannerBitmap, imageInfo.Width - 100 - 50 - adBannerBitmap!.Width, - 100 - adBannerBitmap.Height / 2f); + 100 - adBannerBitmap.Height / 2f, SKSamplingOptions.Default); } return bitmap; @@ -273,31 +273,32 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template var bitmap = new SKBitmap(imageInfo); using var canvas = new SKCanvas(bitmap); - canvas.DrawBitmap(templateBitmap, SKPoint.Empty); + canvas.DrawBitmap(templateBitmap, SKPoint.Empty, SKSamplingOptions.Default); // Drawing the shop title using var shopTitlePaint = new SKPaint(); + using var shopTitlePaintFont = new SKFont(); shopTitlePaint.IsAntialias = true; - shopTitlePaint.TextSize = TITLE_FONT_SIZE; + shopTitlePaintFont.Size = TITLE_FONT_SIZE; shopTitlePaint.Color = SKColors.White; - shopTitlePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); + shopTitlePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86Bold.otf"); - var shopTitleWidth = shopTitlePaint.MeasureText(shop.Title); - canvas.DrawAlignedText(shop.Title, new SKPoint(100, 50), shopTitlePaint); + var shopTitleWidth = shopTitlePaintFont.MeasureText(shop.Title, shopTitlePaint); + canvas.DrawAlignedText(shop.Title, new SKPoint(100, 50), shopTitlePaintFont, shopTitlePaint); // Drawing the date using var datePaint = new SKPaint(); + using var datePaintFont = new SKFont(); datePaint.IsAntialias = true; - datePaint.TextSize = DATE_FONT_SIZE; + datePaintFont.Size = DATE_FONT_SIZE; datePaint.Color = SKColors.White; - datePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86BoldItalic.otf"); - datePaint.TextAlign = SKTextAlign.Center; + datePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86BoldItalic.otf"); var datePoint = new SKPoint( Math.Max(HORIZONTAL_PADDING + shopTitleWidth / 2f, - HORIZONTAL_PADDING + datePaint.MeasureText(shop.Date) / 2), + HORIZONTAL_PADDING + datePaintFont.MeasureText(shop.Date, datePaint) / 2), 313); - canvas.DrawAlignedText(shop.Date, datePoint, datePaint, SKTextAlign.Center); + canvas.DrawAlignedText(shop.Date, datePoint, datePaintFont, datePaint, SKTextAlign.Center); foreach (var sectionLocationData in shopSectionLocationData) { @@ -307,13 +308,14 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template if (sectionLocationData.Name != null && shopSection?.Name != null) { using var sectionNamePaint = new SKPaint(); + using var sectionNamePaintFont = new SKFont(); sectionNamePaint.IsAntialias = true; - sectionNamePaint.TextSize = SECTION_NAME_FONT_SIZE; + sectionNamePaintFont.Size = SECTION_NAME_FONT_SIZE; sectionNamePaint.Color = SKColors.White; - sectionNamePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86BoldItalic.otf"); + sectionNamePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-86BoldItalic.otf"); var sectionNamePoint = new SKPoint(sectionLocationData.Name.X, sectionLocationData.Name.Y); - canvas.DrawAlignedText(shopSection.Name, sectionNamePoint, sectionNamePaint); + canvas.DrawAlignedText(shopSection.Name, sectionNamePoint, sectionNamePaintFont, sectionNamePaint); } foreach (var entryLocationData in sectionLocationData.Entries) @@ -323,39 +325,42 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template continue; using var entryNamePaint = new SKPaint(); + using var entryNamePaintFont = new SKFont(); entryNamePaint.IsAntialias = true; - entryNamePaint.TextSize = ENTRY_NAME_FONT_SIZE; + entryNamePaintFont.Size = ENTRY_NAME_FONT_SIZE; entryNamePaint.Color = SKColors.White; - entryNamePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); + entryNamePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); - var nameLines = SplitNameText(shopEntry.Name, entryLocationData.Name.MaxWidth ?? 0, entryNamePaint); + var nameLines = SplitNameText(shopEntry.Name, entryLocationData.Name.MaxWidth ?? 0, + entryNamePaintFont, entryNamePaint); if (nameLines.Length > 1) { canvas.DrawAlignedText( nameLines[0], - new SKPoint(entryLocationData.Name.X, entryLocationData.Name.Y - 33), + new SKPoint(entryLocationData.Name.X, entryLocationData.Name.Y - 33), entryNamePaintFont, entryNamePaint); } canvas.DrawAlignedText( nameLines.Last(), - new SKPoint(entryLocationData.Name.X, entryLocationData.Name.Y), + new SKPoint(entryLocationData.Name.X, entryLocationData.Name.Y), entryNamePaintFont, entryNamePaint); // Draw the shop entry price using var pricePaint = new SKPaint(); + using var pricePaintFont = new SKFont(); pricePaint.IsAntialias = true; - pricePaint.TextSize = ENTRY_PRICE_FONT_SIZE; + pricePaintFont.Size = ENTRY_PRICE_FONT_SIZE; pricePaint.Color = SKColors.White; - pricePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); + pricePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); - var priceTextWidth = pricePaint.MeasureText(shopEntry.FinalPrice); + var priceTextWidth = pricePaintFont.MeasureText(shopEntry.FinalPrice, pricePaint); var pricePoint = new SKPoint( entryLocationData.Price.X, - entryLocationData.Price.Y - pricePaint.FontMetrics.Descent); + entryLocationData.Price.Y - pricePaintFont.Metrics.Descent); canvas.DrawAlignedText( shopEntry.FinalPrice, - pricePoint, + pricePoint, pricePaintFont, pricePaint, verticalAlignment: VerticalTextAlignment.Baseline); @@ -363,18 +368,19 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template if (shopEntry.FinalPrice != shopEntry.RegularPrice) { using var oldPricePaint = new SKPaint(); + using var oldPricePaintFont = new SKFont(); oldPricePaint.IsAntialias = true; - oldPricePaint.TextSize = ENTRY_PRICE_FONT_SIZE; + oldPricePaintFont.Size = ENTRY_PRICE_FONT_SIZE; oldPricePaint.Color = SKColors.White.WithAlpha((int)(.6 * 255)); - oldPricePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); + oldPricePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-75Medium.otf"); - var oldPriceTextWidth = oldPricePaint.MeasureText(shopEntry.RegularPrice); + var oldPriceTextWidth = oldPricePaintFont.MeasureText(shopEntry.RegularPrice, oldPricePaint); var oldPricePoint = new SKPoint( entryLocationData.Price.X + priceTextWidth + 9, - entryLocationData.Price.Y - oldPricePaint.FontMetrics.Descent); + entryLocationData.Price.Y - oldPricePaintFont.Metrics.Descent); canvas.DrawAlignedText( shopEntry.RegularPrice, - oldPricePoint, + oldPricePoint, oldPricePaintFont, oldPricePaint, verticalAlignment: VerticalTextAlignment.Baseline); @@ -393,7 +399,7 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template { using var bannerBitmap = await GenerateBanner(shopEntry.Banner.Text, shopEntry.Banner.Colors, (int)entryLocationData.Banner!.MaxWidth!); - canvas.DrawBitmap(bannerBitmap, entryLocationData.Banner!.X, entryLocationData.Banner.Y); + canvas.DrawBitmap(bannerBitmap, entryLocationData.Banner!.X, entryLocationData.Banner.Y, SKSamplingOptions.Default); } } } @@ -483,7 +489,7 @@ private async Task GenerateLocaleTemplate(Shop shop, SKBitmap template shopLocationData[iSec] = new ShopSectionLocationData(section.Id, sectionNameLocationData, shopEntryData.ToArray()); - canvas.DrawBitmap(sectionBitmap, new SKPoint(sectionX, sectionY)); + canvas.DrawBitmap(sectionBitmap, new SKPoint(sectionX, sectionY), SKSamplingOptions.Default); iSec++; } } @@ -497,26 +503,27 @@ private async Task GenerateCreatorCodeBox(string creatorCodeTitle, str creatorCode = $"{creatorCode} "; using var creatorCodeTitlePaint = new SKPaint(); + using var creatorCodeTitlePaintFont = new SKFont(); creatorCodeTitlePaint.IsAntialias = true; - creatorCodeTitlePaint.TextSize = 100f; - creatorCodeTitlePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76Bold.otf"); + creatorCodeTitlePaintFont.Size = 100f; + creatorCodeTitlePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76Bold.otf"); creatorCodeTitlePaint.Color = SKColors.Black; using var creatorCodePaint = new SKPaint(); + using var creatorCodePaintFont = new SKFont(); creatorCodePaint.IsAntialias = true; - creatorCodePaint.TextSize = 100f; - creatorCodePaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76Bold.otf"); + creatorCodePaintFont.Size = 100f; + creatorCodePaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76Bold.otf"); creatorCodePaint.Color = new SKColor(178, 165, 255); - creatorCodePaint.TextAlign = SKTextAlign.Right; float width = - creatorCodeTitlePaint.MeasureText(creatorCodeTitle) + creatorCodeTitlePaint.MeasureText(creatorCode), + creatorCodeTitlePaintFont.MeasureText(creatorCodeTitle, creatorCodeTitlePaint) + creatorCodeTitlePaintFont.MeasureText(creatorCode, creatorCodeTitlePaint), height = 150f; while (width > maxWidth) { - creatorCodeTitlePaint.TextSize--; - creatorCodePaint.TextSize--; - width = creatorCodeTitlePaint.MeasureText(creatorCodeTitle) + creatorCodePaint.MeasureText(creatorCode); + creatorCodeTitlePaintFont.Size--; + creatorCodePaintFont.Size--; + width = creatorCodeTitlePaintFont.MeasureText(creatorCodeTitle, creatorCodeTitlePaint) + creatorCodePaintFont.MeasureText(creatorCode, creatorCodePaint); height--; } @@ -530,10 +537,10 @@ private async Task GenerateCreatorCodeBox(string creatorCodeTitle, str boxPaint.Style = SKPaintStyle.Fill; canvas.DrawRoundRect(new SKRect(0, 0, imageInfo.Width, imageInfo.Height), 100, 100, boxPaint); - var y = (imageInfo.Height - creatorCodePaint.FontSpacing) / 2 - creatorCodePaint.FontMetrics.Ascent; + var y = (imageInfo.Height - creatorCodePaintFont.Spacing) / 2 - creatorCodePaintFont.Metrics.Ascent; - canvas.DrawText(creatorCodeTitle, 0, y, creatorCodeTitlePaint); - canvas.DrawText(creatorCode, imageInfo.Width, y, creatorCodePaint); + canvas.DrawText(creatorCodeTitle, 0, y, SKTextAlign.Left, creatorCodeTitlePaintFont, creatorCodeTitlePaint); + canvas.DrawText(creatorCode, imageInfo.Width, y, SKTextAlign.Right, creatorCodePaintFont, creatorCodePaint); return bitmap; } @@ -541,13 +548,13 @@ private async Task GenerateCreatorCodeBox(string creatorCodeTitle, str private async Task GenerateBanner(string text, IReadOnlyList colors, int maxWidth) { using var bannerPaint = new SKPaint(); + using var bannerPaintFont = new SKFont(); bannerPaint.IsAntialias = true; - bannerPaint.TextSize = 17.0f; - bannerPaint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76BoldItalic.otf"); + bannerPaintFont.Size = 17.0f; + bannerPaintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-76BoldItalic.otf"); bannerPaint.Color = SKColor.Parse(colors[1]); - var textBounds = new SKRect(); - bannerPaint.MeasureText(text, ref textBounds); + bannerPaintFont.MeasureText(text, out var textBounds, bannerPaint); var maxTextWidth = maxWidth - 2 * 13; var imageInfo = new SKImageInfo(Math.Min(2 * 13 + (int)textBounds.Width, maxWidth), 34); @@ -566,7 +573,7 @@ private async Task GenerateBanner(string text, IReadOnlyList c while (textBounds.Width > maxTextWidth) { text = text.Remove(text.Length - 1, 1); - bannerPaint.MeasureText(text + "...", ref textBounds); + bannerPaintFont.MeasureText(text + "...", out textBounds, bannerPaint); } text += "..."; @@ -575,7 +582,7 @@ private async Task GenerateBanner(string text, IReadOnlyList c canvas.DrawAlignedText( text, - new SKPoint(13, imageInfo.Height / 2f), + new SKPoint(13, imageInfo.Height / 2f), bannerPaintFont, bannerPaint, verticalAlignment: VerticalTextAlignment.Center); @@ -654,13 +661,12 @@ private async Task GenerateItemCard(ShopEntry shopEntry) if (shopEntry is { ImageType: "track", ImageUrl: null }) { var coverRect = SKRect.Create(10, 10, 236, 236); - + using var coverPaint = new SKPaint(); coverPaint.IsAntialias = true; - coverPaint.FilterQuality = SKFilterQuality.Medium; canvas.Save(); canvas.ClipRoundRect(new SKRoundRect(coverRect, 10), antialias: true); - canvas.DrawBitmap(shopEntry.Image, coverRect, coverPaint); + canvas.DrawBitmap(shopEntry.Image, coverRect, SKSamplingOptions.Default, coverPaint); canvas.Restore(); } else @@ -680,7 +686,6 @@ private async Task GenerateItemCard(ShopEntry shopEntry) } using var imagePaint = new SKPaint(); - imagePaint.FilterQuality = SKFilterQuality.Medium; // Car bundles get centered in the middle of the card vertically if (shopEntry.ImageType == "car-bundle") @@ -690,7 +695,7 @@ private async Task GenerateItemCard(ShopEntry shopEntry) var sourceRect = new SKRect(0, cropY * sourceScaleY, shopEntry.Image.Width, (cropY + imageInfo.Height) * sourceScaleY); canvas.DrawBitmap(shopEntry.Image, sourceRect, - new SKRect(0, 0, resizeWidth, imageInfo.Height), imagePaint); + new SKRect(0, 0, resizeWidth, imageInfo.Height), SKSamplingOptions.Default, imagePaint); } // Center image in the middle of the card, if width is bigger than the image else if (resizeWidth > imageInfo.Width) @@ -700,14 +705,14 @@ private async Task GenerateItemCard(ShopEntry shopEntry) var sourceRect = new SKRect(cropX * sourceScaleX, 0, (cropX + imageInfo.Width) * sourceScaleX, shopEntry.Image.Height); canvas.DrawBitmap(shopEntry.Image, sourceRect, - new SKRect(0, 0, imageInfo.Width, resizeHeight), imagePaint); + new SKRect(0, 0, imageInfo.Width, resizeHeight), SKSamplingOptions.Default, imagePaint); } else { var offsetMulti = shopEntry.Size >= 3f ? 0.08f : 0f; canvas.DrawBitmap(shopEntry.Image, new SKRect(0, resizeHeight * -offsetMulti, resizeWidth, - resizeHeight * (1 - offsetMulti)), imagePaint); + resizeHeight * (1 - offsetMulti)), SKSamplingOptions.Default, imagePaint); } } @@ -748,25 +753,25 @@ private async Task GenerateItemCard(ShopEntry shopEntry) // Draw V-Bucks icon var vbucksBitmap = await assets.GetBitmap("Assets/Images/Shop/vbucks_icon.png"); // don't dispose - canvas.DrawBitmap(vbucksBitmap, 13, imageInfo.Height - vbucksBitmap!.Height - 11); + canvas.DrawBitmap(vbucksBitmap, 13, imageInfo.Height - vbucksBitmap!.Height - 11, SKSamplingOptions.Default); if (shopEntry.IsSpecial) { using var paint = new SKPaint(); + using var paintFont = new SKFont(); using var font = new SKFont(await assets.GetFont("Assets/Fonts/Fortnite-74Regular.otf"), 35.0f); paint.IsAntialias = true; - paint.TextSize = 35.0f; + paintFont.Size = 35.0f; paint.Color = SKColors.White; - paint.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-74Regular.otf"); - paint.TextAlign = SKTextAlign.Right; + paintFont.Typeface = await assets.GetFont("Assets/Fonts/Fortnite-74Regular.otf"); - canvas.DrawText("+", imageInfo.Width - 18, imageInfo.Height - paint.FontMetrics.Descent + 3, paint); + canvas.DrawText("+", imageInfo.Width - 18, imageInfo.Height - paintFont.Metrics.Descent + 3, SKTextAlign.Right, paintFont, paint); } return bitmap; } - private static string[] SplitNameText(string text, int maxWidth, SKPaint paint) + private static string[] SplitNameText(string text, int maxWidth, SKFont paintFont, SKPaint paint) { var regex = NameSplitRegex(); var matches = regex.Matches(text); @@ -776,8 +781,7 @@ private static string[] SplitNameText(string text, int maxWidth, SKPaint paint) foreach (Match match in matches) { var line = lines[currentLine]; - var bounds = new SKRect(); - paint.MeasureText(line + match.Value, ref bounds); + paintFont.MeasureText(line + match.Value, out var bounds, paint); if (bounds.Width > maxWidth) currentLine++; if (currentLine >= 2) { @@ -791,14 +795,13 @@ private static string[] SplitNameText(string text, int maxWidth, SKPaint paint) // Adjust lines that are too long and add ellipsis foreach (var line in lines) { - var textBounds = new SKRect(); - paint.MeasureText(line.ToString(), ref textBounds); + paintFont.MeasureText(line.ToString(), out var textBounds, paint); if (textBounds.Width <= maxWidth) continue; while (textBounds.Width > maxWidth) { line.Remove(line.Length - 1, 1); - paint.MeasureText(line + "...", ref textBounds); + paintFont.MeasureText(line + "...", out textBounds, paint); } line.Append("..."); diff --git a/Controllers/StatsImageController.cs b/Controllers/StatsImageController.cs index 26bc7c0..fd32597 100644 --- a/Controllers/StatsImageController.cs +++ b/Controllers/StatsImageController.cs @@ -81,11 +81,10 @@ await assets.GetBitmap("data/images/{0}", { using var backgroundImagePaint = new SKPaint(); backgroundImagePaint.IsAntialias = true; - backgroundImagePaint.FilterQuality = SKFilterQuality.Medium; canvas.Save(); canvas.ClipRoundRect(new SKRoundRect(imageInfo.Rect, 50), antialias: true); - canvas.DrawBitmap(customBackgroundBitmap, imageInfo.Rect, backgroundImagePaint); + canvas.DrawBitmap(customBackgroundBitmap, imageInfo.Rect, SKSamplingOptions.Default, backgroundImagePaint); canvas.Restore(); } @@ -103,22 +102,25 @@ await assets.GetBitmap("data/images/{0}", var segoeFont = await assets.GetFont("Assets/Fonts/Segoe.ttf"); // don't dispose using var competitiveBoxTitlePaint = new SKPaint(); + using var competitiveBoxTitlePaintFont = new SKFont(); competitiveBoxTitlePaint.IsAntialias = true; competitiveBoxTitlePaint.Color = SKColors.White; - competitiveBoxTitlePaint.Typeface = fortniteFont; - competitiveBoxTitlePaint.TextSize = 25; + competitiveBoxTitlePaintFont.Typeface = fortniteFont; + competitiveBoxTitlePaintFont.Size = 25; using var boxTitlePaint = new SKPaint(); + using var boxTitlePaintFont = new SKFont(); boxTitlePaint.IsAntialias = true; boxTitlePaint.Color = SKColors.White; - boxTitlePaint.Typeface = fortniteFont; - boxTitlePaint.TextSize = 50; + boxTitlePaintFont.Typeface = fortniteFont; + boxTitlePaintFont.Size = 50; using var titlePaint = new SKPaint(); + using var titlePaintFont = new SKFont(); titlePaint.IsAntialias = true; titlePaint.Color = SKColors.LightGray; - titlePaint.Typeface = segoeFont; - titlePaint.TextSize = 20; + titlePaintFont.Typeface = segoeFont; + titlePaintFont.Size = 20; if (type == StatsType.Competitive) { @@ -142,26 +144,26 @@ await assets.GetBitmap("data/images/{0}", canvas.DrawRoundRect(267, 192, 1, 77, 1, 1, splitPaint); var buildLogo = await assets.GetBitmap("Assets/Images/Stats/BuildLogo.png"); // don't dispose - canvas.DrawBitmap(buildLogo, new SKPoint(115, 277)); + canvas.DrawBitmap(buildLogo, new SKPoint(115, 277), SKSamplingOptions.Default); var zeroBuildLogo = await assets.GetBitmap("Assets/Images/Stats/ZeroBuildLogo.png"); // don't dispose - canvas.DrawBitmap(zeroBuildLogo, new SKPoint(317, 277)); + canvas.DrawBitmap(zeroBuildLogo, new SKPoint(317, 277), SKSamplingOptions.Default); - canvas.DrawAlignedText("OVERALL", new SKPoint(211, 305), competitiveBoxTitlePaint); + canvas.DrawAlignedText("OVERALL", new SKPoint(211, 305), competitiveBoxTitlePaintFont, competitiveBoxTitlePaint); - canvas.DrawAlignedText("Earnings", new SKPoint(70, 338), titlePaint); + canvas.DrawAlignedText("Earnings", new SKPoint(70, 338), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Power Ranking", new SKPoint(250, 338), titlePaint); + canvas.DrawAlignedText("Power Ranking", new SKPoint(250, 338), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Games", new SKPoint(70, 414), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(70, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(231, 414), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(231, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(370, 414), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(370, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(70, 491), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(70, 491), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(231, 491), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(231, 491), titlePaintFont, titlePaint); } else { @@ -169,27 +171,27 @@ await assets.GetBitmap("data/images/{0}", DrawBlurredRoundRect(bitmap, overallBoxRect); canvas.DrawRoundRect(overallBoxRect, boxPaint); - canvas.DrawAlignedText("OVERALL", new SKPoint(60, 134), boxTitlePaint); + canvas.DrawAlignedText("OVERALL", new SKPoint(60, 134), boxTitlePaintFont, boxTitlePaint); - canvas.DrawAlignedText("Games", new SKPoint(70, 184), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(70, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(231, 184), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(231, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(370, 184), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(370, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(70, 261), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(70, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(231, 261), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(231, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Playtime since Season 7", new SKPoint(70, 338), titlePaint); + canvas.DrawAlignedText("Playtime since Season 7", new SKPoint(70, 338), titlePaintFont, titlePaint); - canvas.DrawAlignedText("days", new SKPoint(70, 397), titlePaint); + canvas.DrawAlignedText("days", new SKPoint(70, 397), titlePaintFont, titlePaint); - canvas.DrawAlignedText("hours", new SKPoint(147, 397), titlePaint); + canvas.DrawAlignedText("hours", new SKPoint(147, 397), titlePaintFont, titlePaint); - canvas.DrawAlignedText("minutes", new SKPoint(231, 397), titlePaint); + canvas.DrawAlignedText("minutes", new SKPoint(231, 397), titlePaintFont, titlePaint); - canvas.DrawAlignedText("BattlePass Level", new SKPoint(70, 442), titlePaint); + canvas.DrawAlignedText("BattlePass Level", new SKPoint(70, 442), titlePaintFont, titlePaint); using var battlePassBarBackgroundPaint = new SKPaint(); battlePassBarBackgroundPaint.IsAntialias = true; @@ -202,88 +204,88 @@ await assets.GetBitmap("data/images/{0}", DrawBlurredRoundRect(bitmap, soloBoxRect); canvas.DrawRoundRect(soloBoxRect, boxPaint); - canvas.DrawAlignedText("SOLO", new SKPoint(527, 134), boxTitlePaint); + canvas.DrawAlignedText("SOLO", new SKPoint(527, 134), boxTitlePaintFont, boxTitlePaint); var soloIcon = await assets.GetBitmap("Assets/Images/Stats/PlaylistIcons/solo.png"); // don't dispose - canvas.DrawBitmap(soloIcon, new SKPoint(648, 134)); + canvas.DrawBitmap(soloIcon, new SKPoint(648, 134), SKSamplingOptions.Default); - canvas.DrawAlignedText("Games", new SKPoint(537, 184), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(537, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(698, 184), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(698, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(837, 184), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(837, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(537, 261), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(537, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(698, 261), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(698, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Top 25", new SKPoint(837, 261), titlePaint); + canvas.DrawAlignedText("Top 25", new SKPoint(837, 261), titlePaintFont, titlePaint); // Duos var duosBoxRect = new SKRoundRect(SKRect.Create(996, 159, 459, 185), 30); DrawBlurredRoundRect(bitmap, duosBoxRect); canvas.DrawRoundRect(duosBoxRect, boxPaint); - canvas.DrawAlignedText("DUOS", new SKPoint(1006, 134), boxTitlePaint); + canvas.DrawAlignedText("DUOS", new SKPoint(1006, 134), boxTitlePaintFont, boxTitlePaint); var duosIcon = await assets.GetBitmap("Assets/Images/Stats/PlaylistIcons/duos.png"); // don't dispose - canvas.DrawBitmap(duosIcon, new SKPoint(1133, 134)); + canvas.DrawBitmap(duosIcon, new SKPoint(1133, 134), SKSamplingOptions.Default); - canvas.DrawAlignedText("Games", new SKPoint(1016, 184), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(1016, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(1177, 184), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(1177, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(1316, 184), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(1316, 184), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(1016, 261), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(1016, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(1177, 261), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(1177, 261), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Top 12", new SKPoint(1316, 261), titlePaint); + canvas.DrawAlignedText("Top 12", new SKPoint(1316, 261), titlePaintFont, titlePaint); // Trios var triosBoxRect = new SKRoundRect(SKRect.Create(517, 389, 459, 185), 30); DrawBlurredRoundRect(bitmap, triosBoxRect); canvas.DrawRoundRect(triosBoxRect, boxPaint); - canvas.DrawAlignedText("TRIOS", new SKPoint(527, 364), boxTitlePaint); + canvas.DrawAlignedText("TRIOS", new SKPoint(527, 364), boxTitlePaintFont, boxTitlePaint); var triosIcon = await assets.GetBitmap(@"Assets/Images/Stats/PlaylistIcons/trios.png"); // don't dispose - canvas.DrawBitmap(triosIcon, new SKPoint(663, 364)); + canvas.DrawBitmap(triosIcon, new SKPoint(663, 364), SKSamplingOptions.Default); - canvas.DrawAlignedText("Games", new SKPoint(537, 414), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(537, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(698, 414), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(698, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(837, 414), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(837, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(537, 491), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(537, 491), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(698, 491), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(698, 491), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Top 6", new SKPoint(837, 491), titlePaint); + canvas.DrawAlignedText("Top 6", new SKPoint(837, 491), titlePaintFont, titlePaint); // Squads var squadsBoxRect = new SKRoundRect(SKRect.Create(996, 389, 459, 185), 30); DrawBlurredRoundRect(bitmap, squadsBoxRect); canvas.DrawRoundRect(squadsBoxRect, boxPaint); - canvas.DrawAlignedText("SQUADS", new SKPoint(1006, 364), boxTitlePaint); + canvas.DrawAlignedText("SQUADS", new SKPoint(1006, 364), boxTitlePaintFont, boxTitlePaint); var squadsIcon = await assets.GetBitmap(@"Assets/Images/Stats/PlaylistIcons/squads.png"); // don't dispose - canvas.DrawBitmap(squadsIcon, new SKPoint(1191, 364)); + canvas.DrawBitmap(squadsIcon, new SKPoint(1191, 364), SKSamplingOptions.Default); - canvas.DrawAlignedText("Games", new SKPoint(1016, 414), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(1016, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(1177, 414), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(1177, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(1316, 414), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(1316, 414), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(1016, 491), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(1016, 491), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(1177, 491), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(1177, 491), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Top 6", new SKPoint(1316, 491), titlePaint); + canvas.DrawAlignedText("Top 6", new SKPoint(1316, 491), titlePaintFont, titlePaint); if (type == StatsType.Normal) { @@ -292,20 +294,20 @@ await assets.GetBitmap("data/images/{0}", DrawBlurredRoundRect(bitmap, teamsBoxRect); canvas.DrawRoundRect(teamsBoxRect, boxPaint); - canvas.DrawAlignedText("TEAMS", new SKPoint(527, 594), boxTitlePaint); + canvas.DrawAlignedText("TEAMS", new SKPoint(527, 594), boxTitlePaintFont, boxTitlePaint); var teamsIcon = await assets.GetBitmap("Assets/Images/Stats/PlaylistIcons/teams.png"); // don't dispose - canvas.DrawBitmap(teamsIcon, new SKPoint(683, 594)); + canvas.DrawBitmap(teamsIcon, new SKPoint(683, 594), SKSamplingOptions.Default); - canvas.DrawAlignedText("Games", new SKPoint(537, 644), titlePaint); + canvas.DrawAlignedText("Games", new SKPoint(537, 644), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Wins", new SKPoint(698, 644), titlePaint); + canvas.DrawAlignedText("Wins", new SKPoint(698, 644), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Win%", new SKPoint(837, 644), titlePaint); + canvas.DrawAlignedText("Win%", new SKPoint(837, 644), titlePaintFont, titlePaint); - canvas.DrawAlignedText("Kills", new SKPoint(954, 644), titlePaint); + canvas.DrawAlignedText("Kills", new SKPoint(954, 644), titlePaintFont, titlePaint); - canvas.DrawAlignedText("K/D", new SKPoint(1115, 644), titlePaint); + canvas.DrawAlignedText("K/D", new SKPoint(1115, 644), titlePaintFont, titlePaint); } return bitmap; @@ -317,67 +319,67 @@ private async Task GenerateImage(Stats stats, StatsType type, SKBitmap var bitmap = new SKBitmap(imageInfo); using var canvas = new SKCanvas(bitmap); - canvas.DrawBitmap(templateBitmap, SKPoint.Empty); + canvas.DrawBitmap(templateBitmap, SKPoint.Empty, SKSamplingOptions.Default); var fortniteFont = await assets.GetFont("Assets/Fonts/Fortnite.ttf"); // don't dispose var segoeFont = await assets.GetFont("Assets/Fonts/Segoe.ttf"); // don't dispose using var namePaint = new SKPaint(); + using var namePaintFont = new SKFont(); namePaint.IsAntialias = true; namePaint.Color = SKColors.White; - namePaint.Typeface = segoeFont; - namePaint.TextSize = 64; - namePaint.FilterQuality = SKFilterQuality.Medium; + namePaintFont.Typeface = segoeFont; + namePaintFont.Size = 64; using var titlePaint = new SKPaint(); + using var titlePaintFont = new SKFont(); titlePaint.IsAntialias = true; titlePaint.Color = SKColors.LightGray; - titlePaint.Typeface = segoeFont; - titlePaint.TextSize = 20; - titlePaint.FilterQuality = SKFilterQuality.Medium; + titlePaintFont.Typeface = segoeFont; + titlePaintFont.Size = 20; using var valuePaint = new SKPaint(); + using var valuePaintFont = new SKFont(); valuePaint.IsAntialias = true; valuePaint.Color = SKColors.White; - valuePaint.Typeface = fortniteFont; - valuePaint.TextSize = 35; - valuePaint.FilterQuality = SKFilterQuality.Medium; + valuePaintFont.Typeface = fortniteFont; + valuePaintFont.Size = 35; using var divisionPaint = new SKPaint(); + using var divisionPaintFont = new SKFont(); divisionPaint.IsAntialias = true; divisionPaint.Color = SKColors.White; - divisionPaint.Typeface = fortniteFont; - divisionPaint.TextSize = 35; - divisionPaint.FilterQuality = SKFilterQuality.Medium; + divisionPaintFont.Typeface = fortniteFont; + divisionPaintFont.Size = 35; using var rankProgressPaint = new SKPaint(); + using var rankProgressPaintFont = new SKFont(); rankProgressPaint.IsAntialias = true; rankProgressPaint.Color = SKColors.White.WithAlpha((int)(255 * 0.7)); - rankProgressPaint.Typeface = segoeFont; - rankProgressPaint.TextSize = 16; - rankProgressPaint.FilterQuality = SKFilterQuality.Medium; + rankProgressPaintFont.Typeface = segoeFont; + rankProgressPaintFont.Size = 16; using var rankingPaint = new SKPaint(); + using var rankingPaintFont = new SKFont(); rankingPaint.IsAntialias = true; rankingPaint.Color = SKColors.White; - rankingPaint.Typeface = fortniteFont; - rankingPaint.TextSize = 20; - rankingPaint.FilterQuality = SKFilterQuality.Medium; + rankingPaintFont.Typeface = fortniteFont; + rankingPaintFont.Size = 20; var inputIcon = await assets.GetBitmap($"Assets/Images/Stats/InputTypes/{stats.InputType}.png"); // don't dispose - canvas.DrawBitmap(inputIcon, 50, 50); + canvas.DrawBitmap(inputIcon, 50, 50, SKSamplingOptions.Default); - var playerNameWidth = namePaint.MeasureText(stats.PlayerName); - canvas.DrawAlignedText(stats.PlayerName, new SKPoint(159, 58), namePaint); + var playerNameWidth = namePaintFont.MeasureText(stats.PlayerName, namePaint); + canvas.DrawAlignedText(stats.PlayerName, new SKPoint(159, 58), namePaintFont, namePaint); if (stats.IsVerified) { var verifiedIcon = await assets.GetBitmap("Assets/Images/Stats/Verified.png"); // don't dispose - canvas.DrawBitmap(verifiedIcon, 159 + playerNameWidth + 5, 47); + canvas.DrawBitmap(verifiedIcon, 159 + playerNameWidth + 5, 47, SKSamplingOptions.Default); using var discordBoxBitmap = await ImageUtils.GenerateDiscordBox(assets, stats.UserName ?? "???#0000"); - canvas.DrawBitmap(discordBoxBitmap, imageInfo.Width - 50 - discordBoxBitmap.Width, 39); + canvas.DrawBitmap(discordBoxBitmap, imageInfo.Width - 50 - discordBoxBitmap.Width, 39, SKSamplingOptions.Default); } if (type == StatsType.Competitive) @@ -396,11 +398,11 @@ private async Task GenerateImage(Stats stats, StatsType type, SKBitmap var divisionIconBitmap = await assets.GetBitmap( $"Assets/Images/Stats/DivisionIcons/{divisionAssetName}.png"); // don't dispose - canvas.DrawBitmap(divisionIconBitmap, x - divisionIconBitmap!.Width / 2f, 109); + canvas.DrawBitmap(divisionIconBitmap, x - divisionIconBitmap!.Width / 2f, 109, SKSamplingOptions.Default); canvas.DrawAlignedText( rankedStatsEntry.CurrentDivisionName, - new SKPoint(x, 206), + new SKPoint(x, 206), divisionPaintFont, divisionPaint, SKTextAlign.Center); @@ -408,7 +410,7 @@ await assets.GetBitmap( { const int maxBarWidth = 130, barHeight = 6; var progressText = $"{(int)(rankedStatsEntry.Progress * 100)}%"; - var progressTextWidth = rankProgressPaint.MeasureText(progressText); + var progressTextWidth = rankProgressPaintFont.MeasureText(progressText, rankProgressPaint); var barX = x - progressTextWidth / 2f - maxBarWidth / 2f; using var barBackgroundPaint = new SKPaint(); @@ -434,52 +436,52 @@ await assets.GetBitmap( canvas.DrawRoundRect(barX, 250, rankProgressBarWidth, barHeight, 10, 10, battlePassBarPaint); } - canvas.DrawAlignedText(progressText, new SKPoint(barX + maxBarWidth + 7, 247), rankProgressPaint); + canvas.DrawAlignedText(progressText, new SKPoint(barX + maxBarWidth + 7, 247), rankProgressPaintFont, rankProgressPaint); } else { canvas.DrawAlignedText( rankedStatsEntry.Ranking, - new SKPoint(x, 245), + new SKPoint(x, 245), rankingPaintFont, rankingPaint, SKTextAlign.Center); } } - canvas.DrawAlignedText(stats.Competitive.Earnings, new SKPoint(70, 365), valuePaint); + canvas.DrawAlignedText(stats.Competitive.Earnings, new SKPoint(70, 365), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Competitive.PowerRanking, new SKPoint(250, 365), valuePaint); + canvas.DrawAlignedText(stats.Competitive.PowerRanking, new SKPoint(250, 365), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.MatchesPlayed, new SKPoint(70, 441), valuePaint); + canvas.DrawAlignedText(stats.Overall.MatchesPlayed, new SKPoint(70, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.Wins, new SKPoint(231, 441), valuePaint); + canvas.DrawAlignedText(stats.Overall.Wins, new SKPoint(231, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.WinRatio, new SKPoint(370, 441), valuePaint); + canvas.DrawAlignedText(stats.Overall.WinRatio, new SKPoint(370, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.Kills, new SKPoint(70, 518), valuePaint); + canvas.DrawAlignedText(stats.Overall.Kills, new SKPoint(70, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.KD, new SKPoint(231, 518), valuePaint); + canvas.DrawAlignedText(stats.Overall.KD, new SKPoint(231, 518), valuePaintFont, valuePaint); } else { - canvas.DrawAlignedText(stats.Overall.MatchesPlayed, new SKPoint(70, 211), valuePaint); + canvas.DrawAlignedText(stats.Overall.MatchesPlayed, new SKPoint(70, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.Wins, new SKPoint(231, 211), valuePaint); + canvas.DrawAlignedText(stats.Overall.Wins, new SKPoint(231, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.WinRatio, new SKPoint(370, 211), valuePaint); + canvas.DrawAlignedText(stats.Overall.WinRatio, new SKPoint(370, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.Kills, new SKPoint(70, 288), valuePaint); + canvas.DrawAlignedText(stats.Overall.Kills, new SKPoint(70, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Overall.KD, new SKPoint(231, 288), valuePaint); + canvas.DrawAlignedText(stats.Overall.KD, new SKPoint(231, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Playtime.Days, new SKPoint(70, 369), valuePaint); + canvas.DrawAlignedText(stats.Playtime.Days, new SKPoint(70, 369), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Playtime.Hours, new SKPoint(147, 369), valuePaint); + canvas.DrawAlignedText(stats.Playtime.Hours, new SKPoint(147, 369), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Playtime.Minutes, new SKPoint(213, 369), valuePaint); + canvas.DrawAlignedText(stats.Playtime.Minutes, new SKPoint(213, 369), valuePaintFont, valuePaint); var battlePassLevel = ((int)stats.BattlePassLevel).ToString(); - canvas.DrawAlignedText(battlePassLevel, new SKPoint(70, 479), valuePaint); + canvas.DrawAlignedText(battlePassLevel, new SKPoint(70, 479), valuePaintFont, valuePaint); const int maxBarWidth = 309, barHeight = 20; @@ -503,68 +505,68 @@ await assets.GetBitmap( } } - canvas.DrawAlignedText(stats.Solo.MatchesPlayed, new SKPoint(537, 211), valuePaint); + canvas.DrawAlignedText(stats.Solo.MatchesPlayed, new SKPoint(537, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Solo.Wins, new SKPoint(698, 211), valuePaint); + canvas.DrawAlignedText(stats.Solo.Wins, new SKPoint(698, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Solo.WinRatio, new SKPoint(837, 211), valuePaint); + canvas.DrawAlignedText(stats.Solo.WinRatio, new SKPoint(837, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Solo.Kills, new SKPoint(537, 288), valuePaint); + canvas.DrawAlignedText(stats.Solo.Kills, new SKPoint(537, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Solo.KD, new SKPoint(698, 288), valuePaint); + canvas.DrawAlignedText(stats.Solo.KD, new SKPoint(698, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Solo.Top25!, new SKPoint(837, 288), valuePaint); + canvas.DrawAlignedText(stats.Solo.Top25!, new SKPoint(837, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.MatchesPlayed, new SKPoint(1016, 211), valuePaint); + canvas.DrawAlignedText(stats.Duos.MatchesPlayed, new SKPoint(1016, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.Wins, new SKPoint(1177, 211), valuePaint); + canvas.DrawAlignedText(stats.Duos.Wins, new SKPoint(1177, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.WinRatio, new SKPoint(1316, 211), valuePaint); + canvas.DrawAlignedText(stats.Duos.WinRatio, new SKPoint(1316, 211), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.Kills, new SKPoint(1016, 288), valuePaint); + canvas.DrawAlignedText(stats.Duos.Kills, new SKPoint(1016, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.KD, new SKPoint(1177, 288), valuePaint); + canvas.DrawAlignedText(stats.Duos.KD, new SKPoint(1177, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Duos.Top12!, new SKPoint(1316, 288), valuePaint); + canvas.DrawAlignedText(stats.Duos.Top12!, new SKPoint(1316, 288), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.MatchesPlayed, new SKPoint(537, 441), valuePaint); + canvas.DrawAlignedText(stats.Trios.MatchesPlayed, new SKPoint(537, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.Wins, new SKPoint(698, 441), valuePaint); + canvas.DrawAlignedText(stats.Trios.Wins, new SKPoint(698, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.WinRatio, new SKPoint(837, 441), valuePaint); + canvas.DrawAlignedText(stats.Trios.WinRatio, new SKPoint(837, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.Kills, new SKPoint(537, 518), valuePaint); + canvas.DrawAlignedText(stats.Trios.Kills, new SKPoint(537, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.KD, new SKPoint(698, 518), valuePaint); + canvas.DrawAlignedText(stats.Trios.KD, new SKPoint(698, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Trios.Top6!, new SKPoint(837, 518), valuePaint); + canvas.DrawAlignedText(stats.Trios.Top6!, new SKPoint(837, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.MatchesPlayed, new SKPoint(1016, 441), valuePaint); + canvas.DrawAlignedText(stats.Squads.MatchesPlayed, new SKPoint(1016, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.Wins, new SKPoint(1177, 441), valuePaint); + canvas.DrawAlignedText(stats.Squads.Wins, new SKPoint(1177, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.WinRatio, new SKPoint(1316, 441), valuePaint); + canvas.DrawAlignedText(stats.Squads.WinRatio, new SKPoint(1316, 441), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.Kills, new SKPoint(1016, 518), valuePaint); + canvas.DrawAlignedText(stats.Squads.Kills, new SKPoint(1016, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.KD, new SKPoint(1177, 518), valuePaint); + canvas.DrawAlignedText(stats.Squads.KD, new SKPoint(1177, 518), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Squads.Top6!, new SKPoint(1316, 518), valuePaint); + canvas.DrawAlignedText(stats.Squads.Top6!, new SKPoint(1316, 518), valuePaintFont, valuePaint); if (type == StatsType.Normal && stats.Teams is not null) { - canvas.DrawAlignedText(stats.Teams.MatchesPlayed, new SKPoint(537, 671), valuePaint); + canvas.DrawAlignedText(stats.Teams.MatchesPlayed, new SKPoint(537, 671), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Teams.Wins, new SKPoint(698, 671), valuePaint); + canvas.DrawAlignedText(stats.Teams.Wins, new SKPoint(698, 671), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Teams.WinRatio, new SKPoint(837, 671), valuePaint); + canvas.DrawAlignedText(stats.Teams.WinRatio, new SKPoint(837, 671), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Teams.Kills, new SKPoint(954, 671), valuePaint); + canvas.DrawAlignedText(stats.Teams.Kills, new SKPoint(954, 671), valuePaintFont, valuePaint); - canvas.DrawAlignedText(stats.Teams.KD, new SKPoint(1115, 671), valuePaint); + canvas.DrawAlignedText(stats.Teams.KD, new SKPoint(1115, 671), valuePaintFont, valuePaint); } return bitmap; @@ -582,6 +584,6 @@ private static void DrawBlurredRoundRect(SKBitmap bitmap, SKRoundRect rect) paint.IsAntialias = true; paint.ImageFilter = _blurredFilter; - canvas.DrawBitmap(bitmap, 0, 0, paint); + canvas.DrawBitmap(bitmap, 0, 0, SKSamplingOptions.Default, paint); } } diff --git a/Controllers/UtilsImageController.cs b/Controllers/UtilsImageController.cs index a25006c..177fc04 100644 --- a/Controllers/UtilsImageController.cs +++ b/Controllers/UtilsImageController.cs @@ -48,28 +48,30 @@ public async Task GenerateProgressBar(ProgressBar progressBar) var segoeFont = await assets.GetFont("Assets/Fonts/Segoe.ttf"); using var textPaint = new SKPaint(); + using var textPaintFont = new SKFont(); textPaint.IsAntialias = true; textPaint.Color = SKColors.White; - textPaint.TextSize = 20; - textPaint.Typeface = segoeFont; + textPaintFont.Size = 20; + textPaintFont.Typeface = segoeFont; canvas.DrawAlignedText( progressBar.Text, - new SKPoint(500 + 5, bitmap.Height / 2f), + new SKPoint(500 + 5, bitmap.Height / 2f), textPaintFont, textPaint, verticalAlignment: VerticalTextAlignment.Center); if (progressBar.BarText != null) { using var barTextPaint = new SKPaint(); + using var barTextPaintFont = new SKFont(); barTextPaint.IsAntialias = true; barTextPaint.Color = SKColors.White; - barTextPaint.TextSize = 15; - barTextPaint.Typeface = segoeFont; + barTextPaintFont.Size = 15; + barTextPaintFont.Typeface = segoeFont; canvas.DrawAlignedText( progressBar.BarText, - SKRect.Create(0, 0, 500, bitmap.Height), + SKRect.Create(0, 0, 500, bitmap.Height), barTextPaintFont, barTextPaint, SKTextAlign.Center, VerticalTextAlignment.Center); @@ -103,7 +105,7 @@ await assets.GetBitmap( var mx = (drop.X + worldRadius) / (worldRadius * 2f) * bitmap.Width + xOffset; var my = (drop.Y + worldRadius) / (worldRadius * 2f) * bitmap.Height + yOffset; - canvas.DrawBitmap(markerBitmap, mx - markerBitmap!.Width / 2f, my - markerBitmap.Height); + canvas.DrawBitmap(markerBitmap, mx - markerBitmap!.Width / 2f, my - markerBitmap.Height, SKSamplingOptions.Default); var data = bitmap.Encode(SKEncodedImageFormat.Jpeg, 100); return File(data.AsStream(true), "image/jpeg"); diff --git a/EasyFortniteStats-ImageApi.csproj b/EasyFortniteStats-ImageApi.csproj index 5bca900..a9efbf2 100644 --- a/EasyFortniteStats-ImageApi.csproj +++ b/EasyFortniteStats-ImageApi.csproj @@ -11,8 +11,8 @@ - - + + diff --git a/ImageUtils.cs b/ImageUtils.cs index 4861921..7269b8e 100644 --- a/ImageUtils.cs +++ b/ImageUtils.cs @@ -22,13 +22,13 @@ public static async Task GenerateDiscordBox(SharedAssets assets, strin var segoeFont = await assets.GetFont("Assets/Fonts/Segoe.ttf"); // don't dispose using var discordTagTextPaint = new SKPaint(); + using var discordTagTextPaintFont = new SKFont(); discordTagTextPaint.IsAntialias = true; discordTagTextPaint.Color = SKColors.White; - discordTagTextPaint.Typeface = segoeFont; - discordTagTextPaint.TextSize = 25 * resizeFactor; + discordTagTextPaintFont.Typeface = segoeFont; + discordTagTextPaintFont.Size = 25 * resizeFactor; - var discordTagTextBounds = new SKRect(); - discordTagTextPaint.MeasureText(username, ref discordTagTextBounds); + discordTagTextPaintFont.MeasureText(username, out var discordTagTextBounds, discordTagTextPaint); var imageInfo = new SKImageInfo( (int)Math.Min(discordTagTextBounds.Width + (10 + 2 * 15 + 50) * resizeFactor, 459 * resizeFactor), @@ -51,18 +51,17 @@ public static async Task GenerateDiscordBox(SharedAssets assets, strin using var drawdiscordLogoPaint = new SKPaint(); drawdiscordLogoPaint.IsAntialias = true; - drawdiscordLogoPaint.FilterQuality = SKFilterQuality.High; - canvas.DrawBitmap(discordLogoBitmap, SKRect.Create(logoX, logoY, logoResizeWidth, logoResizeHeight), drawdiscordLogoPaint); + canvas.DrawBitmap(discordLogoBitmap, SKRect.Create(logoX, logoY, logoResizeWidth, logoResizeHeight), SKSamplingOptions.Default, drawdiscordLogoPaint); while (discordTagTextBounds.Width + (10 + 2 * 15 + 50) * resizeFactor > imageInfo.Width) { - discordTagTextPaint.TextSize--; - discordTagTextPaint.MeasureText(username, ref discordTagTextBounds); + discordTagTextPaintFont.Size--; + discordTagTextPaintFont.MeasureText(username, out discordTagTextBounds, discordTagTextPaint); } canvas.DrawAlignedText( username, - new SKPoint((10 + 15) * resizeFactor + logoResizeWidth, imageInfo.Height / 2f), + new SKPoint((10 + 15) * resizeFactor + logoResizeWidth, imageInfo.Height / 2f), discordTagTextPaintFont, discordTagTextPaint, verticalAlignment: VerticalTextAlignment.Center); @@ -84,7 +83,7 @@ private static SKBitmap RotateBitmap(SKBitmap bitmap, float angle) rotatedCanvas.Translate(rotatedWidth / 2f, rotatedHeight / 2f); rotatedCanvas.RotateDegrees(-angle); rotatedCanvas.Translate(-originalWidth / 2f, -originalHeight / 2f); - rotatedCanvas.DrawBitmap(bitmap, SKPoint.Empty); + rotatedCanvas.DrawBitmap(bitmap, SKPoint.Empty, SKSamplingOptions.Default); return rotatedBitmap; } @@ -100,12 +99,13 @@ public static SKBitmap GenerateRarityStripe(int width, SKColor rarityColor) paint.Color = rarityColor; paint.Style = SKPaintStyle.Fill; - using var path = new SKPath(); - path.MoveTo(0, imageInfo.Height - 5); - path.LineTo(imageInfo.Width, 0); - path.LineTo(imageInfo.Width, imageInfo.Height - 6); - path.LineTo(0, imageInfo.Height); - path.Close(); + using var pathBuilder = new SKPathBuilder(); + pathBuilder.MoveTo(0, imageInfo.Height - 5); + pathBuilder.LineTo(imageInfo.Width, 0); + pathBuilder.LineTo(imageInfo.Width, imageInfo.Height - 6); + pathBuilder.LineTo(0, imageInfo.Height); + pathBuilder.Close(); + using var path = pathBuilder.Detach(); canvas.DrawPath(path, paint); @@ -130,9 +130,9 @@ public static SKBitmap GenerateItemCardOverlay(int width, SKBitmap? icon = null) if (icon is not null) { using var rotatedVbucksBitmap = RotateBitmap(icon, -20); - using var resizedVBucksBitmap = rotatedVbucksBitmap.Resize(new SKImageInfo(47, 47), SKFilterQuality.Medium); + using var resizedVBucksBitmap = rotatedVbucksBitmap.Resize(new SKImageInfo(47, 47), new SKSamplingOptions(SKFilterMode.Linear)); - canvas.DrawBitmap(resizedVBucksBitmap, new SKPoint(imageInfo.Width - 45, imageInfo.Height - 35)); + canvas.DrawBitmap(resizedVBucksBitmap, new SKPoint(imageInfo.Width - 45, imageInfo.Height - 35), SKSamplingOptions.Default); } using (var paint = new SKPaint()) @@ -141,12 +141,13 @@ public static SKBitmap GenerateItemCardOverlay(int width, SKBitmap? icon = null) paint.Color = new SKColor(30, 30, 30); paint.Style = SKPaintStyle.Fill; - using var path = new SKPath(); - path.MoveTo(0, imageInfo.Height - 29); - path.LineTo(imageInfo.Width, imageInfo.Height - 29); - path.LineTo(imageInfo.Width, imageInfo.Height - 25); - path.LineTo(0, imageInfo.Height - 24); - path.Close(); + using var pathBuilder = new SKPathBuilder(); + pathBuilder.MoveTo(0, imageInfo.Height - 29); + pathBuilder.LineTo(imageInfo.Width, imageInfo.Height - 29); + pathBuilder.LineTo(imageInfo.Width, imageInfo.Height - 25); + pathBuilder.LineTo(0, imageInfo.Height - 24); + pathBuilder.Close(); + using var path = pathBuilder.Detach(); canvas.DrawPath(path, paint); diff --git a/SKPaintSafe.cs b/SKPaintSafe.cs index c3efc14..118c9e7 100644 --- a/SKPaintSafe.cs +++ b/SKPaintSafe.cs @@ -30,4 +30,4 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } -} \ No newline at end of file +} diff --git a/TextDrawingExtensions.cs b/TextDrawingExtensions.cs index 1c99cb7..bf9ab4a 100644 --- a/TextDrawingExtensions.cs +++ b/TextDrawingExtensions.cs @@ -16,35 +16,27 @@ public static class TextDrawingExtensions { public void DrawAlignedText(string text, SKPoint anchor, + SKFont font, SKPaint paint, SKTextAlign horizontalAlignment = SKTextAlign.Left, VerticalTextAlignment verticalAlignment = VerticalTextAlignment.Top) - { - var bounds = new SKRect(); - paint.MeasureText(text, ref bounds); - var baseline = verticalAlignment switch { - VerticalTextAlignment.Top => anchor.Y - bounds.Top, - VerticalTextAlignment.Center => anchor.Y - bounds.MidY, - VerticalTextAlignment.Baseline => anchor.Y, - VerticalTextAlignment.Bottom => anchor.Y - bounds.Bottom, - _ => throw new ArgumentOutOfRangeException(nameof(verticalAlignment), verticalAlignment, null) - }; - - var previousAlignment = paint.TextAlign; - try + font.MeasureText(text, out var bounds, paint); + var baseline = verticalAlignment switch { - paint.TextAlign = horizontalAlignment; - canvas.DrawText(text, anchor.X, baseline, paint); - } - finally - { - paint.TextAlign = previousAlignment; - } - } + VerticalTextAlignment.Top => anchor.Y - bounds.Top, + VerticalTextAlignment.Center => anchor.Y - bounds.MidY, + VerticalTextAlignment.Baseline => anchor.Y, + VerticalTextAlignment.Bottom => anchor.Y - bounds.Bottom, + _ => throw new ArgumentOutOfRangeException(nameof(verticalAlignment), verticalAlignment, null) + }; + + canvas.DrawText(text, anchor.X, baseline, horizontalAlignment, font, paint); + } public void DrawAlignedText(string text, SKRect area, + SKFont font, SKPaint paint, SKTextAlign horizontalAlignment = SKTextAlign.Left, VerticalTextAlignment verticalAlignment = VerticalTextAlignment.Top) @@ -66,7 +58,7 @@ public void DrawAlignedText(string text, _ => throw new ArgumentOutOfRangeException(nameof(verticalAlignment), verticalAlignment, null) }; - canvas.DrawAlignedText(text, new SKPoint(x, y), paint, horizontalAlignment, verticalAlignment); + canvas.DrawAlignedText(text, new SKPoint(x, y), font, paint, horizontalAlignment, verticalAlignment); } } }