mirror of
https://github.com/tiennm99/miti99bot.git
synced 2026-08-07 00:24:06 +00:00
feat(misc): support vietnamese wheel beta text
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
DejaVu Sans font license
|
||||
|
||||
Source: https://dejavu-fonts.github.io/
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
|
||||
Bitstream Vera is a trademark of Bitstream, Inc.
|
||||
DejaVu changes are in public domain.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and distributed under the "Bitstream Vera"
|
||||
names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
|
||||
TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
|
||||
FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
|
||||
ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
|
||||
FONT SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively.
|
||||
Binary file not shown.
@@ -425,6 +425,32 @@ func TestWheelOfNamesBeta_RotatesOptionLabelsWithSlices(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWheelOfNamesBeta_DisplayTextPreservesVietnamese(t *testing.T) {
|
||||
input := "Tiếng Việt Đặng"
|
||||
got := wheelBetaDisplayText(input, 32)
|
||||
if got != input {
|
||||
t.Fatalf("wheelBetaDisplayText() = %q, want %q", got, input)
|
||||
}
|
||||
if strings.Contains(got, "?") {
|
||||
t.Fatalf("wheelBetaDisplayText() replaced Vietnamese with ?: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWheelOfNamesBeta_FontSupportsVietnameseGlyphs(t *testing.T) {
|
||||
for _, r := range "Tiếng Việt Đặng Ơ Ư ấ ệ" {
|
||||
if r == ' ' {
|
||||
continue
|
||||
}
|
||||
glyphIndex, err := wheelBetaTextFont.GlyphIndex(nil, r)
|
||||
if err != nil {
|
||||
t.Fatalf("GlyphIndex(%q): %v", r, err)
|
||||
}
|
||||
if glyphIndex == 0 {
|
||||
t.Fatalf("GlyphIndex(%q) = 0, want Vietnamese glyph support", r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func countColorIndex(img *image.Paletted, bounds image.Rectangle, colorIndex byte) int {
|
||||
bounds = bounds.Intersect(img.Bounds())
|
||||
count := 0
|
||||
|
||||
@@ -140,10 +140,10 @@ func renderWheelBetaFrameWithCelebration(options []string, winner int, rotation
|
||||
if label == "" {
|
||||
label = "CURRENT"
|
||||
}
|
||||
value := asciiWheelText(options[currentIndex], 28)
|
||||
value := wheelBetaDisplayText(options[currentIndex], 28)
|
||||
if reveal {
|
||||
label = "RESULT"
|
||||
value = asciiWheelText(options[winner], 28)
|
||||
value = wheelBetaDisplayText(options[winner], 28)
|
||||
}
|
||||
drawStatusBand(img, label, value)
|
||||
return img
|
||||
|
||||
@@ -1,20 +1,49 @@
|
||||
package misc
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"image"
|
||||
"image/color"
|
||||
"math"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/font/opentype"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
const (
|
||||
wheelBetaSliceLabelRadius = 64
|
||||
wheelBetaFontSize = 10
|
||||
wheelBetaFontDPI = 72
|
||||
)
|
||||
|
||||
//go:embed fonts/dejavu-sans.ttf
|
||||
var wheelBetaTextFontBytes []byte
|
||||
|
||||
var wheelBetaTextFont = mustWheelBetaTextFont()
|
||||
|
||||
func mustWheelBetaTextFont() *opentype.Font {
|
||||
parsed, err := opentype.Parse(wheelBetaTextFontBytes)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return parsed
|
||||
}
|
||||
|
||||
func newWheelBetaTextFace() font.Face {
|
||||
face, err := opentype.NewFace(wheelBetaTextFont, &opentype.FaceOptions{
|
||||
Size: wheelBetaFontSize,
|
||||
DPI: wheelBetaFontDPI,
|
||||
Hinting: font.HintingFull,
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return face
|
||||
}
|
||||
|
||||
func drawWheelSliceLabels(img *image.Paletted, options []string, rotation float64) {
|
||||
if len(options) == 0 {
|
||||
return
|
||||
@@ -26,7 +55,7 @@ func drawWheelSliceLabels(img *image.Paletted, options []string, rotation float6
|
||||
angle := rotation + (float64(idx)+0.5)*segment
|
||||
centerX := cx + int(math.Round(math.Cos(angle)*float64(wheelBetaSliceLabelRadius)))
|
||||
centerY := cy + int(math.Round(math.Sin(angle)*float64(wheelBetaSliceLabelRadius)))
|
||||
text := asciiWheelText(option, limit)
|
||||
text := wheelBetaDisplayText(option, limit)
|
||||
drawRotatedCenteredTextAt(img, text, centerX+1, centerY+1, angle, wheelBetaPaperColorIndex)
|
||||
drawRotatedCenteredTextAt(img, text, centerX, centerY, angle, wheelBetaInkColorIndex)
|
||||
}
|
||||
@@ -203,7 +232,10 @@ func drawCenteredText(img *image.Paletted, text string, baselineY int, colorInde
|
||||
}
|
||||
|
||||
func drawCenteredTextAt(img *image.Paletted, text string, centerX, baselineY int, colorIndex byte) {
|
||||
face := basicfont.Face7x13
|
||||
face := newWheelBetaTextFace()
|
||||
defer func() {
|
||||
_ = face.Close()
|
||||
}()
|
||||
width := font.MeasureString(face, text).Ceil()
|
||||
x := centerX - width/2
|
||||
drawer := font.Drawer{
|
||||
@@ -216,7 +248,10 @@ func drawCenteredTextAt(img *image.Paletted, text string, centerX, baselineY int
|
||||
}
|
||||
|
||||
func drawRotatedCenteredTextAt(img *image.Paletted, text string, centerX, centerY int, angle float64, colorIndex byte) {
|
||||
face := basicfont.Face7x13
|
||||
face := newWheelBetaTextFace()
|
||||
defer func() {
|
||||
_ = face.Close()
|
||||
}()
|
||||
padding := 2
|
||||
metrics := face.Metrics()
|
||||
textWidth := font.MeasureString(face, text).Ceil()
|
||||
@@ -247,17 +282,20 @@ func drawRotatedCenteredTextAt(img *image.Paletted, text string, centerX, center
|
||||
}
|
||||
}
|
||||
|
||||
func asciiWheelText(s string, limit int) string {
|
||||
func wheelBetaDisplayText(s string, limit int) string {
|
||||
var b strings.Builder
|
||||
count := 0
|
||||
for _, r := range s {
|
||||
if b.Len() >= limit {
|
||||
if count >= limit {
|
||||
break
|
||||
}
|
||||
if r < 32 || r > 126 {
|
||||
if unicode.IsControl(r) {
|
||||
b.WriteByte('?')
|
||||
count++
|
||||
continue
|
||||
}
|
||||
b.WriteRune(r)
|
||||
count++
|
||||
}
|
||||
out := strings.TrimSpace(b.String())
|
||||
if out == "" {
|
||||
|
||||
Reference in New Issue
Block a user