Finished binary parsing of DrawData/drawsteps.
svn-id: r35071
This commit is contained in:
parent
2babdcb41d
commit
486523af51
1 changed files with 66 additions and 76 deletions
|
@ -30,10 +30,11 @@ from __future__ import with_statement
|
||||||
import os
|
import os
|
||||||
import xml.dom.minidom as DOM
|
import xml.dom.minidom as DOM
|
||||||
import struct
|
import struct
|
||||||
|
from UserDict import UserDict
|
||||||
|
|
||||||
def pbin(data):
|
def pbin(data):
|
||||||
return " ".join(["%0.2X" % ord(c) for c in data])
|
return str(map(lambda c: hex(ord(c)), data))
|
||||||
|
# return " ".join(["%0.2X" % ord(c) for c in data])
|
||||||
|
|
||||||
class STXBinaryFile:
|
class STXBinaryFile:
|
||||||
class InvalidRGBColor(Exception):
|
class InvalidRGBColor(Exception):
|
||||||
|
@ -42,6 +43,14 @@ class STXBinaryFile:
|
||||||
class InvalidResolution(Exception):
|
class InvalidResolution(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class DrawStepData:
|
||||||
|
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}
|
TRUTH_VALUES = {"" : 0, "true" : 1, "false" : 0, "True" : 1, "False" : 0}
|
||||||
|
|
||||||
BLOCK_HEADERS = {
|
BLOCK_HEADERS = {
|
||||||
|
@ -53,24 +62,50 @@ class STXBinaryFile:
|
||||||
"drawdata" : 0x0100000F
|
"drawdata" : 0x0100000F
|
||||||
}
|
}
|
||||||
|
|
||||||
DRAWSTEP_FORMAT_DEF = [
|
DS_triangleOrientations = {"top" : 0x1, "bottom" : 0x2, "left" : 0x3, "right" : 0x4}
|
||||||
"stroke", "shadow",
|
DS_fillModes = {"none" : 0x0, "foreground" : 0x1, "background" : 0x2, "gradient" : 0x3}
|
||||||
"bevel", "gradient_factor",
|
DS_vectorAlign = {"left" : 0x1, "right" : 0x2, "bottom" : 0x3, "top" : 0x4, "center" : 0x5}
|
||||||
"fg_color", "bg_color",
|
|
||||||
"fill", "gradient_start",
|
|
||||||
"gradient_end", "bevel_color",
|
|
||||||
]
|
|
||||||
|
|
||||||
DRAWSTEP_FORMAT = [
|
DS_functions = {
|
||||||
"func", "radius", "width", "height",
|
"void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4,
|
||||||
"xpos", "ypos", "file", "orientation",
|
"line" : 0x5, "triangle" : 0x6, "fill" : 0x7, "tab" : 0x8, "bitmap" : 0x9, "cross" : 0xA
|
||||||
] + DRAWSTEP_FORMAT_DEF
|
}
|
||||||
|
|
||||||
|
DS_list = [
|
||||||
|
"func", "fill", "stroke", "gradient_factor",
|
||||||
|
"width", "height", "xpos", "ypos",
|
||||||
|
"radius", "bevel", "shadow", "orientation",
|
||||||
|
"fg_color", "bg_color", "gradient_start", "gradient_end", "bevel_color",
|
||||||
|
"file"
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, themeName, autoLoad = True, verbose = False):
|
def __init__(self, themeName, autoLoad = True, verbose = False):
|
||||||
self._themeName = themeName
|
self._themeName = themeName
|
||||||
self._stxFiles = []
|
self._stxFiles = []
|
||||||
self._verbose = verbose
|
self._verbose = verbose
|
||||||
|
|
||||||
|
self.DS_data = {
|
||||||
|
# attribute name isDefault pack parse function
|
||||||
|
"func" : self.DrawStepData(False, "B", lambda f: self.DS_functions[f]),
|
||||||
|
"fill" : self.DrawStepData(True, "B", lambda f: self.DS_fillModes[f]),
|
||||||
|
"stroke" : self.DrawStepData(True, "B", int),
|
||||||
|
"gradient_factor" : self.DrawStepData(True, "B", int),
|
||||||
|
"width" : self.DrawStepData(False, "i", lambda w: -1 if w == 'height' else 0 if w == 'auto' else int(w)),
|
||||||
|
"height" : self.DrawStepData(False, "i", lambda h: -1 if h == 'width' else 0 if h == 'auto' else int(h)),
|
||||||
|
"xpos" : self.DrawStepData(False, "i", lambda pos: self.DS_vectorAlign[pos] if pos in self.DS_vectorAlign else int(pos)),
|
||||||
|
"ypos" : self.DrawStepData(False, "i", lambda pos: self.DS_vectorAlign[pos] if pos in self.DS_vectorAlign else int(pos)),
|
||||||
|
"radius" : self.DrawStepData(False, "B", lambda r: 0xFF if r == 'auto' else int(r)),
|
||||||
|
"bevel" : self.DrawStepData(True, "B", int),
|
||||||
|
"shadow" : self.DrawStepData(True, "B", int),
|
||||||
|
"orientation" : self.DrawStepData(False, "B", lambda o: self.DS_triangleOrientations[o]),
|
||||||
|
"fg_color" : self.DrawStepData(True, "4s", self.__parseColor),
|
||||||
|
"bg_color" : self.DrawStepData(True, "4s", self.__parseColor),
|
||||||
|
"gradient_start" : self.DrawStepData(True, "4s", self.__parseColor),
|
||||||
|
"gradient_end" : self.DrawStepData(True, "4s", self.__parseColor),
|
||||||
|
"bevel_color" : self.DrawStepData(True, "4s", self.__parseColor),
|
||||||
|
"file" : self.DrawStepData(False, "%ds", str),
|
||||||
|
}
|
||||||
|
|
||||||
if autoLoad:
|
if autoLoad:
|
||||||
if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")):
|
if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")):
|
||||||
raise IOError
|
raise IOError
|
||||||
|
@ -116,60 +151,26 @@ class STXBinaryFile:
|
||||||
|
|
||||||
def __parseDrawStep(self, drawstepDom, localDefaults = {}):
|
def __parseDrawStep(self, drawstepDom, localDefaults = {}):
|
||||||
|
|
||||||
triangleOrientations = {"top" : 0x1, "bottom" : 0x2, "left" : 0x3, "right" : 0x4}
|
|
||||||
fillModes = {"none" : 0x0, "foreground" : 0x1, "background" : 0x2, "gradient" : 0x3}
|
|
||||||
vectorAlign = {"left" : 0x1, "right" : 0x2, "bottom" : 0x3, "top" : 0x4, "center" : 0x5}
|
|
||||||
|
|
||||||
functions = {
|
|
||||||
"void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4,
|
|
||||||
"line" : 0x5, "triangle" : 0x6, "fill" : 0x7, "tab" : 0x8, "bitmap" : 0x9, "cross" : 0xA
|
|
||||||
}
|
|
||||||
|
|
||||||
parseAttribute = {
|
|
||||||
"stroke" : int,
|
|
||||||
"bevel" : int,
|
|
||||||
"shadow" : int,
|
|
||||||
"gradient_factor" : int,
|
|
||||||
|
|
||||||
"fg_color" : self.__parseColor,
|
|
||||||
"bg_color" : self.__parseColor,
|
|
||||||
"gradient_start" : self.__parseColor,
|
|
||||||
"gradient_end" : self.__parseColor,
|
|
||||||
"bevel_color" : self.__parseColor,
|
|
||||||
|
|
||||||
"radius" : lambda r: 0xFF if r == 'auto' else int(r),
|
|
||||||
"file" : str,
|
|
||||||
"orientation" : lambda o: triangleOrientations[o],
|
|
||||||
"fill" : lambda f: fillModes[f],
|
|
||||||
"func" : lambda f: functions[f],
|
|
||||||
|
|
||||||
"width" : lambda w: -1 if w == 'height' else 0 if w == 'auto' else int(w),
|
|
||||||
"height" : lambda h: -1 if h == 'width' else 0 if h == 'auto' else int(h),
|
|
||||||
|
|
||||||
"xpos" : lambda pos: vectorAlign[pos] if pos in vectorAlign else int(pos),
|
|
||||||
"ypos" : lambda pos: vectorAlign[pos] if pos in vectorAlign else int(pos),
|
|
||||||
}
|
|
||||||
|
|
||||||
dstable = {}
|
dstable = {}
|
||||||
|
|
||||||
if drawstepDom.tagName == "defaults":
|
if drawstepDom.tagName == "defaults":
|
||||||
isGlobal = drawstepDom.parentNode.tagName == "render_info"
|
isGlobal = drawstepDom.parentNode.tagName == "render_info"
|
||||||
|
|
||||||
for attr in self.DRAWSTEP_FORMAT_DEF:
|
for ds in self.DS_list:
|
||||||
if drawstepDom.hasAttribute(attr):
|
if self.DS_data[ds].isDefault and drawstepDom.hasAttribute(ds):
|
||||||
dstable[attr] = parseAttribute[attr](drawstepDom.getAttribute(attr))
|
dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds))
|
||||||
|
|
||||||
elif isGlobal:
|
elif isGlobal:
|
||||||
dstable[attr] = None
|
dstable[ds] = None
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for attr in self.DRAWSTEP_FORMAT:
|
for ds in self.DS_data:
|
||||||
if drawstepDom.hasAttribute(attr):
|
if drawstepDom.hasAttribute(ds):
|
||||||
dstable[attr] = parseAttribute[attr](drawstepDom.getAttribute(attr))
|
dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds))
|
||||||
elif attr in self.DRAWSTEP_FORMAT_DEF:
|
elif self.DS_data[ds].isDefault:
|
||||||
dstable[attr] = localDefaults[attr] if attr in localDefaults else self._globalDefaults[attr]
|
dstable[ds] = localDefaults[ds] if ds in localDefaults else self._globalDefaults[ds]
|
||||||
else:
|
else:
|
||||||
dstable[attr] = None
|
dstable[ds] = None
|
||||||
|
|
||||||
return dstable
|
return dstable
|
||||||
|
|
||||||
|
@ -197,23 +198,12 @@ class STXBinaryFile:
|
||||||
file (byte string, null terminated)
|
file (byte string, null terminated)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DRAWSTEP_BININFO = {
|
|
||||||
"stroke" : "B", "shadow" : "B", "bevel" : "B",
|
|
||||||
"fill" : "B", "func" : "B", "radius" : "b",
|
|
||||||
"width" : "i", "height" : "i", "xpos" : "i",
|
|
||||||
"ypos" : "i", "orientation" : "B", "file" : "%ds",
|
|
||||||
|
|
||||||
"fg_color" : "4s", "bg_color" : "4s",
|
|
||||||
"gradient_start" : "4s", "gradient_end" : "4s",
|
|
||||||
"bevel_color" : "4s", "gradient_factor" : "B"
|
|
||||||
}
|
|
||||||
|
|
||||||
packLayout = ""
|
packLayout = ""
|
||||||
packData = []
|
packData = []
|
||||||
|
|
||||||
for attr in self.DRAWSTEP_FORMAT:
|
for ds in self.DS_list:
|
||||||
layout = DRAWSTEP_BININFO[attr]
|
layout = self.DS_data[ds].packFormat
|
||||||
data = stepDict[attr]
|
data = stepDict[ds]
|
||||||
|
|
||||||
if layout == "%ds":
|
if layout == "%ds":
|
||||||
if data:
|
if data:
|
||||||
|
@ -233,7 +223,7 @@ class STXBinaryFile:
|
||||||
packData.append(data)
|
packData.append(data)
|
||||||
|
|
||||||
|
|
||||||
stepBin = struct.pack(packLayout, *tuple(packData))
|
stepBin = struct.pack(self.BYTEORDER + packLayout, *tuple(packData))
|
||||||
# self.debugBinary(stepBin)
|
# self.debugBinary(stepBin)
|
||||||
return stepBin
|
return stepBin
|
||||||
|
|
||||||
|
@ -249,7 +239,7 @@ class STXBinaryFile:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if resString == "":
|
if resString == "":
|
||||||
return struct.pack("ixxxbII", 1, 0, 0, 0)
|
return struct.pack(self.BYTEORDER + "ixxxbII", 1, 0, 0, 0)
|
||||||
|
|
||||||
resolutions = resString.split(", ")
|
resolutions = resString.split(", ")
|
||||||
packFormat = "i" + "xxxbII" * len(resolutions)
|
packFormat = "i" + "xxxbII" * len(resolutions)
|
||||||
|
@ -272,7 +262,7 @@ class STXBinaryFile:
|
||||||
packData.append(x)
|
packData.append(x)
|
||||||
packData.append(y)
|
packData.append(y)
|
||||||
|
|
||||||
buff = struct.pack(packFormat, *tuple(packData))
|
buff = struct.pack(self.BYTEORDER + packFormat, *tuple(packData))
|
||||||
self.debug("Pack format: %s => %s" % (packFormat, str(packData)))
|
self.debug("Pack format: %s => %s" % (packFormat, str(packData)))
|
||||||
# self.debugBinary(buff)
|
# self.debugBinary(buff)
|
||||||
return buff
|
return buff
|
||||||
|
@ -298,7 +288,7 @@ class STXBinaryFile:
|
||||||
if c < 0 or c > 255:
|
if c < 0 or c > 255:
|
||||||
raise self.InvalidRGBColor
|
raise self.InvalidRGBColor
|
||||||
|
|
||||||
rgb = struct.pack("xBBB", *tuple(rgb))
|
rgb = struct.pack(self.BYTEORDER + "xBBB", *tuple(rgb))
|
||||||
|
|
||||||
# self.debugBinary(rgb)
|
# self.debugBinary(rgb)
|
||||||
return rgb
|
return rgb
|
||||||
|
@ -385,7 +375,7 @@ class STXBinaryFile:
|
||||||
id_hash = str.__hash__(str(ddDom.getAttribute("id")))
|
id_hash = str.__hash__(str(ddDom.getAttribute("id")))
|
||||||
cached = self.TRUTH_VALUES[ddDom.getAttribute("cached")]
|
cached = self.TRUTH_VALUES[ddDom.getAttribute("cached")]
|
||||||
|
|
||||||
ddBinary = struct.pack(
|
ddBinary = struct.pack(self.BYTEORDER + \
|
||||||
"I%dsiBBH%ds%ds" % (len(resolution), len(text), len(stepByteArray)),
|
"I%dsiBBH%ds%ds" % (len(resolution), len(text), len(stepByteArray)),
|
||||||
|
|
||||||
self.BLOCK_HEADERS['drawdata'], # Section Header (uint32)
|
self.BLOCK_HEADERS['drawdata'], # Section Header (uint32)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue