-
Notifications
You must be signed in to change notification settings - Fork 275
/
driver_language.go
123 lines (103 loc) · 3.12 KB
/
driver_language.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package base64Captcha
import (
"image/color"
"log"
"math/rand"
"github.com/golang/freetype/truetype"
)
// https://en.wikipedia.org/wiki/Unicode_block
var langMap = map[string][]int{
//"zh-CN": []int{19968, 40869},
"latin": {0x0000, 0x007f},
"zh": {0x4e00, 0x9fa5},
"ko": {12593, 12686},
"jp": {12449, 12531}, //[]int{12353, 12435}
"ru": {1025, 1169},
"th": {0x0e00, 0x0e7f},
"greek": {0x0380, 0x03ff},
"arabic": {0x0600, 0x06ff},
"hebrew": {0x0590, 0x05ff},
//"emotion": []int{0x1f601, 0x1f64f},
}
func generateRandomRune(size int, code string) string {
lang, ok := langMap[code]
if !ok {
log.Printf("can not font language of %s \n", code)
lang = langMap["latin"]
}
start := lang[0]
end := lang[1]
randRune := make([]rune, size)
for i := range randRune {
idx := rand.Intn(end-start) + start
randRune[i] = rune(idx)
}
return string(randRune)
}
// DriverLanguage generates language unicode by lanuage
type DriverLanguage struct {
// Height png height in pixel.
Height int
// Width Captcha png width in pixel.
Width int
//NoiseCount text noise count.
NoiseCount int
//ShowLineOptions := OptionShowHollowLine | OptionShowSlimeLine | OptionShowSineLine .
ShowLineOptions int
//Length random string length.
Length int
//BgColor captcha image background color (optional)
BgColor *color.RGBA
//fontsStorage font storage (optional)
fontsStorage FontsStorage
//Fonts loads by name see fonts.go's comment
Fonts []*truetype.Font
LanguageCode string
}
// NewDriverLanguage creates a driver
func NewDriverLanguage(height int, width int, noiseCount int, showLineOptions int, length int, bgColor *color.RGBA, fontsStorage FontsStorage, fonts []*truetype.Font, languageCode string) *DriverLanguage {
return &DriverLanguage{Height: height, Width: width, NoiseCount: noiseCount, ShowLineOptions: showLineOptions, Length: length, BgColor: bgColor, fontsStorage: fontsStorage, Fonts: fonts, LanguageCode: languageCode}
}
// GenerateIdQuestionAnswer creates content and answer
func (d *DriverLanguage) GenerateIdQuestionAnswer() (id, content, answer string) {
id = RandomId()
content = generateRandomRune(d.Length, d.LanguageCode)
return id, content, content
}
// DrawCaptcha creates item
func (d *DriverLanguage) DrawCaptcha(content string) (item Item, err error) {
var bgc color.RGBA
if d.BgColor != nil {
bgc = *d.BgColor
} else {
bgc = RandLightColor()
}
itemChar := NewItemChar(d.Width, d.Height, bgc)
//draw hollow line
if d.ShowLineOptions&OptionShowHollowLine == OptionShowHollowLine {
itemChar.drawHollowLine()
}
//draw slime line
if d.ShowLineOptions&OptionShowSlimeLine == OptionShowSlimeLine {
itemChar.drawSlimLine(3)
}
//draw sine line
if d.ShowLineOptions&OptionShowSineLine == OptionShowSineLine {
itemChar.drawSineLine()
}
//draw noise
if d.NoiseCount > 0 {
noise := RandText(d.NoiseCount, TxtNumbers+TxtAlphabet+",.[]<>")
err = itemChar.drawNoise(noise, fontsAll)
if err != nil {
return
}
}
//draw content
//use font that match your language
err = itemChar.drawText(content, []*truetype.Font{fontChinese})
if err != nil {
return
}
return itemChar, nil
}