integrated SVG Icon rendering into the SCons build

This commit is contained in:
Fischlurch 2008-08-19 05:03:29 +02:00
parent 19156f3a34
commit 878ce2319b
8 changed files with 113 additions and 14 deletions

2
.gitignore vendored
View file

@ -5,7 +5,7 @@
*.os
*.gch
,valgrind.log*
admin/scons/*.pyc
*.pyc
optcache
Makefile.in
build/*

View file

@ -37,6 +37,7 @@ BINDIR = 'bin'
TESTDIR = 'tests'
ICONDIR = 'icons'
VERSION = '0.1+pre.01'
SVGRENDERER = 'admin/render-icon'
#-----------------------------------Configuration
# NOTE: scons -h for help.
@ -68,6 +69,7 @@ def setupBasicEnvironment():
, CCFLAGS='-Wall ' # -fdiagnostics-show-option
)
RegisterIcon_Builder(env,SVGRENDERER)
RegisterPrecompiledHeader_Builder(env)
handleNoBugSwitches(env)
@ -225,6 +227,10 @@ def configurePlatform(env):
if not conf.CheckPkgConfig('gtkmm-2.4', 2.8):
print 'Unable to configure GTK--, exiting.'
Exit(1)
if not conf.CheckPkgConfig('glibmm-2.4', '2.16'):
print 'Unable to configure Lib glib--, exiting.'
Exit(1)
if not conf.CheckPkgConfig('cairomm-1.0', 0.6):
print 'Unable to configure Cairo--, exiting.'
@ -234,6 +240,10 @@ def configurePlatform(env):
print 'Unable to configure the GNOME DevTool Library, exiting.'
Exit(1)
if not conf.CheckPkgConfig('librsvg-2.0', '2.18.1'):
print 'Need rsvg Library for rendering icons.'
Exit(1)
if not conf.CheckPkgConfig('xv'): Exit(1)
# if not conf.CheckPkgConfig('xext'): Exit(1)
# if not conf.CheckPkgConfig('sm'): Exit(1)
@ -292,16 +302,24 @@ def defineBuildTargets(env, artifacts):
artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug)
# the Lumiera GTK GUI
envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','xv','xext','sm'])
envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm'])
objgui = srcSubtree(envgtk,'$SRCDIR/gui')
# render and install Icons
vector_icon_dir = env.subst('$ICONDIR/svg')
prerendered_icon_dir = env.subst('$ICONDIR/prerendered')
artifacts['icons'] = ( [env.IconRender(f) for f in scanSubtree(vector_icon_dir, ['*.svg'])]
+ [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])]
)
artifacts['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core)
+ env.Install('$BINDIR', env.Glob('$ICONDIR/*.png'))
+ env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc'))
+ artifacts['icons']
)
# call subdir SConscript(s) for independent components
SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core')
SConscript(dirs=['admin'], exports='env envgtk artifacts core')
SConscript(dirs=[TESTDIR], exports='env artifacts core')

17
admin/SConscript Normal file
View file

@ -0,0 +1,17 @@
# -*- python -*-
##
## SConscript - SCons buildscript for helper tools (called by SConstruct)
##
Import('env','envgtk','artifacts','core')
vgsuppr = env.Program('#$BINDIR/vgsuppression',['vgsuppression.c']+core)
rsvg = envgtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c')
artifacts['tools'] += [ vgsuppr ## for supressing false valgrind alarms
+ rsvg ## for rendering SVG icons (uses librsvg)
]
# Rendering the SVG Icons depends on rsvg-convert
env.Depends(artifacts['icons'], rsvg)

View file

@ -68,7 +68,7 @@ def parsePlateLayer( layer ):
return rectangles
def parseSVG( file_path ):
print "Rendering " + file_path
print "Parsing " + file_path
svgdoc = minidom.parse(file_path)
for root_node in svgdoc.childNodes:
if root_node.nodeType == minidom.Node.ELEMENT_NODE:
@ -104,6 +104,9 @@ def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size):
# Prepare a Cairo context
width = int(rectangle[2])
height = int(rectangle[3])
if not os.path.exists(rsvgPath):
print "Error: executable %s not found." % rsvgPath
os.spawnlp(os.P_WAIT, rsvgPath, rsvgPath,
"--source-rect=%g:%g:%g:%g" % (rectangle[0], rectangle[1], rectangle[2], rectangle[3]),
@ -115,6 +118,13 @@ def renderSvgIcon(file_path, out_dir):
for rectangle in rectangles:
renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size)
def getTargetNames(file_path):
"""get a list of target names to be rendered from the given source SVG
usable to setup the build targets for SCons
"""
artwork_name, _ , rectangles = parseSVG(file_path)
return ["%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name) for rectangle in rectangles ]
#def renderSvgIcons():
# listing = os.listdir(svgDir)
# for file_path in listing:
@ -129,7 +139,8 @@ def renderSvgIcon(file_path, out_dir):
# copyMergeDirectory(src_dir, list_item)
def printHelp():
print "render-icon.py - An icon rendering utility script for lumiera"
print "render-icon.py SRCFILE.svg TARGETDIR"
print "An icon rendering utility script for lumiera"
def parseArguments(argv):
optlist, args = getopt.getopt(argv, "")

View file

@ -28,6 +28,8 @@ import fnmatch
import re
import tarfile
from SCons.Action import Action
#
@ -58,13 +60,13 @@ def srcSubtree(env,tree,isShared=False,builder=None, **args):
else:
builder = lambda f: env.Object(f, **args)
return [builder(f) for f in scanSrcSubtree(root)]
return [builder(f) for f in scanSubtree(root)]
SRCPATTERNS = ['*.c','*.cpp','*.cc']
def scanSrcSubtree(roots):
def scanSubtree(roots, patterns=SRCPATTERNS):
""" first expand (possible) wildcards and filter out non-dirs.
Then scan the given subtree for source filesnames
(python generator function)
@ -73,7 +75,7 @@ def scanSrcSubtree(roots):
for (dir,_,files) in os.walk(root):
if dir.startswith('./'):
dir = dir[2:]
for p in SRCPATTERNS:
for p in patterns:
for f in fnmatch.filter(files, p):
yield os.path.join(dir,f)
@ -102,6 +104,53 @@ def filterNodes(nlist, removeName=None):
return filter(predicate, nlist)
def getDirname(dir):
""" extract directory name without leading path """
dir = os.path.realpath(dir)
if not os.path.isdir(dir):
dir,_ = os.path.split(dir)
_, name = os.path.split(dir)
return name
def RegisterIcon_Builder(env, renderer):
""" Registeres Custom Builders for generating and installing Icons.
Additionally you need to build the tool (rsvg-convert.c)
used to generate png from the svg source using librsvg.
"""
renderer = __import__(renderer) # load python script for invoking the render
renderer.rsvgPath = env.subst("$BINDIR/rsvg-convert")
def invokeRenderer(target, source, env):
source = str(source[0])
targetdir = env.subst("$BINDIR")
renderer.main([source,targetdir])
return 0
def createIconTargets(target,source,env):
""" parse the SVG to get the target file names """
source = str(source[0])
targetdir = os.path.basename(str(target[0]))
targetfiles = renderer.getTargetNames(source) # parse SVG
return (["$BINDIR/%s" % name for name in targetfiles], source)
def IconCopy(env, source):
"""Copy icon to corresponding icon dir. """
subdir = getDirname(source)
return env.Install("$BINDIR/%s" % subdir, source)
buildIcon = env.Builder( action = Action(invokeRenderer, "rendering Icon: $SOURCE --> $TARGETS")
, single_source = True
, emitter = createIconTargets
)
env.Append(BUILDERS = {'IconRender' : buildIcon})
env.AddMethod(IconCopy)
def RegisterPrecompiledHeader_Builder(env):
""" Registeres an Custom Builder for generating a precompiled Header.
Note you should define a dependency to the PCH file

View file

@ -77,10 +77,14 @@ class LumieraEnvironment(Environment):
return libInfo
def Glob (self, pattern):
""" temporary workaround; newer versions of SCons provide this as a global function
"""
""" temporary workaround; newer versions of SCons provide this as a global function """
pattern = self.subst(pattern)
return glob.glob(pattern)
def AddMethod (self, function):
""" temporary workaround; newer versions of SCons provide this as a global function """
self.__dict__[function.__name__] = function.__get__(self)
class LumieraConfigContext(SConf):

View file

@ -747,7 +747,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BuildDependencies" modifier="Ichthyostega" modified="200808180346" created="200803261326" changecount="14">
<div title="BuildDependencies" modifier="Ichthyostega" modified="200808190851" created="200803261326" changecount="15">
<pre>! Programming Languages
* C
** a C99 compatible compiler, some GCC extensions are used, most are optional.
@ -787,7 +787,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
** libcairomm-1.0-dev (&gt;=0.6.0)
** libgdl-1-dev (&gt;=0.6.1)
*** libbonoboui2-dev (&gt;=2.14.0)
** libgtkmm-2.4-dev (&gt;=2.16), requiring glib2.0 (&gt;=2.16)
** libglibmm-2.4-dev (&gt;=2.16), requiring glib2.0 (&gt;=2.16)
** libxv-dev ~~(1.0.2 is known to work)~~

View file

@ -759,7 +759,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200808180346" created="200708120103" tags="organization buildsys" changecount="17">
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200808190850" created="200708120103" tags="organization buildsys" changecount="18">
<pre>for __Building__
* gcc (4.1), glibc6 (2.3), libstdc++6 (4.1)
* [[build system|BuildSystem]] dependencies: SCons (0.96.90), Python (2.4), pkg-config
@ -778,7 +778,7 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
** libcairomm-1.0-dev (&gt;=0.6.0)
** libgdl-1-dev (&gt;=0.6.1)
*** libbonoboui2-dev (&gt;=2.14.0)
** libgtkmm-2.4-dev (&gt;=2.16), requiring glib2.0 (&gt;=2.16)
** libglibmm-2.4-dev (&gt;=2.16), requiring glib2.0 (&gt;=2.16)
** libxv-dev (&gt;=1.0.2)
//usually, newer versions are OK//