Files
bag-tabs/scripts/generate_tab_mockups.ps1

328 lines
11 KiB
PowerShell

$ErrorActionPreference = 'Stop'
Add-Type -AssemblyName System.Drawing
$root = Split-Path -Parent $PSScriptRoot
$guiDir = Join-Path $root 'src\main\resources\assets\bagtabs\textures\gui'
$itemDir = Join-Path $root 'src\main\resources\assets\bagtabs\textures\item'
$outDir = Join-Path $root 'art\mockups'
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
function New-Bitmap {
param([int]$Width, [int]$Height)
return [System.Drawing.Bitmap]::new($Width, $Height, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
}
function Load-Bitmap {
param([string]$Path)
return [System.Drawing.Bitmap]::new($Path)
}
function Get-Half {
param(
[System.Drawing.Bitmap]$Image,
[bool]$RightHalf = $false
)
$halfWidth = [int]($Image.Width / 2)
$sourceX = if ($RightHalf) { $halfWidth } else { 0 }
$bmp = New-Bitmap $halfWidth $Image.Height
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
try {
$graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor
$graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half
$graphics.DrawImage(
$Image,
[System.Drawing.Rectangle]::new(0, 0, $halfWidth, $Image.Height),
[System.Drawing.Rectangle]::new($sourceX, 0, $halfWidth, $Image.Height),
[System.Drawing.GraphicsUnit]::Pixel
)
} finally {
$graphics.Dispose()
}
return $bmp
}
function Tint-Bitmap {
param(
[System.Drawing.Bitmap]$Image,
[Nullable[int]]$Rgb
)
$bmp = New-Bitmap $Image.Width $Image.Height
$tr = if ($Rgb.HasValue) { (($Rgb.Value -shr 16) -band 0xFF) / 255.0 } else { 1.0 }
$tg = if ($Rgb.HasValue) { (($Rgb.Value -shr 8) -band 0xFF) / 255.0 } else { 1.0 }
$tb = if ($Rgb.HasValue) { ($Rgb.Value -band 0xFF) / 255.0 } else { 1.0 }
for ($x = 0; $x -lt $Image.Width; $x++) {
for ($y = 0; $y -lt $Image.Height; $y++) {
$src = $Image.GetPixel($x, $y)
if ($src.A -eq 0) {
$bmp.SetPixel($x, $y, $src)
continue
}
$r = [Math]::Min(255, [int]($src.R * $tr))
$g = [Math]::Min(255, [int]($src.G * $tg))
$b = [Math]::Min(255, [int]($src.B * $tb))
$bmp.SetPixel($x, $y, [System.Drawing.Color]::FromArgb($src.A, $r, $g, $b))
}
}
return $bmp
}
function Compose-Layered {
param(
[System.Drawing.Bitmap]$Base,
[System.Drawing.Bitmap]$Overlay
)
$bmp = New-Bitmap $Base.Width $Base.Height
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
try {
$graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor
$graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half
$graphics.DrawImage($Base, 0, 0, $Base.Width, $Base.Height)
$graphics.DrawImage($Overlay, 0, 0, $Overlay.Width, $Overlay.Height)
} finally {
$graphics.Dispose()
}
return $bmp
}
function Draw-ScaledBitmap {
param(
[System.Drawing.Graphics]$Graphics,
[System.Drawing.Bitmap]$Bitmap,
[int]$X,
[int]$Y,
[int]$Width,
[int]$Height
)
$Graphics.DrawImage(
$Bitmap,
[System.Drawing.Rectangle]::new($X, $Y, $Width, $Height),
[System.Drawing.Rectangle]::new(0, 0, $Bitmap.Width, $Bitmap.Height),
[System.Drawing.GraphicsUnit]::Pixel
)
}
function Draw-Pin {
param([System.Drawing.Graphics]$Graphics, [int]$X, [int]$Y)
$yellow = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 235, 205, 86))
$red = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 205, 55, 44))
try {
$Graphics.FillRectangle($yellow, $X + 1, $Y + 1, 3, 5)
$Graphics.FillRectangle($yellow, $X + 2, $Y + 6, 2, 1)
$Graphics.FillRectangle($red, $X, $Y + 2, 1, 1)
} finally {
$yellow.Dispose()
$red.Dispose()
}
}
function Draw-Fullness {
param(
[System.Drawing.Graphics]$Graphics,
[int]$X,
[int]$Y,
[int]$Width,
[int]$Height,
[double]$Percent
)
$back = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 40, 40, 40))
$fill = [System.Drawing.SolidBrush]::new([System.Drawing.Color]::FromArgb(255, 105, 180, 90))
try {
$Graphics.FillRectangle($back, $X, $Y, $Width, $Height)
$fillHeight = [Math]::Max(1, [int]([Math]::Round($Height * $Percent)))
$Graphics.FillRectangle($fill, $X, $Y + ($Height - $fillHeight), $Width, $fillHeight)
} finally {
$back.Dispose()
$fill.Dispose()
}
}
function Draw-BagItem {
param(
[System.Drawing.Graphics]$Graphics,
[System.Drawing.Bitmap]$BagBase,
[System.Drawing.Bitmap]$BagOverlay,
[Nullable[int]]$Color,
[int]$X,
[int]$Y,
[int]$Size
)
$tinted = Tint-Bitmap $BagBase $Color
$bag = Compose-Layered $tinted $BagOverlay
try {
Draw-ScaledBitmap $Graphics $bag $X $Y $Size $Size
} finally {
$tinted.Dispose()
$bag.Dispose()
}
}
function Draw-CompactText {
param(
[System.Drawing.Graphics]$Graphics,
[string]$Line1,
[string]$Line2,
[int]$X,
[int]$Y,
[int]$Width,
[int]$Height,
[System.Drawing.Color]$Color
)
$font = [System.Drawing.Font]::new('Microsoft Sans Serif', 5.5, [System.Drawing.FontStyle]::Bold, [System.Drawing.GraphicsUnit]::Pixel)
$brush = [System.Drawing.SolidBrush]::new($Color)
$format = [System.Drawing.StringFormat]::new()
$format.Alignment = [System.Drawing.StringAlignment]::Center
$format.LineAlignment = [System.Drawing.StringAlignment]::Center
try {
$Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::SingleBitPerPixelGridFit
$Graphics.DrawString($Line1, $font, $brush, [System.Drawing.RectangleF]::new($X, $Y - 1, $Width, [int]($Height / 2)), $format)
$Graphics.DrawString($Line2, $font, $brush, [System.Drawing.RectangleF]::new($X, $Y + [int]($Height / 2) - 2, $Width, [int]($Height / 2) + 2), $format)
} finally {
$font.Dispose()
$brush.Dispose()
$format.Dispose()
}
}
function New-Canvas {
param([int]$Width, [int]$Height)
$bmp = New-Bitmap $Width $Height
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
$graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::NearestNeighbor
$graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::Half
$graphics.Clear([System.Drawing.Color]::FromArgb(255, 48, 48, 52))
return @{ Bitmap = $bmp; Graphics = $graphics }
}
$bagNamer = Load-Bitmap (Join-Path $guiDir 'bag_namer.png')
$tabBase = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_base.png'))
$tabOverlay = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_overlay.png'))
$compactBase = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_compact_base.png'))
$compactOverlay = Get-Half (Load-Bitmap (Join-Path $guiDir 'bag_tabs_compact_overlay.png'))
$dockTab = Load-Bitmap (Join-Path $guiDir 'bag_tabs_dock.png')
$gear = Load-Bitmap (Join-Path $guiDir 'dock_gear.png')
$lock = Load-Bitmap (Join-Path $guiDir 'dock_lock.png')
$prev = Load-Bitmap (Join-Path $guiDir 'dock_prev.png')
$next = Load-Bitmap (Join-Path $guiDir 'dock_next.png')
$bagBase = Load-Bitmap (Join-Path $itemDir 'bag.png')
$bagOverlay = Load-Bitmap (Join-Path $itemDir 'bag_overlay.png')
$bagColors = @($null, 0x8032A8, 0xE4E5DE)
$bagFullness = @(0.82, 0.56, 0.31)
$compactNames = @(
@{ Line1 = 'Canvas'; Line2 = 'Bag' },
@{ Line1 = 'Purple'; Line2 = 'Bag' },
@{ Line1 = 'Pale'; Line2 = 'Bag' }
)
function Draw-StandardStrip {
param(
[System.Drawing.Graphics]$Graphics,
[int]$X,
[int]$Y,
[bool]$Compact
)
Draw-ScaledBitmap $Graphics $dockTab $X $Y 18 22
Draw-ScaledBitmap $Graphics $gear ($X + 5) ($Y + 2) 8 8
Draw-ScaledBitmap $Graphics $lock ($X + 5) ($Y + 12) 8 8
$tabStep = 21
$tabX = $X + 17
for ($i = 0; $i -lt 3; $i++) {
if ($Compact) {
$tintedBase = Tint-Bitmap $compactBase $bagColors[$i]
$tab = Compose-Layered $tintedBase $compactOverlay
try {
Draw-ScaledBitmap $Graphics $tab ($tabX + ($i * $tabStep)) ($Y + 11) 22 11
} finally {
$tintedBase.Dispose()
$tab.Dispose()
}
$textColor = if ($bagColors[$i] -eq $null -or $bagColors[$i] -gt 0x7F7F7F) {
[System.Drawing.Color]::FromArgb(255, 30, 30, 30)
} else {
[System.Drawing.Color]::White
}
Draw-CompactText $Graphics $compactNames[$i].Line1 $compactNames[$i].Line2 ($tabX + ($i * $tabStep) + 2) ($Y + 11) 18 10 $textColor
Draw-Fullness $Graphics ($tabX + ($i * $tabStep) + 18) ($Y + 12) 2 8 $bagFullness[$i]
} else {
$tintedBase = Tint-Bitmap $tabBase $bagColors[$i]
$tab = Compose-Layered $tintedBase $tabOverlay
try {
Draw-ScaledBitmap $Graphics $tab ($tabX + ($i * $tabStep)) $Y 22 22
} finally {
$tintedBase.Dispose()
$tab.Dispose()
}
Draw-BagItem $Graphics $bagBase $bagOverlay $bagColors[$i] ($tabX + ($i * $tabStep) + 3) ($Y + 2) 16
Draw-Fullness $Graphics ($tabX + ($i * $tabStep) + 18) ($Y + 3) 2 15 $bagFullness[$i]
}
}
Draw-Pin $Graphics ($tabX + 1) ($Y + 1)
$scrollX = $tabX + (3 * $tabStep)
Draw-ScaledBitmap $Graphics $dockTab $scrollX $Y 18 22
Draw-ScaledBitmap $Graphics $prev ($scrollX + 5) ($Y + 2) 8 8
Draw-ScaledBitmap $Graphics $next ($scrollX + 5) ($Y + 12) 8 8
}
function Save-Mockup {
param(
[string]$Name,
[bool]$Compact,
[bool]$Floating
)
$canvas = New-Canvas 260 220
$bmp = $canvas.Bitmap
$graphics = $canvas.Graphics
try {
$guiX = 42
$guiY = 28
Draw-ScaledBitmap $graphics $bagNamer $guiX $guiY $bagNamer.Width $bagNamer.Height
if ($Floating) {
$stripX = $guiX + 18
$stripY = $guiY + $bagNamer.Height + 12
} else {
$stripX = $guiX + 2
$stripY = if ($Compact) { $guiY + $bagNamer.Height - 2 } else { $guiY + $bagNamer.Height - 3 }
}
Draw-StandardStrip $graphics $stripX $stripY $Compact
$bmp.Save((Join-Path $outDir $Name), [System.Drawing.Imaging.ImageFormat]::Png)
} finally {
$graphics.Dispose()
$bmp.Dispose()
}
}
Save-Mockup 'rename_docked_normal.png' $false $false
Save-Mockup 'rename_docked_compact.png' $true $false
Save-Mockup 'rename_floating_horizontal_normal.png' $false $true
Save-Mockup 'rename_floating_horizontal_compact.png' $true $true
$bagNamer.Dispose()
$tabBase.Dispose()
$tabOverlay.Dispose()
$compactBase.Dispose()
$compactOverlay.Dispose()
$dockTab.Dispose()
$gear.Dispose()
$lock.Dispose()
$prev.Dispose()
$next.Dispose()
$bagBase.Dispose()
$bagOverlay.Dispose()