badgemaker.nim 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # author: Ethosa
  2. import streams
  3. import xmltree
  4. import strutils
  5. from base64 import encode
  6. type
  7. BadgeRef* = ref object
  8. style: string ## egg "flat", "square" or "plastic"
  9. label: string ## left text.
  10. value: string ## right text.
  11. label_text_color: string ## left text color
  12. value_text_color: string ## right text color
  13. label_color: string ## left color.
  14. value_color: string ## right color.
  15. font: string
  16. width, height: int
  17. image_path: string
  18. image_color: string
  19. proc newBadge*(label="", value="", style="flat", label_color="#212121",
  20. value_color="#e0e0e0", label_text_color="white",
  21. value_text_color="black", width=120, height=20): BadgeRef =
  22. BadgeRef(label: label, value: value, style: style,
  23. label_text_color: label_text_color, value_text_color: value_text_color,
  24. label_color: label_color, value_color: value_color,
  25. font: "DejaVu Sans,Verdana,Geneva,sans-serif",
  26. width: width, height: height, image_path: "", image_color: "")
  27. proc setFont*(badge: BadgeRef, font: string) =
  28. badge.font = font
  29. proc setIcon*(badge: BadgeRef, image_path: string) =
  30. badge.image_path = image_path
  31. proc setIcon*(badge: BadgeRef, image_path, color: string) =
  32. badge.image_path = image_path
  33. badge.image_color = color
  34. proc write*(badge: BadgeRef, filename: string) =
  35. var tree = newXMLTree(
  36. "svg", [], {
  37. "xmlns": "http://www.w3.org/2000/svg",
  38. "xmlns:xlink": "http://www.w3.org/1999/xlink",
  39. "width": $badge.width,
  40. "height": $badge.height
  41. }.toXMLAttributes)
  42. var gradient = newXMLTree(
  43. "linearGradient", [],
  44. {"id": "gradient",
  45. "x2": "0", "y2": "100%"
  46. }.toXMLAttributes)
  47. gradient.add newXMLTree("stop", [], {
  48. "offset": "0", "stop-color": "#bbb",
  49. "stop-opacity": if "plastic" notin badge.style:
  50. "0"
  51. else:
  52. ".1"
  53. }.toXMLAttributes)
  54. gradient.add newXMLTree("stop", [], {
  55. "offset": "1",
  56. "stop-opacity": if "plastic" notin badge.style:
  57. "0"
  58. else:
  59. ".1"
  60. }.toXMLAttributes)
  61. var
  62. main = newXMLTree("g", [], {"mask": "url(#gradient)"}.toXMLAttributes)
  63. image_width =
  64. if badge.image_path != "":
  65. badge.height
  66. else:
  67. 0
  68. labelw = len(badge.label)*9 + len(badge.label) + image_width
  69. valuew = len(badge.value)*9 + len(badge.value) + image_width
  70. dif =
  71. if labelw > valuew:
  72. labelw - valuew
  73. else:
  74. labelw - 12
  75. radius = if "square" in badge.style: "0" else: "4"
  76. main.add newXMLTree(
  77. "rect", [], {
  78. "x": "0", "y": "0", "width": $labelw, "height": $badge.height,
  79. "rx": radius,
  80. "ry": radius,
  81. "style": "fill:" & badge.label_color
  82. }.toXMLAttributes
  83. )
  84. main.add newXMLTree(
  85. "rect", [], {
  86. "x": $dif, "y": "0",
  87. "width": $((badge.width - 6) - (dif)),
  88. "height": $badge.height,
  89. "rx": "0", "ry": "0", "style": "fill:" & badge.value_color
  90. }.toXMLAttributes
  91. )
  92. main.add newXMLTree(
  93. "rect", [], {
  94. "x": $(badge.width - 12), "y": "0",
  95. "width": "12", "height": $badge.height,
  96. "rx": radius,
  97. "ry": radius,
  98. "style": "fill:" & badge.value_color
  99. }.toXMLAttributes
  100. )
  101. main.add newXMLTree(
  102. "path", [], {
  103. "fill": "url(#gradient)",
  104. "d": "M0 0h" & $badge.width & "v" & $badge.height & "H0z"
  105. }.toXMLAttributes
  106. )
  107. var text = newXMLTree("g", [], {
  108. "font-family": badge.font, "font-size": "12", "fill": badge.label_color
  109. }.toXMLAttributes)
  110. text.add newXMLTree(
  111. "text", [], {
  112. "x": $(image_width + 2 + parseInt(radius)),
  113. "y": $(badge.height/2 + 5), "fill": badge.label_text_color
  114. }.toXMLAttributes
  115. )
  116. text[0].add newText badge.label
  117. text.add newXMLTree(
  118. "text", [], {
  119. "x": $(dif + 2),
  120. "y": $(badge.height/2 + 5), "fill": badge.value_text_color
  121. }.toXMLAttributes
  122. )
  123. text[1].add newText badge.value
  124. tree.add gradient
  125. tree.add main
  126. tree.add text
  127. if badge.image_path != "":
  128. var img = newFileStream(badge.image_path, fmRead)
  129. var image = img.readAll
  130. img.close
  131. tree.add newXMLTree(
  132. "image", [], {
  133. "xlink:href": "data:image/png;base64," & encode image,
  134. "width": $badge.height, "height": $badge.height,
  135. "x": radius, "y": "0",
  136. "fill": badge.image_color
  137. }.toXMLAttributes
  138. )
  139. var strm = newFileStream(filename, fmWrite)
  140. strm.write $tree
  141. strm.close