stable
This commit is contained in:
commit
d55d8bc32d
93 files changed
+13507
No files matched your search
@@ -0,0 +1,104 @@
|
||||
# Haalt de Twemoji-set (emoji-datasource-twitter) en de CLDR-trefwoorden op en schrijft
|
||||
# een compacte catalogus naar src/Kniip/Assets/Emoji. Alleen opnieuw draaien bij een update.
|
||||
#
|
||||
# Twemoji-afbeeldingen: (c) Twitter, Inc en andere bijdragers, CC-BY 4.0.
|
||||
# Emoji-data: emoji-datasource (MIT). Trefwoorden: Unicode CLDR (Unicode License).
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
$datasourceVersion = '15.1.2'
|
||||
$cldrVersion = '46.0.0'
|
||||
|
||||
$root = Split-Path -Parent $PSScriptRoot
|
||||
$outDir = Join-Path $root 'src\Kniip\Assets\Emoji'
|
||||
New-Item -ItemType Directory -Force -Path $outDir | Out-Null
|
||||
|
||||
$datasource = "https://unpkg.com/emoji-datasource-twitter@$datasourceVersion"
|
||||
$cldr = "https://raw.githubusercontent.com/unicode-org/cldr-json/$cldrVersion/cldr-json"
|
||||
|
||||
function Get-Json([string]$url) {
|
||||
$bytes = (Invoke-WebRequest -Uri $url -UseBasicParsing).RawContentStream.ToArray()
|
||||
[Text.Encoding]::UTF8.GetString($bytes) | ConvertFrom-Json
|
||||
}
|
||||
|
||||
function Get-Annotations([string]$lang) {
|
||||
$map = @{}
|
||||
foreach ($kind in 'cldr-annotations-full/annotations', 'cldr-annotations-derived-full/annotationsDerived') {
|
||||
$json = Get-Json "$cldr/$kind/$lang/annotations.json"
|
||||
$set = if ($json.annotations) { $json.annotations.annotations } else { $json.annotationsDerived.annotations }
|
||||
foreach ($p in $set.PSObject.Properties) {
|
||||
$key = $p.Name.Replace([string][char]0xFE0F, '')
|
||||
$map[$key] = $p.Value
|
||||
}
|
||||
}
|
||||
$map
|
||||
}
|
||||
|
||||
Write-Host 'Spritesheet downloaden...'
|
||||
Invoke-WebRequest -Uri "$datasource/img/twitter/sheets/64.png" -OutFile (Join-Path $outDir 'twemoji-64.png') -UseBasicParsing
|
||||
|
||||
Write-Host 'emoji.json downloaden...'
|
||||
$emoji = Get-Json "$datasource/emoji.json"
|
||||
|
||||
Write-Host 'CLDR-trefwoorden downloaden...'
|
||||
$nl = Get-Annotations 'nl'
|
||||
$en = Get-Annotations 'en'
|
||||
|
||||
function Get-Char([string]$unified) {
|
||||
($unified -split '-' | ForEach-Object { [char]::ConvertFromUtf32([Convert]::ToInt32($_, 16)) }) -join ''
|
||||
}
|
||||
|
||||
$tones = @{ '1F3FB' = 1; '1F3FC' = 2; '1F3FD' = 3; '1F3FE' = 4; '1F3FF' = 5 }
|
||||
|
||||
$items = foreach ($e in $emoji) {
|
||||
if (-not $e.has_img_twitter -or $e.obsoleted_by -or $e.category -eq 'Component') { continue }
|
||||
|
||||
$key = (Get-Char $e.unified).Replace([string][char]0xFE0F, '')
|
||||
$nlEntry = $nl[$key]
|
||||
$enEntry = $en[$key]
|
||||
|
||||
$words = New-Object System.Collections.Generic.List[string]
|
||||
$words.AddRange([string[]]$e.short_names)
|
||||
if ($e.name) { $words.Add($e.name) }
|
||||
foreach ($entry in $nlEntry, $enEntry) {
|
||||
if ($entry) {
|
||||
if ($entry.tts) { $words.AddRange([string[]]$entry.tts) }
|
||||
if ($entry.default) { $words.AddRange([string[]]$entry.default) }
|
||||
}
|
||||
}
|
||||
|
||||
$skins = $null
|
||||
if ($e.skin_variations) {
|
||||
$skins = [ordered]@{}
|
||||
foreach ($p in $e.skin_variations.PSObject.Properties) {
|
||||
$parts = $p.Name -split '-'
|
||||
if (($parts | Select-Object -Unique).Count -ne 1 -or -not $tones.ContainsKey($parts[0])) { continue }
|
||||
if (-not $p.Value.has_img_twitter) { continue }
|
||||
$skins[[string]$tones[$parts[0]]] = @($p.Value.unified.ToLowerInvariant(), $p.Value.sheet_x, $p.Value.sheet_y)
|
||||
}
|
||||
if ($skins.Count -eq 0) { $skins = $null }
|
||||
}
|
||||
|
||||
$nameNl = if ($nlEntry -and $nlEntry.tts) { $nlEntry.tts[0] } else { $null }
|
||||
$nameEn = if ($enEntry -and $enEntry.tts) { $enEntry.tts[0] } elseif ($e.name) { $e.name.ToLowerInvariant() } else { $e.short_name }
|
||||
|
||||
$item = [ordered]@{
|
||||
u = $e.unified.ToLowerInvariant()
|
||||
c = $e.category
|
||||
o = $e.sort_order
|
||||
x = $e.sheet_x
|
||||
y = $e.sheet_y
|
||||
s = $e.short_name
|
||||
n = if ($nameNl) { $nameNl } else { $nameEn }
|
||||
k = (($words | ForEach-Object { $_.ToLowerInvariant().Replace('_', ' ') } | Select-Object -Unique) -join '|')
|
||||
}
|
||||
if ($skins) { $item['t'] = $skins }
|
||||
[pscustomobject]$item
|
||||
}
|
||||
|
||||
$items = $items | Sort-Object o
|
||||
$json = $items | ConvertTo-Json -Depth 5 -Compress
|
||||
[IO.File]::WriteAllText((Join-Path $outDir 'emoji.json'), $json, (New-Object Text.UTF8Encoding $false))
|
||||
|
||||
Write-Host "Klaar: $(@($items).Count) emoji naar $outDir"
|
||||
@@ -0,0 +1,108 @@
|
||||
# Genereert src/Kniip/AppIcon.ico (16-256 px) met System.Drawing.
|
||||
# Kleine formaten als 32-bit DIB, 256 px als PNG (standaard ICO-layout).
|
||||
param(
|
||||
[string]$Output = (Join-Path $PSScriptRoot '..\src\Kniip\AppIcon.ico')
|
||||
)
|
||||
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
function New-IconBitmap([int]$size) {
|
||||
$bmp = New-Object System.Drawing.Bitmap($size, $size, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
|
||||
$g = [System.Drawing.Graphics]::FromImage($bmp)
|
||||
$g.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::AntiAlias
|
||||
$g.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::AntiAliasGridFit
|
||||
$g.Clear([System.Drawing.Color]::Transparent)
|
||||
|
||||
$pad = [Math]::Max(1, [int]($size * 0.04))
|
||||
$rect = New-Object System.Drawing.RectangleF($pad, $pad, ($size - 2 * $pad), ($size - 2 * $pad))
|
||||
$radius = $size * 0.22
|
||||
$path = New-Object System.Drawing.Drawing2D.GraphicsPath
|
||||
$d = $radius * 2
|
||||
$path.AddArc($rect.X, $rect.Y, $d, $d, 180, 90)
|
||||
$path.AddArc($rect.Right - $d, $rect.Y, $d, $d, 270, 90)
|
||||
$path.AddArc($rect.Right - $d, $rect.Bottom - $d, $d, $d, 0, 90)
|
||||
$path.AddArc($rect.X, $rect.Bottom - $d, $d, $d, 90, 90)
|
||||
$path.CloseFigure()
|
||||
|
||||
$brush = New-Object System.Drawing.Drawing2D.LinearGradientBrush($rect,
|
||||
[System.Drawing.Color]::FromArgb(255, 0, 120, 212),
|
||||
[System.Drawing.Color]::FromArgb(255, 0, 84, 166), 90.0)
|
||||
$g.FillPath($brush, $path)
|
||||
|
||||
# Gestippeld selectiekader
|
||||
$inset = $size * 0.2
|
||||
$penW = [Math]::Max(1.0, $size / 16.0)
|
||||
$pen = New-Object System.Drawing.Pen([System.Drawing.Color]::White, $penW)
|
||||
if ($size -ge 32) { $pen.DashStyle = [System.Drawing.Drawing2D.DashStyle]::Dash }
|
||||
$g.DrawRectangle($pen, $inset, $inset, $size - 2 * $inset, $size * 0.5)
|
||||
|
||||
# Geel markeerstreepje
|
||||
$hl = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(255, 255, 214, 0))
|
||||
$g.FillRectangle($hl, $inset, $size * 0.74, $size * 0.36, [Math]::Max(1.0, $size * 0.09))
|
||||
|
||||
# Plus-badge
|
||||
$badge = $size * 0.36
|
||||
$bx = $size - $badge - $pad * 0.5
|
||||
$by = $size - $badge - $pad * 0.5
|
||||
$g.FillEllipse((New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(255, 232, 17, 35))), $bx, $by, $badge, $badge)
|
||||
$pw = [Math]::Max(1.0, $badge * 0.16)
|
||||
$plusPen = New-Object System.Drawing.Pen([System.Drawing.Color]::White, $pw)
|
||||
$c = $badge / 2
|
||||
$l = $badge * 0.27
|
||||
$g.DrawLine($plusPen, $bx + $c - $l, $by + $c, $bx + $c + $l, $by + $c)
|
||||
$g.DrawLine($plusPen, $bx + $c, $by + $c - $l, $bx + $c, $by + $c + $l)
|
||||
|
||||
$g.Dispose()
|
||||
return $bmp
|
||||
}
|
||||
|
||||
function Get-DibBytes([System.Drawing.Bitmap]$bmp) {
|
||||
$w = $bmp.Width; $h = $bmp.Height
|
||||
$ms = New-Object System.IO.MemoryStream
|
||||
$bw = New-Object System.IO.BinaryWriter($ms)
|
||||
$bw.Write([int]40); $bw.Write([int]$w); $bw.Write([int]($h * 2))
|
||||
$bw.Write([int16]1); $bw.Write([int16]32); $bw.Write([int]0)
|
||||
$bw.Write([int]0); $bw.Write([int]0); $bw.Write([int]0); $bw.Write([int]0); $bw.Write([int]0)
|
||||
for ($y = $h - 1; $y -ge 0; $y--) {
|
||||
for ($x = 0; $x -lt $w; $x++) {
|
||||
$px = $bmp.GetPixel($x, $y)
|
||||
$bw.Write([byte]$px.B); $bw.Write([byte]$px.G); $bw.Write([byte]$px.R); $bw.Write([byte]$px.A)
|
||||
}
|
||||
}
|
||||
$maskStride = [int]([Math]::Ceiling($w / 32.0) * 4)
|
||||
$bw.Write([byte[]]::new($maskStride * $h))
|
||||
$bw.Flush()
|
||||
return , $ms.ToArray()
|
||||
}
|
||||
|
||||
$sizes = 16, 20, 24, 32, 40, 48, 64, 256
|
||||
$images = @()
|
||||
foreach ($s in $sizes) {
|
||||
$bmp = New-IconBitmap $s
|
||||
if ($s -eq 256) {
|
||||
$ms = New-Object System.IO.MemoryStream
|
||||
$bmp.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
|
||||
[byte[]]$bytes = $ms.ToArray()
|
||||
} else {
|
||||
[byte[]]$bytes = Get-DibBytes $bmp
|
||||
}
|
||||
$images += , $bytes
|
||||
$bmp.Dispose()
|
||||
}
|
||||
|
||||
$out = New-Object System.IO.MemoryStream
|
||||
$w = New-Object System.IO.BinaryWriter($out)
|
||||
$w.Write([int16]0); $w.Write([int16]1); $w.Write([int16]$sizes.Count)
|
||||
$offset = 6 + 16 * $sizes.Count
|
||||
for ($i = 0; $i -lt $sizes.Count; $i++) {
|
||||
$s = $sizes[$i]
|
||||
$dim = if ($s -ge 256) { 0 } else { $s }
|
||||
$w.Write([byte]$dim); $w.Write([byte]$dim); $w.Write([byte]0); $w.Write([byte]0)
|
||||
$w.Write([int16]1); $w.Write([int16]32)
|
||||
$w.Write([int]$images[$i].Length); $w.Write([int]$offset)
|
||||
$offset += $images[$i].Length
|
||||
}
|
||||
foreach ($img in $images) { $w.Write([byte[]]$img) }
|
||||
$w.Flush()
|
||||
[System.IO.File]::WriteAllBytes([System.IO.Path]::GetFullPath($Output), $out.ToArray())
|
||||
Write-Host "Icoon geschreven naar $Output"
|
||||
Reference in new issue
Block a user