draw.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package dao
  2. import (
  3. "image"
  4. "image/draw"
  5. "io/ioutil"
  6. "math"
  7. "unicode/utf8"
  8. "go-common/library/log"
  9. "github.com/golang/freetype"
  10. "golang.org/x/image/font"
  11. "golang.org/x/image/math/fixed"
  12. )
  13. // QueConf question img conf.
  14. func (d *Dao) QueConf(mobile bool) (c *TextImgConf) {
  15. if mobile {
  16. // Mobile
  17. c = &TextImgConf{
  18. Fontsize: 16, // mobile font size in points
  19. Length: 11, // mobile question length
  20. Ansfontsize: 12, // mobile ans font size in points
  21. }
  22. } else {
  23. // PC
  24. c = &TextImgConf{
  25. Fontsize: 12, //font size in points
  26. Length: 36, //question length
  27. Ansfontsize: 10, //ans font size in points
  28. }
  29. }
  30. c.Spacing = 2 // line spacing (e.g. 2 means double spaced)
  31. c.Ansspacing = 2 // line ansspacing (e.g. 2 means double spaced)
  32. return
  33. }
  34. // DrawQue draw question title.
  35. func (d *Dao) DrawQue(c *freetype.Context, s string, conf *TextImgConf, pt *fixed.Point26_6) {
  36. c.SetFontSize(float64(conf.Fontsize))
  37. srune := []rune(s)
  38. var end = conf.Length
  39. for len(srune) > 0 {
  40. if conf.Length > len(srune) {
  41. end = len(srune)
  42. }
  43. d.text(c, string(srune[:end]), pt, conf.Fontsize, conf.Spacing)
  44. srune = srune[end:]
  45. }
  46. }
  47. // DrawAns draw ans
  48. func (d *Dao) DrawAns(c *freetype.Context, conf *TextImgConf, anss [4]string, pt *fixed.Point26_6) {
  49. c.SetFontSize(float64(conf.Ansfontsize))
  50. arr := [4]string{"A.", "B.", "C.", "D."}
  51. for i, a := range anss {
  52. d.text(c, arr[i]+a, pt, conf.Ansfontsize, conf.Ansspacing)
  53. }
  54. }
  55. //Height get img height
  56. func (d *Dao) Height(c *TextImgConf, que string, anslen int) (h int) {
  57. len := utf8.RuneCountInString(que)
  58. line := math.Ceil(float64(len) / float64(c.Length))
  59. h = int(math.Ceil(c.Spacing*line*float64(c.Fontsize))) + int(math.Ceil(c.Ansspacing*float64(anslen)*float64(c.Ansfontsize)))
  60. return
  61. }
  62. // text Draw text.
  63. func (d *Dao) text(c *freetype.Context, s string, pt *fixed.Point26_6, size int, spacing float64) (err error) {
  64. _, err = c.DrawString(s, *pt)
  65. if err != nil {
  66. return
  67. }
  68. pt.Y += fixed.Int26_6(int(float64(size)*spacing) << 6)
  69. return
  70. }
  71. var (
  72. dpi = float64(72) // screen resolution in Dots Per Inch
  73. hinting = "none" // none | full
  74. )
  75. // Board init draw board.
  76. func (d *Dao) Board(h int) (r *image.Gray) {
  77. bg := image.White
  78. r = image.NewGray(image.Rect(0, 0, 600, h))
  79. draw.Draw(r, r.Bounds(), bg, image.ZP, draw.Src)
  80. return
  81. }
  82. // Context freetype init context.
  83. func (d *Dao) Context(r *image.Gray, fileStr string) (c *freetype.Context) {
  84. fg := image.Black
  85. // Read the font data.
  86. fontBytes, err := ioutil.ReadFile(fileStr)
  87. if err != nil {
  88. log.Error("ioutil.ReadFile(),err:%+v", err)
  89. return
  90. }
  91. f, err := freetype.ParseFont(fontBytes)
  92. if err != nil {
  93. log.Error("freetype.ParseFont(),err:%+v", err)
  94. return
  95. }
  96. c = freetype.NewContext()
  97. c.SetDPI(dpi)
  98. c.SetFont(f)
  99. c.SetClip(r.Bounds())
  100. c.SetDst(r)
  101. c.SetSrc(fg)
  102. switch hinting {
  103. default:
  104. c.SetHinting(font.HintingNone)
  105. case "full":
  106. c.SetHinting(font.HintingFull)
  107. }
  108. return
  109. }