aboutsummaryrefslogtreecommitdiffstats
path: root/modules/badge/badge.go
diff options
context:
space:
mode:
Diffstat (limited to 'modules/badge/badge.go')
-rw-r--r--modules/badge/badge.go133
1 files changed, 79 insertions, 54 deletions
diff --git a/modules/badge/badge.go b/modules/badge/badge.go
index b30d0b4729..d2e9bd9d1b 100644
--- a/modules/badge/badge.go
+++ b/modules/badge/badge.go
@@ -4,6 +4,10 @@
package badge
import (
+ "strings"
+ "sync"
+ "unicode"
+
actions_model "code.gitea.io/gitea/models/actions"
)
@@ -11,94 +15,115 @@ import (
// We use 10x scale to calculate more precisely
// Then scale down to normal size in tmpl file
-type Label struct {
- text string
- width int
-}
-
-func (l Label) Text() string {
- return l.text
-}
-
-func (l Label) Width() int {
- return l.width
-}
-
-func (l Label) TextLength() int {
- return int(float64(l.width-defaultOffset) * 9.5)
-}
-
-func (l Label) X() int {
- return l.width*5 + 10
-}
-
-type Message struct {
+type Text struct {
text string
width int
x int
}
-func (m Message) Text() string {
- return m.text
+func (t Text) Text() string {
+ return t.text
}
-func (m Message) Width() int {
- return m.width
+func (t Text) Width() int {
+ return t.width
}
-func (m Message) X() int {
- return m.x
+func (t Text) X() int {
+ return t.x
}
-func (m Message) TextLength() int {
- return int(float64(m.width-defaultOffset) * 9.5)
+func (t Text) TextLength() int {
+ return int(float64(t.width-defaultOffset) * 10)
}
type Badge struct {
- Color string
- FontSize int
- Label Label
- Message Message
+ IDPrefix string
+ FontFamily string
+ Color string
+ FontSize int
+ Label Text
+ Message Text
}
func (b Badge) Width() int {
return b.Label.width + b.Message.width
}
+// Style follows https://shields.io/badges
const (
- defaultOffset = 9
- defaultFontSize = 11
- DefaultColor = "#9f9f9f" // Grey
- defaultFontWidth = 7 // approximate speculation
+ StyleFlat = "flat"
+ StyleFlatSquare = "flat-square"
)
-var StatusColorMap = map[actions_model.Status]string{
- actions_model.StatusSuccess: "#4c1", // Green
- actions_model.StatusSkipped: "#dfb317", // Yellow
- actions_model.StatusUnknown: "#97ca00", // Light Green
- actions_model.StatusFailure: "#e05d44", // Red
- actions_model.StatusCancelled: "#fe7d37", // Orange
- actions_model.StatusWaiting: "#dfb317", // Yellow
- actions_model.StatusRunning: "#dfb317", // Yellow
- actions_model.StatusBlocked: "#dfb317", // Yellow
-}
+const (
+ defaultOffset = 10
+ defaultFontSize = 11
+ DefaultColor = "#9f9f9f" // Grey
+ DefaultFontFamily = "DejaVu Sans,Verdana,Geneva,sans-serif"
+ DefaultStyle = StyleFlat
+)
+
+var GlobalVars = sync.OnceValue(func() (ret struct {
+ StatusColorMap map[actions_model.Status]string
+ DejaVuGlyphWidthData map[rune]uint8
+ AllStyles []string
+},
+) {
+ ret.StatusColorMap = map[actions_model.Status]string{
+ actions_model.StatusSuccess: "#4c1", // Green
+ actions_model.StatusSkipped: "#dfb317", // Yellow
+ actions_model.StatusUnknown: "#97ca00", // Light Green
+ actions_model.StatusFailure: "#e05d44", // Red
+ actions_model.StatusCancelled: "#fe7d37", // Orange
+ actions_model.StatusWaiting: "#dfb317", // Yellow
+ actions_model.StatusRunning: "#dfb317", // Yellow
+ actions_model.StatusBlocked: "#dfb317", // Yellow
+ }
+ ret.DejaVuGlyphWidthData = dejaVuGlyphWidthDataFunc()
+ ret.AllStyles = []string{StyleFlat, StyleFlatSquare}
+ return ret
+})
// GenerateBadge generates badge with given template
func GenerateBadge(label, message, color string) Badge {
- lw := defaultFontWidth*len(label) + defaultOffset
- mw := defaultFontWidth*len(message) + defaultOffset
- x := lw*10 + mw*5 - 10
+ lw := calculateTextWidth(label) + defaultOffset
+ mw := calculateTextWidth(message) + defaultOffset
+
+ lx := lw * 5
+ mx := lw*10 + mw*5 - 10
return Badge{
- Label: Label{
+ FontFamily: DefaultFontFamily,
+ Label: Text{
text: label,
width: lw,
+ x: lx,
},
- Message: Message{
+ Message: Text{
text: message,
width: mw,
- x: x,
+ x: mx,
},
FontSize: defaultFontSize * 10,
Color: color,
}
}
+
+func calculateTextWidth(text string) int {
+ width := 0
+ widthData := GlobalVars().DejaVuGlyphWidthData
+ for _, char := range strings.TrimSpace(text) {
+ charWidth, ok := widthData[char]
+ if !ok {
+ // use the width of 'm' in case of missing glyph width data for a printable character
+ if unicode.IsPrint(char) {
+ charWidth = widthData['m']
+ } else {
+ charWidth = 0
+ }
+ }
+ width += int(charWidth)
+ }
+
+ return width
+}