| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // Copyright 2024 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package badge
-
- import (
- "strings"
- "sync"
- "unicode"
-
- actions_model "code.gitea.io/gitea/models/actions"
- )
-
- // The Badge layout: |offset|label|message|
- // We use 10x scale to calculate more precisely
- // Then scale down to normal size in tmpl file
-
- type Text struct {
- text string
- width int
- x int
- }
-
- func (t Text) Text() string {
- return t.text
- }
-
- func (t Text) Width() int {
- return t.width
- }
-
- func (t Text) X() int {
- return t.x
- }
-
- func (t Text) TextLength() int {
- return int(float64(t.width-defaultOffset) * 10)
- }
-
- type Badge struct {
- 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 (
- StyleFlat = "flat"
- StyleFlatSquare = "flat-square"
- )
-
- 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 := calculateTextWidth(label) + defaultOffset
- mw := calculateTextWidth(message) + defaultOffset
-
- lx := lw * 5
- mx := lw*10 + mw*5 - 10
- return Badge{
- FontFamily: DefaultFontFamily,
- Label: Text{
- text: label,
- width: lw,
- x: lx,
- },
- Message: Text{
- text: message,
- width: mw,
- 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
- }
|