mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-07-14 18:42:18 +01:00
171 lines
6.5 KiB
Plaintext
171 lines
6.5 KiB
Plaintext
|
|
/* *********************************************************************
|
|
_____ _ ______ _ _ _____
|
|
/ ____| | | | ____| | | | |_ _|
|
|
| | __ ___| |_ | |__ | | __ _| |_ | | ___ ___ _ __
|
|
| | |_ |/ _ \ __| | __| | |/ _` | __| | | / __/ _ \| '_ \
|
|
| |__| | __/ |_ | | | | (_| | |_ _| || (_| (_) | | | |
|
|
\_____|\___|\__| |_| |_|\__,_|\__| |_____\___\___/|_| |_|
|
|
|
|
Created by David "DarkCampainger" Braun
|
|
|
|
Released under the Unlicense (see end of file)
|
|
|
|
Version 3.0 - September 19, 2014
|
|
|
|
*///////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
// Associative list of [md5 values = Icon] for determining if the icon already exists
|
|
var/list/_flatIcons = list()
|
|
|
|
proc
|
|
getFlatIcon(atom/A, dir, cache=1) // 1 = use cache, 2 = override cache, 0 = ignore cache
|
|
|
|
var/list/layers = list() // Associative list of [overlay = layer]
|
|
var/hash = "" // Hash of overlay combination
|
|
|
|
if(!dir) dir = A.dir // dir defaults to A's dir
|
|
|
|
var/parentColor = ""
|
|
if(A.color || A.alpha != 255)
|
|
parentColor = (A.color || "#FFFFFF") + copytext(rgb(0,0,0,A.alpha), 8)
|
|
|
|
// Add the atom's icon itself
|
|
if(A.icon)
|
|
// Make a copy without pixel_x/y settings
|
|
var/image/copy = image(icon=A.icon,icon_state=A.icon_state,layer=A.layer,dir=dir)
|
|
layers[copy] = A.layer
|
|
|
|
// Loop through the underlays, then overlays, sorting them into the layers list
|
|
var
|
|
list/process = A.underlays // Current list being processed
|
|
processSubset=0 // Which list is being processed: 0 = underlays, 1 = overlays
|
|
|
|
currentIndex=1 // index of 'current' in list being processed
|
|
currentOverlay // Current overlay being sorted
|
|
currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER)
|
|
|
|
compareOverlay // The overlay that the current overlay is being compared against
|
|
compareIndex // The index in the layers list of 'compare'
|
|
while(TRUE)
|
|
if(currentIndex<=process.len)
|
|
currentOverlay = process[currentIndex]
|
|
currentLayer = currentOverlay:layer
|
|
if(currentLayer<0) // Special case for FLY_LAYER
|
|
ASSERT(currentLayer > -1000)
|
|
if(processSubset == 0) // Underlay
|
|
currentLayer = A.layer+currentLayer/1000
|
|
else // Overlay
|
|
currentLayer = A.layer+(1000+currentLayer)/1000
|
|
|
|
// Sort add into layers list
|
|
for(compareIndex=1,compareIndex<=layers.len,compareIndex++)
|
|
compareOverlay = layers[compareIndex]
|
|
if(currentLayer < layers[compareOverlay]) // Associated value is the calculated layer
|
|
layers.Insert(compareIndex,currentOverlay)
|
|
layers[currentOverlay] = currentLayer
|
|
break
|
|
if(compareIndex>layers.len) // Reached end of list without inserting
|
|
layers[currentOverlay]=currentLayer // Place at end
|
|
|
|
currentIndex++
|
|
|
|
if(currentIndex>process.len)
|
|
if(processSubset == 0) // Switch to overlays
|
|
currentIndex = 1
|
|
processSubset = 1
|
|
process = A.overlays
|
|
else // All done
|
|
break
|
|
|
|
if(cache!=0) // If cache is NOT disabled
|
|
// Create a hash value to represent this specific flattened icon
|
|
hash = "[parentColor];__;"
|
|
for(var/I in layers)
|
|
hash += "\ref[I:icon],[I:icon_state],[I:dir != SOUTH ? I:dir : dir],[I:pixel_x],[I:pixel_y],[I:color],[I:alpha];_;"
|
|
hash=md5(hash)
|
|
|
|
if(cache!=2) // If NOT overriding cache
|
|
// Check if the icon has already been generated
|
|
if((hash in _flatIcons) && _flatIcons[hash])
|
|
// Icon already exists, just return that one
|
|
return _flatIcons[hash]
|
|
|
|
var
|
|
// We start with a blank canvas, otherwise some icon procs crash silently
|
|
icon/flat = icon('icons/misc/flatBlank.dmi') // Final flattened icon
|
|
icon/add // Icon of overlay being added
|
|
|
|
// Set current dimensions of flattened icon
|
|
flatX1=1
|
|
flatX2=flat.Width()
|
|
flatY1=1
|
|
flatY2=flat.Height()
|
|
|
|
// Dimensions of overlay being added
|
|
addX1;addX2;addY1;addY2
|
|
|
|
for(var/I in layers)
|
|
|
|
add = icon(I:icon || A.icon
|
|
, I:icon_state || (I:icon && (A.icon_state in icon_states(I:icon)) && A.icon_state)
|
|
, (I:dir != SOUTH ? I:dir : dir)
|
|
, 1
|
|
, 0)
|
|
|
|
// Apply any color or alpha settings
|
|
if(I:color || I:alpha != 255)
|
|
var/rgba = (I:color || "#FFFFFF") + copytext(rgb(0,0,0,I:alpha), 8)
|
|
add.Blend(rgba, ICON_MULTIPLY)
|
|
|
|
if(parentColor)
|
|
add.Blend(parentColor, ICON_MULTIPLY)
|
|
|
|
// Find the new dimensions of the flat icon to fit the added overlay
|
|
addX1 = min(flatX1, I:pixel_x+1)
|
|
addX2 = max(flatX2, I:pixel_x+add.Width())
|
|
addY1 = min(flatY1, I:pixel_y+1)
|
|
addY2 = max(flatY2, I:pixel_y+add.Height())
|
|
|
|
if(addX1!=flatX1 || addX2!=flatX2 || addY1!=flatY1 || addY2!=flatY2)
|
|
// Resize the flattened icon so the new icon fits
|
|
flat.Crop(addX1-flatX1+1, addY1-flatY1+1, addX2-flatX1+1, addY2-flatY1+1)
|
|
flatX1=addX1;flatX2=addX2
|
|
flatY1=addY1;flatY2=addY2
|
|
|
|
// Blend the overlay into the flattened icon
|
|
flat.Blend(add,ICON_OVERLAY,I:pixel_x+2-flatX1,I:pixel_y+2-flatY1)
|
|
|
|
if(cache!=0) // If cache is NOT disabled
|
|
// Cache the generated icon in our list so we don't have to regenerate it
|
|
_flatIcons[hash] = flat
|
|
|
|
return flat
|
|
|
|
/* License:
|
|
This is free and unencumbered software released into the public domain.
|
|
|
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
distribute this software, either in source code form or as a compiled
|
|
binary, for any purpose, commercial or non-commercial, and by any
|
|
means.
|
|
|
|
In jurisdictions that recognize copyright laws, the author or authors
|
|
of this software dedicate any and all copyright interest in the
|
|
software to the public domain. We make this dedication for the benefit
|
|
of the public at large and to the detriment of our heirs and
|
|
successors. We intend this dedication to be an overt act of
|
|
relinquishment in perpetuity of all present and future rights to this
|
|
software under copyright law.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
For more information, please refer to <http://unlicense.org/>
|
|
*/ |