diff options
author | Yotam Barnoy | 2010-10-31 11:08:43 +0000 |
---|---|---|
committer | Yotam Barnoy | 2010-10-31 11:08:43 +0000 |
commit | 94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1 (patch) | |
tree | 3df2a4ae7967c56d464729669fc06ce4e93dff36 /tools/themeparser.py | |
parent | 8df4278ba8cfbf71228e1927f9db635a9a30a57f (diff) | |
parent | dca3c8d8bfc6c4db38cf8e8291818dd472041d4e (diff) | |
download | scummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.tar.gz scummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.tar.bz2 scummvm-rg350-94c8d0a14df429a1b25bd9f5c5d75497fd0ddbd1.zip |
Updated with latest from trunk
svn-id: r53976
Diffstat (limited to 'tools/themeparser.py')
-rw-r--r-- | tools/themeparser.py | 268 |
1 files changed, 134 insertions, 134 deletions
diff --git a/tools/themeparser.py b/tools/themeparser.py index 7150fa02ed..993f7c79bc 100644 --- a/tools/themeparser.py +++ b/tools/themeparser.py @@ -51,70 +51,70 @@ def pbin(data): class STXBinaryFile(object): class InvalidRGBColor(Exception): pass - + class InvalidResolution(Exception): pass - + class InvalidFontIdentifier(Exception): pass - + class InvalidBitmapName(Exception): pass - + class InvalidDialogOverlay(Exception): pass - + class DrawStepData(object): def __init__(self, isDefault, packFormat, function): self.isDefault = isDefault self.packFormat = packFormat self.parse = function - + BYTEORDER = '>' # big-endian format by default, platform independent - + TRUTH_VALUES = {"" : 0, "true" : 1, "false" : 0, "True" : 1, "False" : 0} - + BLOCK_HEADERS = { "bitmaps" : 0x0100000A, "fonts" : 0x0100000B, "cursor" : 0x0100000C, "drawdata" : 0x0100000D, - + "globals" : 0x0200000A, "dialog" : 0x0200000B, } - + DIALOG_shading = {"none" : 0x0, "dim" : 0x1, "luminance" : 0x2} - + DS_triangleOrientations = {"top" : 0x1, "bottom" : 0x2, "left" : 0x3, "right" : 0x4} DS_fillModes = {"none" : 0x0, "foreground" : 0x1, "background" : 0x2, "gradient" : 0x3} DS_vectorAlign = {"left" : 0x1, "right" : 0x2, "bottom" : 0x3, "top" : 0x4, "center" : 0x5} - + DS_functions = { - "void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4, + "void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4, "line" : 0x5, "triangle" : 0x6, "fill" : 0x7, "tab" : 0x8, "bitmap" : 0x9, "cross" : 0xA } - + DS_fonts = { - "text_default" : 0x0, "text_hover" : 0x1, "text_disabled" : 0x2, + "text_default" : 0x0, "text_hover" : 0x1, "text_disabled" : 0x2, "text_inverted" : 0x3, "text_button" : 0x4, "text_button_hover" : 0x5, "text_normal" : 0x6 } - + DS_text_alignV = {"bottom" : 0x0, "center" : 0x1, "top" : 0x2} DS_text_alignH = {"left" : 0x0, "center" : 0x1, "right" : 0x2} - + DS_list = [ "func", "fill", "stroke", "gradient_factor", "width", "height", "xpos", "ypos", "radius", "bevel", "shadow", "orientation", "file", "fg_color", "bg_color", "gradient_start", "gradient_end", "bevel_color" ] - + def __init__(self, themeName, autoLoad = True, verbose = False): self._themeName = themeName self._stxFiles = [] self._verbose = verbose - + self.DS_data = { # attribute name isDefault pack parse function "func" : self.DrawStepData(False, "B", lambda f: self.DS_functions[f]), @@ -136,74 +136,74 @@ class STXBinaryFile(object): "gradient_end" : self.DrawStepData(True, "4s", self.__parseColor), "bevel_color" : self.DrawStepData(True, "4s", self.__parseColor) } - + if autoLoad: if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")): raise IOError - + for filename in os.listdir(themeName): filename = os.path.join(themeName, filename) if os.path.isfile(filename) and filename.endswith('.stx'): self._stxFiles.append(filename) - + def debug(self, text): if self._verbose: print (text) - + def debugBinary(self, data): if self._verbose: print ("BINARY OUTPUT (%d bytes): %s" % (len(data), " ".join(["%0.2X" % ord(c) for c in data]))) - + def addSTXFile(self, filename): if not os.path.isfile(filename): raise IOError else: - self._stxFiles.append(filename) - + self._stxFiles.append(filename) + def parse(self): if not self._stxFiles: self.debug("No files have been loaded for parsing on the theme.") raise IOError - + for f in self._stxFiles: self.debug("Parsing %s." % f) with open(f) as stxFile: self.__parseFile(stxFile) - + def __parseFile(self, xmlFile): stxDom = DOM.parse(xmlFile) - + for layout in stxDom.getElementsByTagName("layout_info"): self.__parseLayout(layout) for render in stxDom.getElementsByTagName("render_info"): self.__parseRender(render) - + stxDom.unlink() - + def __getBitmap(self, bmp): bmp = str(bmp) - + if bmp == "": return 0x0 if bmp not in self._bitmaps: raise self.InvalidBitmapName - + return self._bitmaps[bmp] - + def __parseDrawStep(self, drawstepDom, localDefaults = {}): - + dstable = {} - + if drawstepDom.tagName == "defaults": isGlobal = drawstepDom.parentNode.tagName == "render_info" - + for ds in self.DS_list: if self.DS_data[ds].isDefault and drawstepDom.hasAttribute(ds): dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds)) - + elif isGlobal: dstable[ds] = None - + else: for ds in self.DS_data: if drawstepDom.hasAttribute(ds): @@ -212,13 +212,13 @@ class STXBinaryFile(object): dstable[ds] = localDefaults[ds] if ds in localDefaults else self._globalDefaults[ds] else: dstable[ds] = None - + return dstable - - + + def __parseDrawStepToBin(self, stepDict): """ - /BBBBiiiiiBBB4s4s4s4s4sB/ == + /BBBBiiiiiBBB4s4s4s4s4sB/ == function (byte) fill (byte) stroke (byte) @@ -238,10 +238,10 @@ class STXBinaryFile(object): gradient_end (4 byte) bevel_color (4 byte) """ - + packLayout = "" packData = [] - + for ds in self.DS_list: layout = self.DS_data[ds].packFormat data = stepDict[ds] @@ -249,18 +249,18 @@ class STXBinaryFile(object): if not data: size = struct.calcsize(layout) packLayout += "B" * size - + for d in range(size): packData.append(0) else: packLayout += layout packData.append(data) - - + + stepBin = struct.pack(self.BYTEORDER + packLayout, *tuple(packData)) return stepBin - - + + def __parseResolutionToBin(self, resString): """ /B bHH bHH bHH/ == 1 byte + x * 9 bytes @@ -269,34 +269,34 @@ class STXBinaryFile(object): resolution X (half) resolution Y (half) """ - + if resString == "": return struct.pack(self.BYTEORDER + "BbHH", 1, 0, 0, 0) - + resolutions = resString.split(", ") packFormat = "B" + "bHH" * len(resolutions) packData = [len(resolutions)] - + for res in resolutions: exclude = 0 if res[0] == '-': exclude = 1 res = res[1:] - + try: x, y = res.split('x') x = 0 if x == 'X' else int(x) y = 0 if y == 'Y' else int(y) except ValueError: raise InvalidResolution - + packData.append(exclude) packData.append(x) packData.append(y) - + buff = struct.pack(self.BYTEORDER + packFormat, *tuple(packData)) return buff - + def __parseRGBToBin(self, color): """ /xBBB/ == 32 bits @@ -305,24 +305,24 @@ class STXBinaryFile(object): green color (byte) blue color (byte) """ - + try: rgb = tuple(map(int, color.split(", "))) except ValueError: raise self.InvalidRGBColor - + if len(rgb) != 3: raise self.InvalidRGBColor - + for c in rgb: if c < 0 or c > 255: raise self.InvalidRGBColor - + rgb = struct.pack(self.BYTEORDER + "xBBB", *tuple(rgb)) - + # self.debugBinary(rgb) return rgb - + def __parseColor(self, color): try: color = self.__parseRGBToBin(color) @@ -330,93 +330,93 @@ class STXBinaryFile(object): if color not in self._colors: raise self.InvalidRGBColor color = self._colors[color] - + return color - - + + def __parsePalette(self, paletteDom): - self._colors = {} - + self._colors = {} + for color in paletteDom.getElementsByTagName("color"): color_name = color.getAttribute('name') color_rgb = self.__parseRGBToBin(color.getAttribute('rgb')) - + self._colors[color_name] = color_rgb # self.debug("COLOR: %s" % (color_name)) - - + + def __parseBitmaps(self, bitmapsDom): self._bitmaps = {} idCount = 0xA0 packLayout = "" packData = [] - + for bitmap in bitmapsDom.getElementsByTagName("bitmap"): bmpName = str(bitmap.getAttribute("filename")) self._bitmaps[bmpName] = idCount - + packLayout += "B%ds" % (len(bmpName) + 1) packData.append(idCount) packData.append(bmpName) idCount += 1 - - + + bitmapBinary = struct.pack( self.BYTEORDER + "IB" + packLayout, self.BLOCK_HEADERS['bitmaps'], len(bitmapsDom.getElementsByTagName("bitmap")), *tuple(packData) ) - + # self.debug("BITMAPS:\n%s\n\n" % pbin(bitmapBinary)) return bitmapBinary - + def __parseFonts(self, fontsDom): """ /IB Bs4ss .../ section header (uint32) number of font definitions (byte) - + id for font definition (byte) resolution for font (byte array) color for font (4 bytes) font filename (byte array, null terminated) """ - + packLayout = "" packData = [] for font in fontsDom.getElementsByTagName("font"): ident = font.getAttribute("id") - + if ident not in self.DS_fonts: raise self.InvalidFontIdentifier - + color = self.__parseColor(font.getAttribute("color")) filename = str(font.getAttribute("file")) - + if filename == 'default': filename = '' - + resolution = self.__parseResolutionToBin(font.getAttribute("resolution")) - + packLayout += "B%ds4s%ds" % (len(resolution), len(filename) + 1) packData.append(self.DS_fonts[ident]) packData.append(resolution) packData.append(color) - packData.append(filename) - + packData.append(filename) + fontsBinary = struct.pack(self.BYTEORDER + \ - "IB" + packLayout, - self.BLOCK_HEADERS['fonts'], + "IB" + packLayout, + self.BLOCK_HEADERS['fonts'], len(fontsDom.getElementsByTagName("font")), *tuple(packData) ) - - + + # self.debug("FONTS DATA:\n%s\n\n" % pbin(fontsBinary)) return fontsBinary - + def __parseTextToBin(self, textDom): """ /BBBx/ @@ -425,19 +425,19 @@ class STXBinaryFile(object): horizontal alignment (byte) padding until word (byte) """ - + font = textDom.getAttribute("font") if font not in self.DS_fonts: raise self.InvalidFontIdentifier - + textBin = struct.pack(self.BYTEORDER + "BBBx", self.DS_fonts[font], self.DS_text_alignV[textDom.getAttribute("vertical_align")], self.DS_text_alignH[textDom.getAttribute("horizontal_align")] ) - + return textBin - + def __parseDrawData(self, ddDom): """ /IsIBBHss/ @@ -450,32 +450,32 @@ class STXBinaryFile(object): ** text segment (4 bytes) drawstep segments (byte array) """ - - + + localDefaults = ddDom.getElementsByTagName("defaults") localDefaults = localDefaults[0] if localDefaults else {} - + stepList = [] - + for ds in ddDom.getElementsByTagName("drawstep"): dstable = self.__parseDrawStep(ds, localDefaults) dsbinary = self.__parseDrawStepToBin(dstable) - + stepList.append(dsbinary) stepByteArray = "".join(stepList) - + resolution = self.__parseResolutionToBin(ddDom.getAttribute("resolution")) - + text = ddDom.getElementsByTagName("text") text = self.__parseTextToBin(text[0]) if text else "" - + id_hash = str.__hash__(str(ddDom.getAttribute("id"))) & 0xFFFFFFFF cached = self.TRUTH_VALUES[ddDom.getAttribute("cached")] - + ddBinary = struct.pack(self.BYTEORDER + \ "I%dsIBBH4s%ds" % (len(resolution), len(stepByteArray)), - + self.BLOCK_HEADERS['drawdata'], # Section Header (uint32) resolution, # Resolution (byte array, word-aligned) id_hash, # DrawData id hash (uint32) @@ -485,10 +485,10 @@ class STXBinaryFile(object): text, # ** text segment (byte array) stepByteArray # drawstep segments (byte array) ) - + # self.debug("DRAW DATA %s (%X): \n" % (ddDom.getAttribute("id"), id_hash) + pbin(ddBinary) + "\n\n") return ddBinary - + def __parseCursor(self, cursorDom): """ /IsBBhh/ @@ -499,11 +499,11 @@ class STXBinaryFile(object): hotspot X (half) hotspot Y (half) """ - + resolution = self.__parseResolutionToBin(cursorDom.getAttribute("resolution")) scale = int(cursorDom.getAttribute("scale")) hsX, hsY = cursorDom.getAttribute("hotspot").split(", ") - + cursorBin = struct.pack(self.BYTEORDER + "I%dsBBhh" % len(resolution), self.BLOCK_HEADERS['cursor'], resolution, @@ -512,19 +512,19 @@ class STXBinaryFile(object): int(hsX), int(hsY) ) - + # self.debug("CURSOR:\n%s\n\n" % pbin(cursorBin)) return cursorBin - + def __parseDialog(self, dialogDom): - + dialog_id = str(dialogDom.getAttribute("name")) resolution = self.__parseResolutionToBin(dialogDom.getAttribute("resolution")) - + overlays = str(dialogDom.getAttribute("overlays")) overlay_type = 0x0 overlay_parent = "" - + if overlays == "screen": overlay_type = 0x1 elif overlays == "screen_center": @@ -532,19 +532,19 @@ class STXBinaryFile(object): else: overlay_type = 0x3 overlay_parent = str(overlays) - + dialog_enabled = 0x1 if dialogDom.hasAttribute("enabled"): dialog_enabled = self.TRUTH_VALUES[dialogDom.getAttribute("enabled")] - + dialog_shading = 0x0 if dialogDom.hasAttribute("shading"): dialog_shading = self.DIALOG_shading[dialogDom.getAttribute("shading")] - + dialog_inset = 0 if dialogDom.hasAttribute("inset"): dialog_inset = int(dialogDom.getAttribute("inset")) - + dialogBin = struct.pack(self.BYTEORDER + \ "I%ds%dsBBBB%ds" % (len(resolution), len(dialog_id) + 1, len(overlay_parent) + 1), self.BLOCK_HEADERS['dialog'], @@ -556,51 +556,51 @@ class STXBinaryFile(object): overlay_type, overlay_parent, ) - + return dialogBin - + def __parseLayout(self, layoutDom): self.debug("GLOBAL SECTION: LAYOUT INFO.") - + dialogBIN = "" - + for dialog in layoutDom.getElementsByTagName("dialog"): dialogBIN += self.__parseDialog(dialog) - - + + printBinaryDump(dialogBIN) - + return dialogBIN - + def __parseRender(self, renderDom): self.debug("GLOBAL SECTION: RENDER INFO.") - + bitmapBIN = "" fontsBIN = "" cursorBIN = "" drawdataBIN = "" - + # parse color palettes paletteDom = renderDom.getElementsByTagName("palette") if paletteDom: self.__parsePalette(paletteDom[0]) - + # parse bitmaps bitmapsDom = renderDom.getElementsByTagName("bitmaps") if bitmapsDom: bitmapBIN = self.__parseBitmaps(bitmapsDom[0]) - + # parse fonts fontsDom = renderDom.getElementsByTagName("fonts")[0] fontsBIN = self.__parseFonts(fontsDom) - + # parse defaults defaultsDom = renderDom.getElementsByTagName("defaults") if defaultsDom: self._globalDefaults = self.__parseDrawStep(defaultsDom[0]) else: self._globalDefaults = {} - + # parse cursors for cur in renderDom.getElementsByTagName("cursor"): cursorBIN += self.__parseCursor(cur) @@ -612,10 +612,10 @@ class STXBinaryFile(object): renderInfoBIN = bitmapBIN + fontsBIN + cursorBIN + drawdataBIN printBinaryDump(renderInfoBIN) - + return renderInfoBIN if __name__ == '__main__': bin = STXBinaryFile('../gui/themes/scummclassic', True, True) bin.parse() - + |