From cf3e524e50a6fae2862efb404c9918b74438e9c9 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 23 Oct 2018 16:07:09 -0700 Subject: [PATCH] Generate LED icons on the fly. Include SVG versions. This builds the required LED images from source code. Signed-off-by: Keith Packard --- icon/Makefile.am | 17 ++++- icon/grayled.png | Bin 1528 -> 0 bytes icon/grayon.png | Bin 1873 -> 0 bytes icon/greenled.png | Bin 2281 -> 0 bytes icon/greenoff.png | Bin 1811 -> 0 bytes icon/led.5c | 189 ++++++++++++++++++++++++++++++++++++++++++++++ icon/redled.png | Bin 2103 -> 0 bytes icon/redoff.png | Bin 1694 -> 0 bytes 8 files changed, 205 insertions(+), 1 deletion(-) delete mode 100644 icon/grayled.png delete mode 100644 icon/grayon.png delete mode 100644 icon/greenled.png delete mode 100644 icon/greenoff.png create mode 100644 icon/led.5c delete mode 100644 icon/redled.png delete mode 100644 icon/redoff.png diff --git a/icon/Makefile.am b/icon/Makefile.am index af238ac4..6efe3ecf 100644 --- a/icon/Makefile.am +++ b/icon/Makefile.am @@ -27,6 +27,17 @@ EEPROM_ICON = $(EEPROM_NAME).svg TELEM_ICON = $(TELEM_NAME).svg MPD_ICON = $(MPD_NAME).svg +LED_SVG = \ + redoff.svg \ + greenoff.svg \ + greenled.svg \ + grayon.svg \ + grayled.svg \ + redled.svg +LED_PNG = $(LED_SVG:.svg=.png) + +LED_ICONS = $(LED_SVG) $(LED_PNG) + # Files needed for Mac OSX icons MAC_AM_FILES = $(shell for i in $(MAC_RES); do echo $(AM_NAME)-$$i.png; done) @@ -109,7 +120,7 @@ java-telegps: fat: all $(ICO_FILES) $(ICNS_FILES) $(EXE_FILES) -all-local: $(JAVA_FILES) $(AM_XPM) +all-local: $(JAVA_FILES) $(AM_XPM) $(LED_ICONS) clean-local: $(RM) $(AM_NAME)-*.png $(TG_NAME)-*.png $(MP_NAME)-*.png @@ -117,6 +128,7 @@ clean-local: $(RM) $(EEPROM_NAME)-*.png $(TELEM_NAME)-*.png $(MPD_NAME)-*.png $(RM) *.build *.ico *.rc *.icns *.o *.exe $(MPD_ICON) $(RM) altusmetrum.xpm + $(RM) $(LED_ICONS) if INSTALL_SHARED_MIME_INFO install-data-hook: @@ -124,6 +136,9 @@ install-data-hook: update-icon-caches $(DESTDIR)$(ICON_THEME) endif +$(LED_ICONS): led.5c + nickle led.5c $@ + $(MPD_ICON): $(MP_ICON) $(LN_S) $(MP_ICON) $@ diff --git a/icon/grayled.png b/icon/grayled.png deleted file mode 100644 index bb6005c6caa0757fbf4580a615d12223f902609c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1528 zcmV-*4w}(ybcJ2l z>tL5MMh`B%j3p@qHo6^3iE00X!5BM?9X7_=9m=+YlU~Le5V3By6VE@u@#4giEWNiw zDyji@ z8DmdO)BLhfDAbSRmpkf#m6eqb1wnY&?RL*Jn@zOaZ5W0D%d$WSfoSwbfp|QwS(bIHP$)ckEdi^mt4W^cA9p&PwTdzFvg&&Dv8BnH?Cg2`qTRQy4#?x zfR{DjD3wZLDwRSqnS>w+;CX()905lWJ6U0jL6&6zfTn3Aolbvz>C&Z#&z?Oq0f0CT z1VQ+%TrNwpEJINgmrxLd0UIW0lsTE=I1Z^)3ZYO4&!0b^2nK_{IJ^XS(R91JyBD2? za~wDXei8m&@Rr0&>NNn!X0xc(YABb>@8(7FJY#4gI9s+>?LZMKF0Qfx`jiOSixQ7YLvRt!m8~uKNV9Y=7J&1TSFe?4q+uP2D z_m~KR@Kqv_K%>z(MDDeIzkf)`Fk-KOQE0VVNT<^vgnUiz-Md$d$K#qPim2D?Lq&KU zkIRH}9Y@}5HX+M0lF6ic|Ni|30RYRgZq3ZhKvmU44!zNjD#dZh0iaYWVRm*Fl+w=t z&!P0rojdCr8yjz1mW6CKJND@1Z^TiHjUTG2LXsq0zI?g(;K74;0MCgi5{X>P<#OG< zy**T`)sd-wou~nzR;xkRb(}wczN_o{HD}yC6FzD2a2K`n`jtRRmJY^ zF6QUw?RY%?QK3-y(>p)(_>#}(FZ6o7zcx2F->B7UID7W&D+_5hn<$k^NTpK9<#K!B zaQI50Q259H+_+z}NT<{Jxl*ZI(KL(%NF;K7b#?W>VecIIb9(#s?Td`DZySw9Zf9qQYqeT1O>^K7>hwh*5P+g6NT<^* znM`g0__Ra{ diff --git a/icon/grayon.png b/icon/grayon.png deleted file mode 100644 index c99b376ea1259b076d25b33d8210ad1cb91c35b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1873 zcmV-X2d?;uP)Ag1}nsH>umQ+h}VzZFMM5PUNFgdss8eGF3 zTj-^i-b&en4Ly{#9T2q8(u=JuR+CsBEH94$94o&l+)FL@Vk{!#!vgMi4 zywQB@Ve_Akw9Y2J5Z!JUQcC!~55^dRAb{(- zh@uFbbBvFVBbUozYHF(P`~FAOYW1`K3qYk($#c%{o}8R~yU}PsN{R9Dapd!PD2jqG z42NbA1aKS&jYb3Qb{mSKU~X;>rBdlZ7=|m`+uO(Q4d9K|pT2taO6zvJn4O))#KZ&u zAc`VHQ3L=(!Uux^f*^qJ`v`&n2L}hJ)oRFQv$%Tos%03)cel5<|NTw?w{G3~X%t1j zuh;8rY-|j(v$J4~0RR+5fe-?zR0^q73Q-gx3`6+7kHKI7DJ5Ljh2uCen5R#lqSx!; z`t|F<IIS_BO|D@4q#15xv8gyNc1)8Rb zbUHm`0y0AsMF@fbp69`JT?iq-7>n0^-;ejCl(>BPGV1j@N~O{t0en+zY;0VxEb9Z$ z^Wsn=%}7%MqN*wsMTw0u49an8T8N73QBF4E~Vq?E|za(MCL1={U)d3}AoAcPQ` z&1MssOlBz5NSLas@zixargoHO@(I&4W8qRtNGW55G);?5vA4H}>FMcTvM7pfcDr5V z^La#36o(p7O}0&jALks5u~>6@roGX~Nj?L>%*+froesh<{DF{C7NnF=6lF*=5}p(i zMG+WdNTpIS)pP~`7-I;-5S;TN=12*O9$nWdXIv1T=cR)nKp2KGjdUShN)DG4L_i1t zfur>#i=#6L0x-rPr8LA~Fi0h{8ih?#AURd?{cS9ePtZOA8dWTnO2P9y#zw1JGQAR@ zw@ngABl(;JGrFD}f^#0auFFU$RWnMjROLA5F+0f!0RESblfr1t_x&M7l8maV8Vbgk z8-}3~1OWiVLMgpckxAzNQQApZa(bQ@-!ZyJ=QT~Ug{Emu&iQ4>abOq*q?GVHFD|XB zs>V5f)Y+0W)8&){T-S}W9|7@w9{|wr_o1pP(&==A0r=-r4K2M5}VgS%;wW#3TWkQHw=W;o;+wHimN=~ZlR9-#Li-jjmMLECM z>%p=t*tQMFafX1V zaeRC{RL`kICmWBXDTsw66Si#w0QUFy;kqss78Wemb(iCen2hbUwY6(UM@J7IJb1uM zr4kB-0)Q|3gLFDQ)SMCk3dN+Eq?B<4knmQkg~i3iU}9q8+U?u7pPUKc4Tv8e9UcAY z;lqdAFbvGk&&PYCjpA*BiT)K1#7cXA?Jd??+R4SF;S!dq)bGo*+ zb}fpcKeXHJ^4{KFs?+Jf^Sq&QOvOf3Rb;bS6pO_upU?jnz|X4H>c773{&xbPvAVkY z4aV5VVHhsEu6wcH?;C@`fB}G_C}BFCc642T#W}wl1i^3L_xJn@eBO8WdZOu*00000 LNkvXXu0mjf!xWZi diff --git a/icon/greenled.png b/icon/greenled.png deleted file mode 100644 index d7663961f22f33b6d6f42193acc3d71d89684f21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2281 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 BdGY`N diff --git a/icon/led.5c b/icon/led.5c new file mode 100644 index 00000000..cdbcdc79 --- /dev/null +++ b/icon/led.5c @@ -0,0 +1,189 @@ +/* + * Copyright © 2018 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +/* + * Generate LED images for rocketview and launchcontrol + */ + +autoimport Cairo; + +void led (cairo_t cr, real red, real green, real blue, bool on) +{ + translate (cr, .5, .5); + + /* basic unilluminated LED */ + + if (true) + { + set_source_rgb (cr, red *.4, green *.4, blue *.4); + move_to (cr, 1, 1/2); + arc (cr, .5, .5, .5, 0, pi*2); + fill (cr); + } + + /* Bright spot of LED illumination */ + if (on) + { + pattern_t led = Pattern::create_radial (1/2, 1/2, 0, + 1/2, 1/2, .4); + Pattern::add_color_stop_rgba (led, 0, red, green, blue, 1); + Pattern::add_color_stop_rgba (led, .5, red, green, blue, .8); + Pattern::add_color_stop_rgba (led, 1, red, green, blue, 0); + set_source (cr, led); + move_to (cr, 1, 1/2); + arc (cr, .5, .5, .5, 0, pi*2); + fill (cr); + } + + /* Bezel */ + if (true) + { + pattern_t ring = Pattern::create_radial (.5, .5, .4, .5, .5, .5); + Pattern::add_color_stop_rgba (ring, 0, 0, 0, 0, 1); + Pattern::add_color_stop_rgba (ring, .5, 0, 0, 0, 1); + Pattern::add_color_stop_rgba (ring, 1, .5, .5, .5, 1); + set_source (cr, ring); + move_to (cr, 1, 1/2); + arc (cr, .5, .5, .5, 0, pi*2); + move_to (cr, 1, 1/2); + arc_negative (cr, .5, .5, .45, pi*2, 0); + fill (cr); + } + + /* Specular highlight from room illumination */ + if (true) + { + pattern_t room = Pattern::create_radial (1/3, 1/3, 0, 1/3, 1/3, 1/2); + Pattern::add_color_stop_rgba (room, 0, 1, 1, 1, .4); + Pattern::add_color_stop_rgba (room, 1, 1, 1, 1, 0); + set_source (cr, room); + move_to (cr, 1, 1/2); + arc (cr, .5, .5, .5, 0, pi*2); + fill (cr); + } + +} + +/* + * Desired LED image size in pixels + */ +int diameter = 12; + +void do_one_svg (string name, real red, real green, real blue, bool on) +{ + cairo_t cr = new_svg (name, diameter, diameter); + + translate (cr, -width(cr)/2, -height(cr)/2); + scale (cr, width(cr), height(cr)); + led (cr, red, green, blue, on); + destroy (cr); +} + +void do_one_png (string name, real red, real green, real blue, bool on) +{ + cairo_t cr = new_image (diameter, diameter); + + translate (cr, -width(cr)/2, -height(cr)/2); + scale (cr, width(cr), height(cr)); + led (cr, red, green, blue, on); + write_to_png (cr, name); + destroy (cr); +} + +void do_one(string name, real red, real green, real blue, bool on) +{ + do_one_png(name + ".png", red, green, blue, on); + do_one_svg(name + ".svg", red, green, blue, on); +} + +void doit () +{ + do_one ("redled", 1, 0, 0, true); + do_one ("redoff", 1, 0, 0, false); + do_one ("greenled", 0, 1, .4824, true); + do_one ("greenoff", 0, 1, .4824, false); + do_one ("grayled", .9, .9, .9, false); + do_one ("grayon", .9, .9, .9, true); +} + +typedef struct { + real red, green, blue; + bool on; +} stock_t; + +stock_t[string] stock_leds = { + "redled" => { + .red = 1, + .green = 0, + .blue = 0, + .on = true + }, + "redoff" => { + .red = 1, + .green = 0, + .blue = 0, + .on = false + }, + "greenled" => { + .red = 0, + .green = 1, + .blue = .4824, + .on = true + }, + "greenoff" => { + .red = 0, + .green = 1, + .blue = .4824, + .on = false + }, + "grayon" => { + .red = .9, + .green = .9, + .blue = .9, + .on = true + }, + "grayled" => { + .red = .9, + .green = .9, + .blue = .9, + .on = false + }, +}; + +void main () +{ + for (int i = 1; i < dim(argv); i++) { + string name = argv[i]; + string[] bits = String::split(name, "."); + + if (dim(bits) != 2) { + File::fprintf(stderr, "Filename is weird: \"%s\"\n", argv[i]); + exit (1); + } + + stock_t stock = stock_leds[bits[0]]; + switch (bits[1]) { + case "png": + do_one_png(argv[i], stock.red, stock.green, stock.blue, stock.on); + break; + case "svg": + do_one_svg(argv[i], stock.red, stock.green, stock.blue, stock.on); + break; + } + } +} + +if (dim(argv) > 0) { + main(); +} diff --git a/icon/redled.png b/icon/redled.png deleted file mode 100644 index 230afae09987ed6a09edb6a06de34f9ba0d8557e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2103 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 -- 2.30.2