badgemaker.nim 5.0 KB

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