Joseph Davies
14 years ago
8 changed files with 3025 additions and 0 deletions
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 29 KiB |
@ -0,0 +1,13 @@
|
||||
SOURCE_DIR = .
|
||||
BINARY_DIR = .
|
||||
|
||||
.PHONY: all clean |
||||
|
||||
all: $(BINARY_DIR)/resource.dat |
||||
|
||||
$(BINARY_DIR)/resource.dat: $(SOURCE_DIR)/makeres.py $(SOURCE_DIR)/render_svg.py $(SOURCE_DIR)/create_resource_dat.py $(SOURCE_DIR)/Cursor_Base.svg $(SOURCE_DIR)/Linking_Book.svg $(SOURCE_DIR)/Loading_Text_rasterfont.svg $(SOURCE_DIR)/Voice_Chat.svg |
||||
python $(SOURCE_DIR)/makeres.py --optimize --render --package -i $(SOURCE_DIR) -o $(BINARY_DIR)
|
||||
|
||||
clean: |
||||
rm -rf $(BINARY_DIR)/render
|
||||
rm -fv $(BINARY_DIR)/resource.dat
|
After Width: | Height: | Size: 48 KiB |
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python |
||||
|
||||
from __future__ import print_function |
||||
from __future__ import with_statement |
||||
|
||||
import os |
||||
import sys |
||||
import glob |
||||
import struct |
||||
from optparse import OptionParser |
||||
|
||||
version = 1 |
||||
|
||||
def create_resource_dat(resfilepath, inrespath): |
||||
datHeader = 0xCBBCF00D |
||||
datVersion = 0x00000001 |
||||
|
||||
## Get list of files to archive |
||||
resourceList = glob.glob(os.path.join(inrespath, "*")) |
||||
resourceList.sort() |
||||
if len(resourceList) == 0: |
||||
print("No files found in '{0}'. Quitting.\n".format(inrespath)) |
||||
return False |
||||
print("{0} resources found in '{1}'.".format(len(resourceList), inrespath, )) |
||||
|
||||
## Write each resource into the output file |
||||
with open(resfilepath, "wb") as datFile: |
||||
datFile.write(struct.pack("<I",datHeader)) |
||||
datFile.write(struct.pack("<I",datVersion)) |
||||
datFile.write(struct.pack("<I",len(resourceList))) |
||||
for res in resourceList: |
||||
with open(res, "rb") as resFile: |
||||
name = os.path.basename(res) |
||||
datFile.write(struct.pack("<I", len(name))) |
||||
datFile.write(name) |
||||
datFile.write(struct.pack("<I", os.path.getsize(res))) |
||||
datFile.write(resFile.read()) |
||||
|
||||
print("{0} resources written to '{1}'.\n".format(len(resourceList), resfilepath)) |
||||
|
||||
return True |
||||
|
||||
if __name__ == '__main__': |
||||
parser = OptionParser(usage="usage: %prog [options]", version="%prog {0}".format(version)) |
||||
parser.add_option("-q", "--quiet", dest="verbose", default=True, action="store_false", help="Don't print status messages") |
||||
parser.add_option("-o", "--outfile", dest="outfile", default="resource.dat", help="Sets name for output file") |
||||
parser.add_option("-i", "--inpath", dest="inpath", default=".", help="Sets input path for files to add to resource file") |
||||
|
||||
(options, args) = parser.parse_args() |
||||
|
||||
## Send output to OS's null if unwanted |
||||
if not options.verbose: |
||||
sys.stdout = open(os.devnull,"w") |
||||
sys.stderr = open(os.devnull,"w") |
||||
|
||||
## Compute Paths |
||||
outfile = os.path.expanduser(options.outfile) |
||||
inpath = os.path.expanduser(options.inpath) |
||||
|
||||
## Do the work! |
||||
print("Creating {0}...".format(outfile)) |
||||
create_resource_dat(outfile, inpath) |
@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python |
||||
|
||||
import os |
||||
import sys |
||||
import glob |
||||
import subprocess |
||||
from optparse import OptionParser |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
parser = OptionParser(usage="usage: %prog [options]") |
||||
parser.add_option("-q", "--quiet", dest="verbose", default=True, action="store_false", help="Don't print status messages") |
||||
parser.add_option("-r", "--render", dest="render", default=False, action="store_true", help="Perform SVG Render to images") |
||||
parser.add_option("-p", "--package", dest="package", default=False, action="store_true", help="Perform packaging into resource container") |
||||
parser.add_option("-z", "--optimize", dest="optimize", default=False, action="store_true", help="Perform PNGCrush optimization on PNG resources") |
||||
parser.add_option("-o", "--outpath", dest="outpath", default=".", help="Sets output path for resource container") |
||||
parser.add_option("-i", "--inpath", dest="inpath", default=".", help="Sets input path for files to add to resource file") |
||||
|
||||
(options, args) = parser.parse_args() |
||||
|
||||
## Send output to OS's null if unwanted |
||||
if not options.verbose: |
||||
sys.stdout = open(os.devnull,"w") |
||||
sys.stderr = open(os.devnull,"w") |
||||
|
||||
## Compute Paths |
||||
outpath = os.path.expanduser(options.outpath) |
||||
inpath = os.path.expanduser(options.inpath) |
||||
|
||||
## Do the work! |
||||
if options.render: |
||||
ret = subprocess.call(["python", os.path.join(inpath, "render_svg.py"), "-i", inpath, "-o", os.path.join(outpath, "render")], stdout=sys.stdout, stderr=sys.stderr) |
||||
if ret != 0: |
||||
print("An error has occurred. Aborting.") |
||||
exit(1) |
||||
|
||||
if options.optimize: |
||||
print("Optimizing PNGs with pngcrush...") |
||||
for png in glob.glob(os.path.join("render", "*.png")): |
||||
#print("pngcrushing - {0}".format(png)) |
||||
ret = subprocess.call(["pngcrush", "-q", "-l 9", "-brute", png, "temp.png"], stdout=sys.stdout, stderr=sys.stderr) |
||||
if ret != 0: |
||||
print("An error has occurred. Aborting.") |
||||
exit(1) |
||||
os.remove(png) |
||||
os.rename("temp.png", png) |
||||
|
||||
if options.package: |
||||
ret = subprocess.call(["python", os.path.join(inpath, "create_resource_dat.py"), "-i", os.path.join(outpath, "render"), "-o", "resource.dat"], stdout=sys.stdout, stderr=sys.stderr) |
||||
if ret != 0: |
||||
print("An error has occurred. Aborting.") |
||||
exit(1) |
@ -0,0 +1,205 @@
|
||||
#!/usr/bin/env python |
||||
|
||||
from __future__ import print_function |
||||
from __future__ import with_statement |
||||
|
||||
|
||||
import os |
||||
import math |
||||
from xml.dom.minidom import parse |
||||
from optparse import OptionParser |
||||
|
||||
try: |
||||
import rsvg |
||||
import cairo |
||||
except ImportError as e: |
||||
print("Rendering SVG resources requires PyGTK. Exiting...") |
||||
exit(1) |
||||
|
||||
cursorList = { |
||||
"cursor_up": ["circleOuter"], |
||||
"cursor_poised": ["circleOuter", "circleInnerOpen"], |
||||
"cursor_clicked": ["circleOuter", "circleInnerClosed"], |
||||
"cursor_disabled": ["circleOuter", "cross"], |
||||
|
||||
"cursor_open": ["circleOuter", "arrowGreyUpper", "arrowGreyLower"], |
||||
"cursor_grab": ["circleOuter", "circleInnerClosed", "arrowGreyUpper", "arrowGreyLower"], |
||||
"cursor_updown_open": ["circleOuter", "circleInnerClosed", "arrowGreyUpper", "arrowGreyLower"], |
||||
"cursor_updown_closed": ["circleOuter", "circleInnerClosed", "arrowWhiteUpper", "arrowWhiteLower"], |
||||
|
||||
"cursor_leftright_open": ["circleOuter", "circleInnerClosed", "arrowGreyRight", "arrowGreyLeft"], |
||||
"cursor_leftright_closed": ["circleOuter", "circleInnerClosed", "arrowWhiteRight", "arrowWhiteLeft"], |
||||
|
||||
"cursor_4way_open": ["circleOuter", "circleInnerClosed", "arrowGreyUpper", "arrowGreyRight", "arrowGreyLower", "arrowGreyLeft"], |
||||
"cursor_4way_closed": ["circleOuter", "circleInnerClosed", "arrowWhiteUpper", "arrowWhiteRight", "arrowWhiteLower", "arrowWhiteLeft"], |
||||
|
||||
"cursor_upward": ["circleOuter", "arrowWhiteUpper"], |
||||
"cursor_right": ["circleOuter", "arrowWhiteRight"], |
||||
"cursor_down": ["circleOuter", "arrowWhiteLower"], |
||||
"cursor_left": ["circleOuter", "arrowWhiteLeft"], |
||||
|
||||
"cursor_book": ["circleOuter", "book"], |
||||
"cursor_book_poised": ["circleOuter", "circleInnerOpen", "book"], |
||||
"cursor_book_clicked": ["circleOuter", "circleInnerClosed", "book"], |
||||
} |
||||
cursorOffsetList = { |
||||
"book": [8, 8] |
||||
} |
||||
|
||||
textList = { |
||||
"xLoading_Linking_Text": ["background", "circles", "textLinking"], |
||||
"xLoading_Updating_Text": ["background", "circles", "textUpdating"] |
||||
} |
||||
|
||||
voiceList = { |
||||
"ui_speaker": ["speakerGrille", "speakerIndicator", "speakerOuterRing"], |
||||
"ui_microphone": ["microphoneGrille", "microphoneIndicator", "microphoneOuterRing"] |
||||
} |
||||
|
||||
def enable_only_layers(layerlist, layers): |
||||
for layer in layers: |
||||
if layer in layerlist: |
||||
layers[layer].setAttribute("style","") |
||||
else: |
||||
layers[layer].setAttribute("style","display:none") |
||||
|
||||
def get_layers_from_svg(svgData): |
||||
inkscapeNS = "http://www.inkscape.org/namespaces/inkscape" |
||||
layers = {} |
||||
|
||||
groups = svgData.getElementsByTagName("g") |
||||
for group in groups: |
||||
if group.getAttributeNS(inkscapeNS,"groupmode") == "layer": |
||||
layers[group.getAttribute("id")] = group |
||||
|
||||
return layers |
||||
|
||||
def render_cursors(inpath, outpath): |
||||
resSize = {"width":32, "height":32} |
||||
with open(os.path.join(inpath,"Cursor_Base.svg"), "r") as svgFile: |
||||
cursorSVG = parse(svgFile) |
||||
layers = get_layers_from_svg(cursorSVG) |
||||
ratioW = resSize["width"] / float(cursorSVG.documentElement.getAttribute("width")) |
||||
ratioH = resSize["height"] / float(cursorSVG.documentElement.getAttribute("height")) |
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"]) |
||||
|
||||
for cursor in cursorList: |
||||
ctx = cairo.Context(surface) |
||||
ctx.save() |
||||
ctx.set_operator(cairo.OPERATOR_CLEAR) |
||||
ctx.paint() |
||||
ctx.restore() |
||||
|
||||
enable_only_layers(cursorList[cursor], layers) |
||||
|
||||
for layerName in cursorOffsetList: |
||||
if layerName in cursorList[cursor]: |
||||
ctx.translate(*cursorOffsetList[layerName]) |
||||
svg = rsvg.Handle(data=cursorSVG.toxml()) |
||||
ctx.scale(ratioW, ratioH) |
||||
svg.render_cairo(ctx) |
||||
|
||||
surface.write_to_png(os.path.join(outpath, cursor + ".png")) |
||||
|
||||
def render_loading_books(inpath, outpath): |
||||
resSize = {"width":256, "height":256} |
||||
with open(os.path.join(inpath,"Linking_Book.svg"), "r") as svgFile: |
||||
bookSVG = parse(svgFile) |
||||
layers = get_layers_from_svg(bookSVG) |
||||
ratioW = resSize["width"] / float(bookSVG.documentElement.getAttribute("width")) |
||||
ratioH = resSize["height"] / float(bookSVG.documentElement.getAttribute("height")) |
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"]) |
||||
|
||||
for angle in range(0, 18): |
||||
ctx = cairo.Context(surface) |
||||
|
||||
# Draw Book and Black Background |
||||
enable_only_layers(["background", "book"],layers) |
||||
svg = rsvg.Handle(data=bookSVG.toxml()) |
||||
ctx.save() |
||||
ctx.scale(ratioW, ratioH) |
||||
svg.render_cairo(ctx) |
||||
ctx.restore() |
||||
|
||||
# Draw Circles at appropriate angle |
||||
enable_only_layers(["circles"],layers) |
||||
svg = rsvg.Handle(data=bookSVG.toxml()) |
||||
ctx.translate(resSize["height"] / 2, resSize["width"] / 2) |
||||
ctx.rotate(math.radians(angle*(-5))) |
||||
ctx.translate(-resSize["width"] / 2, -resSize["height"] / 2) |
||||
ctx.scale(ratioW, ratioH) |
||||
svg.render_cairo(ctx) |
||||
|
||||
surface.write_to_png(os.path.join(outpath, "xLoading_Linking.{0:02}.png".format(angle))) |
||||
|
||||
def render_loading_text(inpath, outpath): |
||||
resSize = {"width":192, "height":41} |
||||
with open(os.path.join(inpath,"Loading_Text_rasterfont.svg"), "r") as svgFile: |
||||
textSVG = parse(svgFile) |
||||
layers = get_layers_from_svg(textSVG) |
||||
ratioW = resSize["width"] / float(textSVG.documentElement.getAttribute("width")) |
||||
ratioH = resSize["height"] / float(textSVG.documentElement.getAttribute("height")) |
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"]) |
||||
|
||||
for textEntry in textList: |
||||
ctx = cairo.Context(surface) |
||||
ctx.save() |
||||
ctx.set_operator(cairo.OPERATOR_CLEAR) |
||||
ctx.paint() |
||||
ctx.restore() |
||||
enable_only_layers(textList[textEntry], layers) |
||||
svg = rsvg.Handle(data=textSVG.toxml()) |
||||
ctx.scale(ratioW, ratioH) |
||||
svg.render_cairo(ctx) |
||||
surface.write_to_png(os.path.join(outpath, textEntry + ".png")) |
||||
|
||||
def render_voice_icons(inpath, outpath): |
||||
resSize = {"width":32, "height":32} |
||||
with open(os.path.join(inpath,"Voice_Chat.svg"), "r") as svgFile: |
||||
uiSVG = parse(svgFile) |
||||
layers = get_layers_from_svg(uiSVG) |
||||
ratioW = resSize["width"] / float(uiSVG.documentElement.getAttribute("width")) |
||||
ratioH = resSize["height"] / float(uiSVG.documentElement.getAttribute("height")) |
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, resSize["width"], resSize["height"]) |
||||
|
||||
for voiceUI in voiceList: |
||||
ctx = cairo.Context(surface) |
||||
ctx.save() |
||||
ctx.set_operator(cairo.OPERATOR_CLEAR) |
||||
ctx.paint() |
||||
ctx.restore() |
||||
|
||||
enable_only_layers(voiceList[voiceUI], layers) |
||||
|
||||
svg = rsvg.Handle(data=uiSVG.toxml()) |
||||
ctx.scale(ratioW, ratioH) |
||||
svg.render_cairo(ctx) |
||||
|
||||
surface.write_to_png(os.path.join(outpath, voiceUI + ".png")) |
||||
|
||||
if __name__ == '__main__': |
||||
parser = OptionParser(usage="usage: %prog [options]") |
||||
parser.add_option("-q", "--quiet", dest="verbose", default=True, action="store_false", help="Don't print status messages") |
||||
parser.add_option("-o", "--outpath", dest="outpath", default="./out", help="Sets output path for rendered images") |
||||
parser.add_option("-i", "--inpath", dest="inpath", default=".", help="Sets input path for SVG files") |
||||
|
||||
(options, args) = parser.parse_args() |
||||
|
||||
## Send output to OS's null if unwanted |
||||
if not options.verbose: |
||||
sys.stdout = open(os.devnull,"w") |
||||
sys.stderr = open(os.devnull,"w") |
||||
|
||||
## Compute Paths |
||||
outpath = os.path.expanduser(options.outpath) |
||||
inpath = os.path.expanduser(options.inpath) |
||||
|
||||
if not os.path.exists(outpath): |
||||
os.mkdir(outpath) |
||||
|
||||
## Do the work! |
||||
print("Rendering SVGs...") |
||||
render_cursors(inpath, outpath) |
||||
render_loading_books(inpath, outpath) |
||||
render_loading_text(inpath, outpath) |
||||
render_voice_icons(inpath, outpath) |
Loading…
Reference in new issue