diff --git a/.gitignore b/.gitignore index 05b994c..9434000 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ configure install-sh missing *.tmp +*_timestamp +*.cache diff --git a/src/SplitJob.class b/src/SplitJob.class new file mode 100644 index 0000000..10c467d Binary files /dev/null and b/src/SplitJob.class differ diff --git a/src/SplitJob.java b/src/SplitJob.java new file mode 100644 index 0000000..8498be6 --- /dev/null +++ b/src/SplitJob.java @@ -0,0 +1,54 @@ + +import java.io.*; + +import static java.lang.ProcessBuilder.Redirect; + +public class SplitJob { + + private static final BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + + + public static void main(String[] args) { + + final Runtime runtime = Runtime.getRuntime(); + int numThreads = runtime.availableProcessors(); + Process[] procs = new Process[numThreads]; + + try { + + ProcessBuilder builder = new ProcessBuilder(args); + builder.redirectError(Redirect.INHERIT); + + for (int i = 0; i < numThreads; i++) { + procs[i] = builder.start(); + } + + for (int i = 0; ; i = (i + 1) % numThreads) { + + String s = in.readLine(); + + if (s == null) + break; + + byte[] data = (s + '\n').getBytes(); + procs[i].getOutputStream().write(data, 0, data.length); + procs[i].getOutputStream().flush(); + } + + for (Process proc : procs) { + + proc.getOutputStream().close(); + int exitCode = proc.waitFor(); + + if (exitCode != 0) { + System.err.printf("[Error] %s stopped with exit code: %d\n", args[0], exitCode); + System.exit(2); + } + } + + } catch (Exception e) { + System.err.printf("[Error] %s: %s\n", e.getClass().getName(), e.getMessage()); + System.exit(1); + } + } +} diff --git a/src/render_icons.sh b/src/render_icons.sh old mode 100644 new mode 100755 index 9152e8d..bbbe079 --- a/src/render_icons.sh +++ b/src/render_icons.sh @@ -1,7 +1,6 @@ #!/bin/bash INKSCAPE="/usr/bin/inkscape" -OPTIPNG="/usr/bin/optipng" pushd `dirname $0` > /dev/null DIR="$( cd "$(dirname "$0")" ; pwd -P )" @@ -9,62 +8,116 @@ popd > /dev/null cd ${DIR} -THEMEDIR=../Arc - -mkdir -p $THEMEDIR +TYPES=(actions apps categories devices emblems mimetypes places status) +SIZES=(16 22 24 32 48 64 96 128) -for CONTEXT in actions apps categories devices emblems mimetypes places status -do +THEMEDIR=../Arc - mkdir -p $THEMEDIR/$CONTEXT - mkdir -p $THEMEDIR/$CONTEXT +# Set up all the folders in the theme directory. +mkdir -p $THEMEDIR/{actions,apps,categories,devices,emblems,mimetypes,places,status}/{16,22,24,32,48,64,96,128}{,@2x} - cp -r $CONTEXT/symbolic $THEMEDIR/$CONTEXT +cp -u index.theme $THEMEDIR/index.theme - for SIZE in 16 22 24 32 48 64 96 128 +for CONTEXT in ${TYPES[@]} +do + for SIZE in ${SIZES[@]} do - $INKSCAPE -S $CONTEXT.svg | grep -E "_$SIZE" | sed 's/\,.*$//' > index.tmp - - mkdir -p $THEMEDIR/$CONTEXT/$SIZE - mkdir -p $THEMEDIR/$CONTEXT/$SIZE@2x - - cp -r $CONTEXT/symlinks/* $THEMEDIR/$CONTEXT/$SIZE - cp -r $CONTEXT/symlinks/* $THEMEDIR/$CONTEXT/$SIZE@2x - - for OBJECT_ID in `cat index.tmp` - do - - ICON_NAME=$(sed "s/\_$SIZE.*$//" <<< $OBJECT_ID) - - if [ -f $THEMEDIR/$CONTEXT/$SIZE/$ICON_NAME.png ]; then - echo $THEMEDIR/$CONTEXT/$SIZE/$ICON_NAME.png exists. - else - echo - echo Rendering $THEMEDIR/$CONTEXT/$SIZE/$ICON_NAME.png - $INKSCAPE --export-id=$OBJECT_ID \ - --export-id-only \ - --export-png=$THEMEDIR/$CONTEXT/$SIZE/$ICON_NAME.png $CONTEXT.svg >/dev/null \ - && $OPTIPNG -o7 --quiet $ASSETS_DIR/$i.png - fi - if [ -f $THEMEDIR/$CONTEXT/$SIZE@2x/$ICON_NAME.png ]; then - echo $THEMEDIR/$CONTEXT/$SIZE@2x/$ICON_NAME.png exists. - else - echo - echo Rendering $THEMEDIR/$CONTEXT/$SIZE@2x/$ICON_NAME.png - $INKSCAPE --export-id=$OBJECT_ID \ - --export-dpi=180 \ - --export-id-only \ - --export-png=$THEMEDIR/$CONTEXT/$SIZE@2x/$ICON_NAME.png $CONTEXT.svg >/dev/null \ - && $OPTIPNG -o7 --quiet $ASSETS_DIR/$i@2.png - fi - done + cp -ru $CONTEXT/symlinks/* $THEMEDIR/$CONTEXT/$SIZE + cp -ru $CONTEXT/symlinks/* $THEMEDIR/$CONTEXT/$SIZE@2x + cp -ru $CONTEXT/symbolic $THEMEDIR/$CONTEXT done done -rm index.tmp -cp index.theme $THEMEDIR/index.theme rm -rf $THEMEDIR/actions/{32,32@2x,48,48@2x,64,64@2x,96,96@2x,128,128@2x} # derp # TODO -cp -r animations $THEMEDIR/. -cp -r panel $THEMEDIR/. +cp -ru animations $THEMEDIR/. +cp -ru panel $THEMEDIR/. + +# Ensure cache folder exists +mkdir .cache + +# Takes in an svg-file and an object-id and formats it +# to an inkscape export shell command that inkscape can +# then execute. +formatInkscapeCmd() { + + local CONTEXT=$1 + local OBJECT_ID=$2 + local SIZE=$(sed -r 's/.*\_([0-9]+).*$/\1/' <<< $OBJECT_ID) + + local ICON_NAME=$(sed "s/\_$SIZE.*$//" <<< $OBJECT_ID) + + echo \ + "--export-id=$OBJECT_ID" \ + "--export-id-only" \ + "--export-png=$THEMEDIR/$CONTEXT/$SIZE/$ICON_NAME.png $CONTEXT.svg" + + echo \ + "--export-id=$OBJECT_ID" \ + "--export-dpi=180" \ + "--export-id-only" \ + "--export-png=$THEMEDIR/$CONTEXT/$SIZE@2x/$ICON_NAME.png $CONTEXT.svg" +} + +# Generates inkscape export commands for the given +# svg-file that can be piped to inkscape. +genInkscapeCmds() { + + local CONTEXT=$1 + + for SIZE in ${SIZES[@]} + do + for OBJECT_ID in `cat <($INKSCAPE -S $CONTEXT.svg | grep -E "_$SIZE" | sed 's/\,.*$//')` + do + echo $OBJECT_ID >> .cache/$CONTEXT.cache.tmp + formatInkscapeCmd $CONTEXT $OBJECT_ID + done + done + mv .cache/$CONTEXT.cache.tmp .cache/$CONTEXT.cache +} + +# Generates inkscape export commands that matches +# the provided regex pattern. +genInkscapeCmdsFiltered() { + + local CONTEXT=$1 + local REGEX=$2 + + while read -r OBJECT_ID + do + echo "Match: $OBJECT_ID" >&2 + formatInkscapeCmd $CONTEXT $OBJECT_ID + done < <(grep -E $REGEX .cache/$CONTEXT.cache) +} + +if [[ ! -z $1 ]] +then + echo "Rendering objects with IDs matching regex" + for CONTEXT in ${TYPES[@]} + do + if [[ -f .cache/$CONTEXT.cache ]] || { [[ ! -f .cache/$CONTEXT.cache ]] && ($INKSCAPE -S $CONTEXT.svg | grep -E "_[0-9]+" | sed 's/\,.*$//' > .cache/$CONTEXT.cache.tmp); } + then + mv .cache/$CONTEXT.cache.tmp .cache/$CONTEXT.cache 2> /dev/null + genInkscapeCmdsFiltered $CONTEXT $1 | java SplitJob $INKSCAPE --shell + else + echo "Failed creating creating object-ID cache for $CONTEXT.svg" + fi + done +else + for CONTEXT in ${TYPES[@]} + do + # Only render out the icons if the svg-file has been modified + # since we finished rendering it out last. + if [[ $CONTEXT.svg -nt .cache/${CONTEXT}_timestamp ]] + then + echo "Rendering icons from $CONTEXT.svg" + genInkscapeCmds $CONTEXT | java SplitJob $INKSCAPE --shell && touch .cache/${CONTEXT}_timestamp + else + echo "No changes to $CONTEXT.svg, skipping..." + fi + done +fi + +# Remove all empty directories from the theme folder. +find $THEMEDIR -type d -empty -delete