# Creates an array of page-wide fields with quasi-random colors
# Breaks all RGB logic by simply adding values to the whole
# Language: Simple Inkscape Scripting (SIS, apparently)
# Details: https://inkscape.org/~pakin/%E2%98%85simple-inkscape-scripting
# Github: https://github.com/spakin/SimpInkScr
# colorcript version 0.3
#
# Copyright 2022 Joseph Smith
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without
# fee is hereby granted, provided that the above copyright notice and this permission notice
# appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# Bugs/shortcomings
# - does not necessarily align the output with the bottom of the page
# - has very unpredictable output (which also makes it interesting)
# N.B. tries to reach ffffff, which isn't always achieved due to rounding
# Settings
# Page dimensions. Best practice: create a page of the intended dimensions and set everything to px.
# (Document Properties -> Display units; Export PNG -> Units). In that case, these can be left unset.
# If set, make sure that at least Display units are set to px.
# If either of the folowing is not set, page dimensions of the document are used. Values may differ.
#pagewidth = 1000
#pageheight = 1000
# Entries below with a DEFAULT value can be commented out
fieldnum = 30 # MUST BE SET.
#printvalues = 'yes' # DEFAULTS TO 'no'
#invertcolors = 'yes' # DEFAULTS TO 'no'
# Exotic settings: may or may not yield anything of use or interest
# colorshift is the value by which the value (starting from 0 == 000000) is incremented
# Normally it is auto-determined from the number of fields to be printed.
#colorshift = 24 # DEFAULTS TO 0 for auto
#includeextremes = 'yes' # DEFAULTS TO 'no'; print fields for 000000 and ffffff as well
#colorsalt = 1 # DEFAULTS TO 0; positive or negative integer
# MAINTENANCE GUIDE
# fieldnum
# - determines eveything: no of fields AND increment
# colorshift
# - increment: value by which to increment RGB code in steps
# - calculated according to number of fields set with fieldnum
# colorsalt
# - is just a plaything (no relevance to the main loop)
# - determines whether to divide 0xffffff or 0x1000000
# fieldfactor
# - determines whether to divide by 0xf or 0x10
# coloroffset
# - determines which color to start from (000000 or the first incremented value)
# To include or exclude extremes (000000 black and ffffff white):
# 1. Include
# fieldfactor determines first color: 000000, aaaaaa, bbbbbb, .., ffffff
# E.g. 5 fields (cs = colorshift):
# 000000, aaaaaa, bbbbbb, cccccc, ffffff
# 0cs cs 2cs 3cs 4cs
# ffffff = 4cs ==> cs == ffffff / 4 == ffffff / (fieldnum - 1)
# fieldnum - 1: fieldnum + coloroffset with coloroffset = -1
# 2. Exclude
# fieldfactor determines first color: aaaaaa, bbbbbb, cccccc, .., ffffff - cs
# E.g. 5 fields (cs = colorshift):
# 000000*, aaaaaa, bbbbbb, cccccc, dddddd, eeeeee, ffffff* (* = not shown)
# 0cs cs 2cs 3cs 4cs 5cs 6cs
# ffffff = 6cs ==> cs == ffffff / 6 == ffffff / (fieldnum + 1)
# fieldnum + 1: fieldnum + coloroffset with coloroffset = 1
# Therefore: without includeextremes (no extremes shown):
# - fieldfactor can go (fixed value 1)
# - coloroffset can go (fixed value 1)
# This would probably be acceptable behavior
# Code section
# Return a hex string from a hex int value
def hex2str(value, chars = 6):
return('{0:0{1}x}'.format(value, chars))
if not 'printvalues' in globals(): printvalues = 'no'
if not 'includeextremes' in globals(): includeextremes = 'no'
if not 'invertcolors' in globals(): invertcolors = 'no'
if not 'colorshift' in globals(): colorshift = 0
if not 'colorsalt' in globals(): colorsalt = 0
# Page stuff.
# Set page dimensions if not set already. Pixel-oriented!
if ('pageheight' in globals()) and ('pagewidth' in globals()):
svg_root.set('width', '%spx' % pagewidth)
svg_root.set('height', '%spx' % pageheight)
width, height = svg_root.width, svg_root.height
svg_root.set('viewBox', '0 0 %.0f %.0f' % (width, height))
else:
pagewidth = float(svg_root.get('width').rstrip('px'))
pageheight = float(svg_root.get('height').rstrip('px'))
# Field stuff.
l1 = layer('Fields')
(xmin, ymin) = (0, 0)
fieldheight = int(pageheight / fieldnum)
(xmax, ymax) = (pagewidth, fieldheight)
# Weird stuff.
if (includeextremes == 'yes'):
fieldfactor = -1
coloroffset = 0
else:
fieldfactor = 1
coloroffset = 1
# Auto-determine color shift is not set
if (colorshift == 0):
colorshift = int((0xffffff + colorsalt) / (fieldnum + fieldfactor))
if (printvalues == 'yes'):
print('printing %d fields at color shift 0x%s (%d)' % (fieldnum, hex2str(colorshift), colorshift))
for i in range(fieldnum):
thiscolor = (i + coloroffset) * colorshift
if (invertcolors == 'yes'):
thiscolor = 0xffffff - thiscolor
fieldcolor = hex2str(thiscolor)
if (printvalues == 'yes'): print('%s' % fieldcolor)
field = rect((xmin, ymin), (xmin + xmax, ymin + ymax), stroke=0, stroke_width=0, fill = '#%s' % fieldcolor)
l1.add(field)
ymin = ymin + fieldheight