A rendering engine library for Go supporting both SDL2 and WebAssembly (HTML Canvas) targets.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.1 KiB

  1. package render
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strconv"
  6. )
  7. var regexpResolution = regexp.MustCompile(`^(\d+)x(\d+)$`)
  8. // ParseResolution turns a resolution string like "1024x768" and returns the
  9. // width and height values.
  10. func ParseResolution(resi string) (int, int, error) {
  11. m := regexpResolution.FindStringSubmatch(resi)
  12. if m == nil {
  13. return 0, 0, fmt.Errorf("invalid resolution format, should be %s",
  14. regexpResolution.String(),
  15. )
  16. }
  17. width, err := strconv.Atoi(m[1])
  18. if err != nil {
  19. return 0, 0, err
  20. }
  21. height, err := strconv.Atoi(m[2])
  22. if err != nil {
  23. return 0, 0, err
  24. }
  25. return width, height, nil
  26. }
  27. // TrimBox helps with Engine.Copy() to trim a destination box so that it
  28. // won't overflow with the parent container.
  29. func TrimBox(src, dst *Rect, p Point, S Rect, thickness int) {
  30. // Constrain source width to not bigger than Canvas width.
  31. if src.W > S.W {
  32. src.W = S.W
  33. }
  34. if src.H > S.H {
  35. src.H = S.H
  36. }
  37. // If the destination width will cause it to overflow the widget
  38. // box, trim off the right edge of the destination rect.
  39. //
  40. // Keep in mind we're dealing with chunks here, and a chunk is
  41. // a small part of the image. Example:
  42. // - Canvas is 800x600 (S.W=800 S.H=600)
  43. // - Chunk wants to render at 790,0 width 100,100 or whatever
  44. // dst={790, 0, 100, 100}
  45. // - Chunk box would exceed 800px width (X=790 + W=100 == 890)
  46. // - Find the delta how much it exceeds as negative (800 - 890 == -90)
  47. // - Lower the Source and Dest rects by that delta size so they
  48. // stay proportional and don't scale or anything dumb.
  49. if dst.X+src.W > p.X+S.W {
  50. // NOTE: delta is a negative number,
  51. // so it will subtract from the width.
  52. delta := (p.X + S.W - thickness) - (dst.W + dst.X)
  53. src.W += delta
  54. dst.W += delta
  55. }
  56. if dst.Y+src.H > p.Y+S.H {
  57. // NOTE: delta is a negative number
  58. delta := (p.Y + S.H - thickness) - (dst.H + dst.Y)
  59. src.H += delta
  60. dst.H += delta
  61. }
  62. // The same for the top left edge, so the drawings don't overlap
  63. // menu bars or left side toolbars.
  64. // - Canvas was placed 80px from the left of the screen.
  65. // Canvas.MoveTo(80, 0)
  66. // - A texture wants to draw at 60, 0 which would cause it to
  67. // overlap 20 pixels into the left toolbar. It needs to be cropped.
  68. // - The delta is: p.X=80 - dst.X=60 == 20
  69. // - Set destination X to p.X to constrain it there: 20
  70. // - Subtract the delta from destination W so we don't scale it.
  71. // - Add 20 to X of the source: the left edge of source is not visible
  72. if dst.X < p.X {
  73. // NOTE: delta is a positive number,
  74. // so it will add to the destination coordinates.
  75. delta := p.X - dst.X
  76. dst.X = p.X + thickness
  77. dst.W -= delta
  78. src.X += delta
  79. }
  80. if dst.Y < p.Y {
  81. delta := p.Y - dst.Y
  82. dst.Y = p.Y + thickness
  83. dst.H -= delta
  84. src.Y += delta
  85. }
  86. // Trim the destination width so it doesn't overlap the Canvas border.
  87. if dst.W >= S.W-thickness {
  88. dst.W = S.W - thickness
  89. }
  90. }
  91. // AbsInt returns the absolute value of an integer.
  92. func AbsInt(v int) int {
  93. if v < 0 {
  94. return -v
  95. }
  96. return v
  97. }
  98. // AbsInt32 returns the absolute value of an int32.
  99. func AbsInt32(v int32) int32 {
  100. if v < 0 {
  101. return -v
  102. }
  103. return v
  104. }