[gnome-icon-theme/one-canvas] Add one canvas conversion script (to remove it again in the next commit).



commit e231de4735edbf208876c6b042d4a6d314d6711a
Author: Benjamin Berg <benjamin sipsolutions net>
Date:   Sun Jul 5 20:14:16 2009 +0100

    Add one canvas conversion script (to remove it again in the next commit).

 find_icons.py   |   54 ++++++++++
 icon_builder.py |  298 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 template.svg    |  199 +++++++++++++++++++++++++++++++++++++
 3 files changed, 551 insertions(+), 0 deletions(-)
---
diff --git a/find_icons.py b/find_icons.py
new file mode 100755
index 0000000..18b211a
--- /dev/null
+++ b/find_icons.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+"""
+License: Public Domain
+
+This scans the directory to find all icon files in an icon theme. It has an
+hardcoded list of directories to search. The scalable directory (if found)
+is assumed to contain 48x48 icons.
+"""
+
+import os
+import os.path
+import sys
+
+
+def find_icons(theme_path):
+    icons = {}
+
+    for size_dir in ['16x16', '22x22', '32x32', 'scalable', '48x48']:
+        size = size_dir
+        if size_dir == 'scalable':
+            size = "48x48"
+
+        if not os.path.exists(os.path.join(theme_path, size_dir)):
+            continue
+
+        for context in os.listdir(os.path.join(theme_path, size_dir)):
+            dir = os.path.join(theme_path, size_dir, context)
+
+            if not os.path.isdir(dir):
+                continue
+            
+            for icon in os.listdir(dir):
+                if icon[-4:] == ".svg":
+                    if not icons.has_key((icon[0:-4], context)):
+                        icons[(icon[0:-4], context)] = {}
+                    
+                    icons[(icon[0:-4], context)][size] = os.path.join(dir, icon)
+
+                if icon[-4:] == ".png":
+                    if not icons.has_key((icon[0:-4], context)):
+                        icons[(icon[0:-4], context)] = {}
+
+                    if not size in icons[(icon[0:-4], context)]:
+                        icons[(icon[0:-4], context)][size] = os.path.join(dir, icon)
+
+    return icons
+
+
+if __name__ == '__main__':
+    import pprint
+    icons = find_icons(sys.argv[1])
+    pprint.pprint(icons)
+    print "Number: %i" % len(icons)
+    
diff --git a/icon_builder.py b/icon_builder.py
new file mode 100755
index 0000000..22f2c9a
--- /dev/null
+++ b/icon_builder.py
@@ -0,0 +1,298 @@
+#! /usr/bin/env python
+"""
+License: Public Domain
+
+This script aggregates icons onto one canvas. It is supposed to facilitate the
+conversion of icon themes to the one canvas workflow.
+
+The copyright on the template.svg belongs to Jacub Steiner. 
+"""
+
+import os
+from find_icons import find_icons
+import sys
+import xml.dom.minidom
+
+icons = find_icons(sys.argv[1])
+
+
+def nodes_differ(node1, node2):
+    collision = False
+
+
+    if node1.attributes is None and node2.attributes is None:
+        return False
+    if node1.attributes is None or node2.attributes is None:
+        return True
+
+    if dict(node1.attributes).keys() != dict(node2.attributes).keys():
+        for key in dict(node1.attributes).keys():
+            if node1.getAttribute(key) != node2.getAttribute(node2):
+                return True
+    
+    child1 = node1.firstChild
+    child2 = node2.firstChild
+    while child1 and child2:
+        if child1.nodeType != node1.ELEMENT_NODE:
+            child1.nextSibling
+        if child2.nodeType != node1.ELEMENT_NODE:
+            child2.nextSibling
+    
+        if nodes_differ(child1, child2):
+            return True
+
+        return False
+    
+    return False
+
+def parse_defs(node, defs):
+    collision = False
+    child = node.firstChild
+    while child:
+        if child.nodeType == node.ELEMENT_NODE:
+            id = child.getAttribute('id')
+            
+            next_child = child.nextSibling
+            node.removeChild(child)
+            found = False
+            for def_id, definition in defs:
+                if def_id == id:
+                    found = True
+                    break
+            if not found:
+                defs.append((id, child))
+            else:
+                if nodes_differ(child, definition):
+                    collision = True
+            child = next_child
+
+            continue
+
+        child = child.nextSibling
+    return collision
+
+def build_icon_data(icon, size, data):
+    collision = False
+    dom = xml.dom.minidom.parse(icon)
+    child = dom.firstChild
+    while child:
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "svg":
+            node = child
+            break
+        child = child.nextSibling
+
+    objects = []
+
+    pxsize = float(size.split('x')[0])
+    data["scales"][size] = (pxsize / float(node.getAttribute("width").strip('px')), \
+                            pxsize / float(node.getAttribute("height").strip('px')))
+    
+    child = node.firstChild
+    while child:
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "metadata":
+            sfw = child.firstChild
+            while sfw:
+                if sfw.nodeType != dom.ELEMENT_NODE or sfw.tagName != "ns:sfw":
+                    sfw = sfw.nextSibling
+                    continue
+                
+                sliceSourceBounds = sfw.firstChild
+                while sliceSourceBounds:
+                    if sliceSourceBounds.nodeType != dom.ELEMENT_NODE or sliceSourceBounds.tagName != "ns:sliceSourceBounds":
+                        sliceSourceBounds = sliceSourceBounds.nextSibling
+                        continue
+                    
+                    if sliceSourceBounds.hasAttribute("y"):
+                        y = float(sliceSourceBounds.getAttribute("y").strip("px"))
+                    else:
+                        y = 0
+                    if sliceSourceBounds.hasAttribute("x"):
+                        x = float(sliceSourceBounds.getAttribute("x").strip("px"))
+                    else:
+                        x = 0
+
+                    if y != 0 or x != 0:
+                        data["translates"][size] = (x, y)
+
+                    sliceSourceBounds = sliceSourceBounds.nextSibling
+                
+                sfw = sfw.nextSibling
+
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "defs":
+            ret = parse_defs(child, data["defs"])
+            collision = ret or collision
+
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName.find(':') == -1 \
+           and not child.tagName in ["metadata", "defs"]:
+
+            include = True
+            if child.tagName == "g":
+                group_child = child.firstChild
+                include = False
+                while group_child:
+                    if group_child.nodeType == dom.ELEMENT_NODE:
+                        include = True
+                        break
+                    group_child = group_child.nextSibling
+
+            if include:
+                next_child = child.nextSibling
+                node.removeChild(child)
+                objects.append(child)
+                child = next_child
+
+                continue
+        
+        child = child.nextSibling
+
+    data["icons"][size] = objects
+    return collision
+
+
+import base64
+
+def build_size_objects(doc, node, scales, translates, icon_objects):
+    child = node.firstChild
+    
+    while child:
+        if child.nodeType == node.ELEMENT_NODE and child.tagName == "g":
+            id = child.getAttribute("id")
+            size = id[1:]+"x"+id[1:]
+
+            if size in scales:
+                transform = child.getAttribute("transform")
+                transform += " scale(%f,%f)" % scales[size]
+                child.setAttribute("transform", transform)
+
+            if size in translates:
+                transform = child.getAttribute("transform")
+                transform += " translate(%f,%f)" % translates[size]
+                child.setAttribute("transform", transform)
+
+            if size in icon_objects:
+                data = icon_objects[size]
+                if isinstance(data, type("")):
+                    # embed an image
+                    
+                    image = open(data)
+                    image_data = base64.b64encode(image.read())
+
+                    image_node = doc.createElement("svg:image")
+                    image_node.setAttribute("id", "image"+id[1:])
+                    image_node.setAttribute("x", "0")
+                    image_node.setAttribute("y", "0")
+                    image_node.setAttribute("width", id[1:])
+                    image_node.setAttribute("height", id[1:])
+                    image_node.setAttribute("xlink:href", "data:image/png;base64,"+image_data)
+
+                    child.appendChild(image_node)
+                else:
+                    objects = data
+                    for obj in objects:
+                        if obj.tagName.startswith('i:'):
+                            # Ignore anything from the illustrator namespace ...
+                            continue
+
+                        if obj.tagName != "g" and obj.hasAttribute("style") or obj.hasAttribute("transform"):
+                            clone = obj.cloneNode(True)
+                            child.appendChild(clone)
+                            
+                            continue
+                    
+                        group_child = obj.firstChild
+                        while group_child:
+                            clone = group_child.cloneNode(True)
+                            child.appendChild(clone)
+
+                            group_child = group_child.nextSibling
+        
+        child = child.nextSibling
+
+def build_icon(name, context, data):
+    
+    dom = xml.dom.minidom.parse(os.path.join(os.path.dirname(__file__), "template.svg"))
+    
+    child = dom.firstChild
+    while child:
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "svg":
+            node = child
+            break
+        child = child.nextSibling
+
+    child = node.firstChild
+    while child:
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "defs":
+            for def_id, definition in data["defs"]:
+                child.appendChild(definition)
+
+        if child.nodeType == dom.ELEMENT_NODE and child.tagName == "g":
+            id = child.getAttribute("id")
+            if id == "layer6":
+                rect = child.firstChild
+                while rect:
+                    if rect.nodeType != dom.ELEMENT_NODE or rect.tagName != "rect":
+                        rect = rect.nextSibling
+                        continue
+                    size = rect.getAttribute("inkscape:label")
+                    if not data["icons"].has_key(size):
+                        next = rect.nextSibling
+                        
+                        child.removeChild(rect)
+                        
+                        rect = next
+                        continue
+                    rect = rect.nextSibling
+            else:
+                #child.setAttribute("inkscape:label", "artwork:"+ name)
+                build_size_objects(dom, child, data["scales"], data["translates"], data["icons"])
+                
+        
+        child = child.nextSibling
+
+
+    # Replace the strings
+    for in_node in node.getElementsByTagName("text"):
+        if in_node.getAttribute("inkscape:label") == "icon-name":
+            span = in_node.getElementsByTagName("tspan")[0]
+            text = span.firstChild
+            assert text.nodeType == dom.TEXT_NODE
+            
+            text.data = name
+                
+
+        if in_node.getAttribute("inkscape:label") == "context":
+            span = in_node.getElementsByTagName("tspan")[0]
+            text = span.firstChild
+            assert text.nodeType == dom.TEXT_NODE
+            
+            text.data = context
+
+    if not os.path.exists(os.path.join('.', 'svgs', context)):
+        os.mkdir(os.path.join('.', 'svgs', context))
+    file = open(os.path.join('.', 'svgs', context, name+".svg"), "w")
+    file.write(dom.toxml(encoding="utf-8"))
+    file.close()
+
+for icon_info, sizes in icons.iteritems():
+    data = {}
+    data["defs"] = []
+    data["icons"] = {}
+    data["scales"] = {}
+    data["translates"] = {}
+    
+    if True:
+        collision = False
+        for size, file in sizes.iteritems():
+            if file[-4:] == ".svg":
+                collision = build_icon_data(file, size, data) or collision
+            else:
+                data["icons"][size] = file
+
+        if collision:
+            print "Possible def collision in icon %s" % icon_info[0]
+
+        build_icon(icon_info[0], icon_info[1], data)
+    else:
+        print "Failed for icon %s" % icon_info[0]
+        sys.exit(1)
+
diff --git a/template.svg b/template.svg
new file mode 100644
index 0000000..4da5975
--- /dev/null
+++ b/template.svg
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="300"
+   id="svg11300"
+   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+   inkscape:export-xdpi="90.000000"
+   inkscape:export-ydpi="90.000000"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:version="0.46"
+   sodipodi:docname="template.svg"
+   sodipodi:version="0.32"
+   style="display:inline;enable-background:new"
+   version="1.0"
+   width="400">
+  <title
+     id="title8836">Optical Drive</title>
+  <metadata
+     id="metadata154">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title />
+          </cc:Agent>
+        </dc:creator>
+        <dc:contributor>
+          <cc:Agent>
+            <dc:title />
+          </cc:Agent>
+        </dc:contributor>
+        <dc:source />
+        <cc:license
+           rdf:resource="" />
+        <dc:subject>
+          <rdf:Bag />
+        </dc:subject>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     bordercolor="#666666"
+     borderopacity="0.25490196"
+     fill="#f57900"
+     gridtolerance="12"
+     guidetolerance="13"
+     height="300px"
+     id="base"
+     inkscape:current-layer="layer6"
+     inkscape:cx="144.68008"
+     inkscape:cy="87.105301"
+     inkscape:document-units="px"
+     inkscape:grid-bbox="true"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:showpageshadow="false"
+     inkscape:snap-bbox="true"
+     inkscape:snap-nodes="true"
+     inkscape:window-height="876"
+     inkscape:window-width="968"
+     inkscape:window-x="132"
+     inkscape:window-y="8"
+     inkscape:zoom="1"
+     objecttolerance="7"
+     pagecolor="#ffffff"
+     showgrid="false"
+     stroke="#ef2929"
+     width="400px"
+     showguides="true"
+     inkscape:guide-bbox="true">
+    <inkscape:grid
+       enabled="true"
+       id="grid5883"
+       spacingx="0.5px"
+       spacingy="0.5px"
+       type="xygrid"
+       visible="true"
+       empspacing="2" />
+  </sodipodi:namedview>
+  <defs
+     id="defs3" />
+    <g
+       id="layer6"
+       inkscape:groupmode="layer"
+       inkscape:label="baseplate"
+       style="display:none">
+      <rect
+         height="48"
+         id="rect6284"
+         inkscape:label="48x48"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="48"
+         x="296"
+         y="50" />
+      <rect
+         height="32"
+         id="rect6592"
+         inkscape:label="32x32"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="32"
+         x="303"
+         y="126" />
+      <rect
+         height="22"
+         id="rect6749"
+         inkscape:label="22x22"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="22"
+         x="303"
+         y="177" />
+      <rect
+         height="16"
+         id="rect6833"
+         inkscape:label="16x16"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="16"
+         x="303"
+         y="219" />
+      <rect
+         height="24"
+         id="rect8104"
+         inkscape:label="24x24"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="24"
+         x="302"
+         y="176" />
+      <rect
+         height="256"
+         id="rect6282"
+         inkscape:label="256x256"
+         style="fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         width="256"
+         x="16"
+         y="28" />
+      <text
+         id="context"
+         inkscape:label="context"
+         style="font-size:18.30070686px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Bitstream Vera Sans"
+         x="20.970737"
+         xml:space="preserve"
+         y="21.513618"><tspan
+           id="tspan2716"
+           sodipodi:role="line"
+           x="20.970737"
+           y="21.513618">icon-type</tspan></text>
+      <text
+         id="icon-name"
+         inkscape:label="icon-name"
+         sodipodi:linespacing="125%"
+         style="font-size:18.30070686px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;display:inline;enable-background:new;font-family:Droid Sans;-inkscape-font-specification:Droid Sans Bold"
+         x="191.97073"
+         xml:space="preserve"
+         y="21.513618"><tspan
+           id="tspan3023"
+           sodipodi:role="line"
+           x="191.97073"
+           y="21.513618">icon-name</tspan></text>
+    </g>
+    <g
+       inkscape:groupmode="layer"
+       id="layer2"
+       inkscape:label="small sizes"
+       style="display:inline">
+       <g
+          style="display:inline;enable-background:new"
+          id="g48"
+          transform="translate(296,50)" />
+       <g
+          style="display:inline;enable-background:new"
+          id="g32"
+          transform="translate(303,126)" />
+       <g
+          style="display:inline;enable-background:new"
+          transform="translate(303,177)"
+          id="g22" />
+       <g
+          style="display:inline;enable-background:new"
+          id="g16"
+          transform="translate(303,219)" />
+    </g>
+    <g
+       inkscape:groupmode="layer"
+       id="layer4"
+       inkscape:label="hires"
+       style="display:inline" />
+</svg>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]