xml_processor.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals, print_function
  3. import os
  4. import shutil
  5. from xml.dom import minidom
  6. from . import (
  7. process_atlas, process_font, process_starling_atlas, oxygine_helper
  8. )
  9. def as_bool(attr):
  10. if not attr:
  11. return False
  12. lw = attr.lower()
  13. return lw == "true" or lw == "1"
  14. class XmlWalker:
  15. def __init__(self, src, xml_folder, path, scale_factor, node, meta_node, scale_quality, hit_test):
  16. self.xml_folder = xml_folder
  17. self.path = path
  18. self.scale_factor = scale_factor
  19. self.root = node
  20. self.last = None
  21. self.root_meta = meta_node
  22. self.last_meta = None
  23. self.src = src
  24. self.scale_quality = scale_quality
  25. self.hit_test = hit_test
  26. self.checkSetAttributes()
  27. def getType(self):
  28. return self.root
  29. def getXMLFolder(self):
  30. return self.xml_folder
  31. def getPath(self, attr):
  32. path = self.root.getAttribute(attr)
  33. if path.startswith("./") or path.startswith(".\\"):
  34. return self.xml_folder + path[2:len(path)]
  35. if path == ".":
  36. return self.xml_folder
  37. return self.path + path
  38. def setSrcFullPath(self, path):
  39. return self.src + path
  40. def checkSetAttributes(self):
  41. self._checkSetAttributes(self.root)
  42. def _checkSetAttributes(self, node):
  43. path = node.getAttribute("path")
  44. if path:
  45. if path.startswith("./") or path.startswith(".\\"):
  46. path = self.xml_folder + path[2:len(path)]
  47. elif path == ".":
  48. path = self.xml_folder
  49. self.path = path + "/"
  50. scale_factor = node.getAttribute("scale_factor")
  51. if scale_factor:
  52. self.scale_factor = float(scale_factor)
  53. scale_quality = node.getAttribute("scale_quality")
  54. if scale_quality:
  55. self.scale_quality = float(scale_quality)
  56. attr = node.getAttribute("hit_test")
  57. if attr:
  58. self.hit_test = as_bool(attr)
  59. def next(self):
  60. while True:
  61. if not self.last:
  62. if len(self.root.childNodes) == 0:
  63. return None
  64. self.last = self.root.childNodes[0]
  65. else:
  66. self.last = self.last.nextSibling
  67. if not self.last:
  68. return None
  69. if self.last.nodeType == self.last.TEXT_NODE:
  70. continue
  71. if self.last.nodeType == self.last.COMMENT_NODE:
  72. continue
  73. meta = self.root_meta.ownerDocument.createElement(
  74. self.last.nodeName)
  75. self.root_meta.appendChild(meta)
  76. self.last_meta = meta
  77. if self.last.nodeName == "set":
  78. self._checkSetAttributes(self.last)
  79. continue
  80. break
  81. return XmlWalker(self.src, self.xml_folder, self.path, self.scale_factor, self.last, self.last_meta, self.scale_quality, self.hit_test)
  82. class XmlProcessor(object):
  83. def __init__(self, args):
  84. self.src_data = args.src_data + "/"
  85. self.dest_data = args.dest_data + "/"
  86. self.compression = args.compression.lower()
  87. # self.etc1tool = args.android_sdk + "\\tools\\etc1tool.exe "
  88. # if self.compression == "etc1":
  89. # if not os.path.exists(self.etc1tool):
  90. # raise Exception("can't find etc1tool. please pass correct path to android_sdk")
  91. self.path_xml = args.xml
  92. self.xml_name = os.path.split(self.path_xml)[1]
  93. self.atlas_group_id = 0
  94. self.args = args
  95. self.verbosity = args.verbosity
  96. self.warnings = 0
  97. self.errors = 0
  98. #self.scale_factor = 1.0
  99. #self.scale_quality = 1.0
  100. self.scale = args.scale
  101. self.debug = args.debug
  102. self.processors = {}
  103. #self.path_current = ""
  104. self._meta_doc = None
  105. self._npot = args.npot
  106. #self._meta_element = None
  107. rp = os.path.abspath(__file__)
  108. rp = os.path.dirname(rp)
  109. rp = os.path.join(rp, "../../")
  110. rp = os.path.normpath(rp) + "/"
  111. self.helper = oxygine_helper.helper(rp)
  112. self.register_processor(process_font.bmfc_font_Processor())
  113. self.register_processor(process_font.font_Processor())
  114. self.register_processor(process_atlas.atlas_Processor())
  115. self.register_processor(
  116. process_starling_atlas.starling_atlas_Processor())
  117. self._current_processor = None
  118. def register_processor(self, processor):
  119. self.processors[processor.node_id] = processor
  120. def get_apply_scale(self, applyScaleFactor, walker):
  121. """
  122. returns scale should be applied to image
  123. """
  124. v = self.scale * walker.scale_quality
  125. if applyScaleFactor:
  126. v *= walker.scale_factor
  127. return v
  128. """
  129. def add_meta(self, node_id = ""):
  130. if not node_id:
  131. node_id = self._current_processor.node_id
  132. meta = self._meta_doc.createElement(node_id)
  133. self._meta_element.appendChild(meta)
  134. return meta
  135. def get_meta_doc(self):
  136. return self._meta_doc
  137. """
  138. """
  139. def _process_set(self, el):
  140. path = el.getAttribute("path")
  141. if path:
  142. if path.startswith(".\\") or path.startswith("./"):
  143. path = self.path_current + path
  144. path = os.path.normpath(path) + "/"
  145. self.path_current = path
  146. scale_factor = el.getAttribute("scale_factor")
  147. if scale_factor:
  148. self.scale_factor = float(scale_factor)
  149. scale_quality = el.getAttribute("scale_quality")
  150. if scale_quality:
  151. self.scale_quality = float(scale_quality)
  152. self.add_meta("set");
  153. """
  154. def _open_xml(self, path):
  155. with open(path, "r") as file:
  156. font_doc = minidom.parse(file)
  157. return font_doc.documentElement
  158. def _get_src_path(self, local_path):
  159. return self.src_data + local_path
  160. def _get_dest_path(self, local_path):
  161. return self.dest_data + local_path
  162. def _get_meta_xml_path(self, local_path):
  163. return self._get_dest_path(self.xml_name) + ".ox" + "/" + local_path
  164. """
  165. def get_current_src_path(self, local = ""):
  166. return self._get_src_path(self.path_current + local)
  167. """
  168. def get_inner_dest(self, inner_local_path=""):
  169. return self._get_meta_xml_path(self._current_processor.node_id + "/" + inner_local_path)
  170. def log(self, st):
  171. print(st)
  172. def warning(self, st):
  173. if self.args.warnings:
  174. print("warning: " + st)
  175. self.warnings += 1
  176. def error(self, st):
  177. print("error: " + st)
  178. self.errors += 1
  179. def process(self):
  180. # print self.path_data
  181. # print self.path_xml
  182. # print self.path_atlasses
  183. try:
  184. nm = self._get_src_path(self.path_xml)
  185. file = open(nm, "r")
  186. except IOError:
  187. print("can't open file: " + nm)
  188. return
  189. doc = minidom.parse(file)
  190. del file
  191. self._meta_doc = minidom.Document()
  192. meta_element = self._meta_doc.createElement("resources")
  193. meta_element.setAttribute("version", "2")
  194. self._meta_doc.appendChild(meta_element)
  195. # note: variable unused
  196. totalAtlasses = 0
  197. folder = self._get_meta_xml_path("")
  198. shutil.rmtree(folder, True)
  199. try:
  200. os.makedirs(folder)
  201. except OSError:
  202. pass
  203. xml_folder = os.path.split(self.path_xml)[0] + "/"
  204. hit_test = True
  205. if self.args.no_hit_test:
  206. hit_test = False
  207. walker = XmlWalker(self.src_data, xml_folder, "", 1.0,
  208. doc.documentElement, meta_element, 1.0, hit_test)
  209. while True:
  210. next = walker.next()
  211. if not next:
  212. break
  213. name = next.root.nodeName
  214. if name in self.processors:
  215. proc = self.processors[name]
  216. self._current_processor = proc
  217. try:
  218. if proc.create_folder:
  219. os.makedirs(self.get_inner_dest(""))
  220. except OSError:
  221. pass
  222. proc.process(self, next)
  223. """
  224. for el in doc.documentElement.childNodes:
  225. name = el.nodeName
  226. if name in self.processors:
  227. proc = self.processors[name]
  228. self._current_processor = proc
  229. try:
  230. if proc.create_folder:
  231. os.makedirs(self.get_inner_dest(""))
  232. except OSError:
  233. pass
  234. proc.process(self, el)
  235. if name == "set":
  236. self._process_set(el)
  237. if name == "sdfont":
  238. self._process_sdf_font(el)
  239. """
  240. path_ox_dest = self._get_meta_xml_path("meta.xml")
  241. file = open(path_ox_dest, "w")
  242. if self.verbosity > 1:
  243. print("saving ox file: \n" + os.path.normpath(path_ox_dest))
  244. if self.args.debug:
  245. meta_element.writexml(file, "\t", "\t", "\n")
  246. else:
  247. meta_element.writexml(file)
  248. # if self.verbosity > 1:
  249. # print "created %d atlasses" % (totalAtlasses, )
  250. if self.warnings or self.errors:
  251. print("warnings %d, errors %d" % (self.warnings, self.errors))