<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.4">Jekyll</generator><link href="https://malcolmsoft.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://malcolmsoft.com/" rel="alternate" type="text/html" /><updated>2018-11-17T23:57:18+03:00</updated><id>https://malcolmsoft.com/</id><title type="html">Malcolm-Soft</title><subtitle>Hello there! My name is Alexander Gazarov, and this my personal website. Here you will find all my projects, blog posts, articles, and other contributions. Welcome!</subtitle><author><name>Alexander Gazarov</name></author><entry><title type="html">UTF-16 Anywhere?</title><link href="https://malcolmsoft.com/posts/utf-16-anywhere" rel="alternate" type="text/html" title="UTF-16 Anywhere?" /><published>2016-01-03T15:40:53+03:00</published><updated>2016-01-03T15:40:53+03:00</updated><id>https://malcolmsoft.com/posts/utf-16-anywhere</id><content type="html" xml:base="https://malcolmsoft.com/posts/utf-16-anywhere">&lt;p&gt;&lt;a href=&quot;http://programmers.stackexchange.com/q/303438/32689&quot;&gt;Another question about Unicode&lt;/a&gt; popped up not so long ago into the “attention magnet” list of questions on the StackExchange network. What’s interesting, even though the question itself is about the total characters possible using UTF-8, the discussion quickly jumped to the limitations of UTF-16 and how this standard needs to be phased out.&lt;/p&gt;

&lt;p&gt;It probably all began from the StackOverflow question, &lt;a href=&quot;http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful&quot;&gt;Should UTF-16 be Considered Harmful&lt;/a&gt;, which has since been migrated to &lt;a href=&quot;http://programmers.stackexchange.com&quot;&gt;Programmers.SE&lt;/a&gt;. The author of the top voted post didn’t settle with his answer though, and now there’s a whole website promoting UTF-8: &lt;a href=&quot;http://utf8everywhere.org/&quot;&gt;utf8everywhere.org&lt;/a&gt;. And I’ve been really curious about the effort he put into that.&lt;/p&gt;

&lt;!--cut--&gt;

&lt;p&gt;The facts on the website look correct overall, the only strange fact is that they say that&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;UTF-16 is often misused as a fixed-width encoding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem is, there is no such miracle as fixed-width UTF-16. If we always have two bytes per character, that’s UCS-2, period. It’s not UTF-16. That’s definitely a problem, but we’ll come back to it later.&lt;/p&gt;

&lt;p&gt;The conclusion section is the most interesting one. Here we can take the arguments one by one.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;UTF-16 is too wide.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Being too wide is not really much of a problem since earlier he makes the argument himself that compressed text size doesn’t differ between UTF-8 and UTF-16. And for efficient communication it will always be better to use compression, so this “disadvantage” doesn’t really hold any water.&lt;/p&gt;

&lt;p&gt;Where it &lt;em&gt;would&lt;/em&gt; matter is in the in-memory representations where compressing the strings back and forth would have a certain tax on performance. But it doesn’t necessarily mean that we should simply use UTF-8. For example, &lt;a href=&quot;http://openjdk.java.net/jeps/254&quot;&gt;JEP 254 on compacting strings in Java&lt;/a&gt; uses the approach of representing strings in ASCII where possible and in UTF-16 in all other cases. This will save the memory even better than UTF-8 because it will not only be at least as efficient as UTF-8, but it will also use two bytes where UTF-8 would use three.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It exists only for historical reasons and creates a lot of confusion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Historical reasons - that doesn’t say all, it exists for compatibility reasons (with UCS-2). And so does UTF-8, to be compatible with ASCII. As for creating lots of confusion, we’ll take a look at that later.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Adding &lt;code class=&quot;highlighter-rouge&quot;&gt;wchar_t&lt;/code&gt; to the C++ standard was a mistake, and so are the Unicode additions to C++11.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I believe that they shouldn’t have had &lt;code class=&quot;highlighter-rouge&quot;&gt;wchar_t&lt;/code&gt; in the standard as well, but the thing is the standard doesn’t really say anything about the relation between &lt;code class=&quot;highlighter-rouge&quot;&gt;wchar_t&lt;/code&gt; and Unicode. Isn’t this the fault of the vague standard though?&lt;/p&gt;

&lt;p&gt;This is even more supported by the website having a whole section on how to work with the strings in C++ on Windows. Not just any language or any platform, but this combination in particular.  It makes sense, of course, because the author (or at least one of them, since there are three names) even mentions primarily being a Windows developer, but it just looks strange to pay so much attention to a specific case on a site dealing with the encodings in general. Doesn’t so much attention to this special case hint that the problem lies in there and not with UTF-16?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Safety is an important feature of every design, and encodings are no exception.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here’s a fun fact: when you use UTF-8, it doesn’t automatically mean that you will get proper non-BMP code point support. I had my share of surprise when I found some time ago that MySQL apparently has a so called &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.7/en/charset-unicode-utf8mb4.html&quot;&gt;4-byte UTF-8 Unicode encoding&lt;/a&gt;. As it turns out, if you specify regular UTF-8, it will not handle non-BMP characters with the same effect as if they declared the use of UTF-16 and used UCS-2 instead. And this is a relatively recent addition, this wonderful encoding appeared in MySQL 5.5.3 in 2010, while (crippled) UTF-8 has been there long before that, successfully confusing people.&lt;/p&gt;

&lt;p&gt;So as we see UTF-8 can have problems too. Of course, there are much more cases of that with the UTF-16. But there’s nothing particularly wrong with UTF-16, it is as valid compatibility tool as UTF-8. &lt;strong&gt;What people are really complaining about is that there is a lot of software which works with UCS-2 but says that it supports UTF-16.&lt;/strong&gt; This results from UCS-2 being a thing for a noticeable time period and a considerable amount of software embracing it during that time. This is where all the confusion really comes from. Of course, when a transition needs to happen later, it never goes smoothly because legacy software and backward compatibility is always a thing. As a result we have to put up with the consequences, and there are serious problems with that indeed. But that’s not UTF-16’s fault, and &lt;strong&gt;this couldn’t have happened any other way&lt;/strong&gt;. If not for UTF-16, we would be stuck with UCS-2 with no hope to support non-BMP characters at all since rewriting existing software completely is rarely an option.&lt;/p&gt;

&lt;p&gt;It surely would be advantageous to use one encoding everywhere. If one day every piece of software started supporting one encoding and nothing else, it would be awesome, be it UTF-8 or UTF-16. However, the chances of this happening in the foreseeable future are &lt;em&gt;nil&lt;/em&gt;. Let’s take a look at the &lt;a href=&quot;http://redmonk.com/sogrady/2015/07/01/language-rankings-6-15/&quot;&gt;programming language rankings by RedMonk&lt;/a&gt; which I like so much. What is the string object representation in the top ten languages?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JavaScript - UTF-16;&lt;/li&gt;
  &lt;li&gt;Java - UTF-16;&lt;/li&gt;
  &lt;li&gt;PHP - no specific encoding;&lt;/li&gt;
  &lt;li&gt;Python - UTF-8;&lt;/li&gt;
  &lt;li&gt;C# - UTF-16;&lt;/li&gt;
  &lt;li&gt;C++ - no specific encoding;&lt;/li&gt;
  &lt;li&gt;Ruby - UTF-8;&lt;/li&gt;
  &lt;li&gt;CSS - N/A;&lt;/li&gt;
  &lt;li&gt;C - no specific encoding;&lt;/li&gt;
  &lt;li&gt;Objective-C - UTF-16.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Four out of nine languages (CSS doesn’t count as a programming language) use UTF-16 and only two use UTF-8. One can argue that something like C++ could give the developer a choice of encoding, but that’s not entirely the case, because you will have to take the platform and existing libraries into account, which is why there’s &lt;a href=&quot;http://utf8everywhere.org/#windows&quot;&gt;a long section about Windows&lt;/a&gt; on utf8everywhere.org.&lt;/p&gt;

&lt;p&gt;But even that’s not all, the languages which use UTF-16 represent underlying platforms: Java represents the JVM, browser scripts will have to compile to JavaScript (and not only browser scripts if you remember node.js), and C# represents the .NET platform. We could say Objective-C is tied to a platform too, even though it is limited to Apple software. What this means is that anything that uses these platforms will have to deal with UTF-16.&lt;/p&gt;

&lt;p&gt;I’m sorry to break it to the zealous UTF-8 supporters, but &lt;strong&gt;UTF-16 isn’t going anywhere anytime soon&lt;/strong&gt;. Understand why it’s here, understand how it works, understand that there are legacy functions and methods which deal with UTF-16 code units and not code points, and embrace this encoding. And please fix the legacy software if you are maintaining it.&lt;/p&gt;</content><author><name>Alexander Gazarov</name></author><summary type="html">Another question about Unicode popped up not so long ago into the “attention magnet” list of questions on the StackExchange network. What’s interesting, even though the question itself is about the total characters possible using UTF-8, the discussion quickly jumped to the limitations of UTF-16 and how this standard needs to be phased out. It probably all began from the StackOverflow question, Should UTF-16 be Considered Harmful, which has since been migrated to Programmers.SE. The author of the top voted post didn’t settle with his answer though, and now there’s a whole website promoting UTF-8: utf8everywhere.org. And I’ve been really curious about the effort he put into that.</summary></entry><entry><title type="html">Automatic Android resource generation with Photoshop scripts</title><link href="https://malcolmsoft.com/posts/android-resource-generation-with-photoshop-scripts" rel="alternate" type="text/html" title="Automatic Android resource generation with Photoshop scripts" /><published>2014-01-28T23:55:33+04:00</published><updated>2014-01-28T23:55:33+04:00</updated><id>https://malcolmsoft.com/posts/android-resource-generation-with-photoshop-scripts</id><content type="html" xml:base="https://malcolmsoft.com/posts/android-resource-generation-with-photoshop-scripts">&lt;p&gt;A little foreword would be proper, I guess. As it is known, when developing for Android, you have to keep in mind that you should create resources for all the pixel densities. Originally there were only three of them: &lt;em&gt;ldpi&lt;/em&gt;, &lt;em&gt;mdpi&lt;/em&gt;, and &lt;em&gt;hdpi&lt;/em&gt;. However, the progress waits for no one: pixel densities have been growing to crazy numbers, and Google has been slyly adding the letter “x” and got to &lt;em&gt;xxxhdpi&lt;/em&gt; by now, which means that now there are six major screen configurations. But even that’s not all, because some resources have several different states. Buttons on the action panel have two states, and that would be decent enough, but common buttons have much more of them.&lt;/p&gt;

&lt;p&gt;There are several ways out of this situation: nag your artist, let multiple density support slide and hope that the system is going to somehow handle resource scaling on its own, or you could also do what programmers like to do the most: automation. There are various tools which can help with this. The most advanced one is probably &lt;a href=&quot;http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html&quot;&gt;Android Asset Studio&lt;/a&gt;. But the icons are, of course, drawn only for the common cases, and if you need to draw something custom, with unique styles, it is a poor helper. And that’s where we have something to rescue us: scripting support in a fairly well-known instrument, Adobe Photoshop. In order to simplify the whole process, your humble servant has written several scripts for myself just for the cases like this, and now I’m sharing them with the readers. This article is where I’m going to describe how they work and how they are used. All the sources can be grabbed on &lt;a href=&quot;https://bitbucket.org/DrMetallius/photoshop-scripts-for-android-resources&quot;&gt;BitBucket&lt;/a&gt;, and here I will show major points of interest and also I will shed some light on various tricks of working with Photoshop scripts which could be not obvious for beginners.&lt;/p&gt;

&lt;!--cut--&gt;

&lt;h2 id=&quot;using-the-scripts-and-how-they-work&quot;&gt;Using the scripts and how they work&lt;/h2&gt;

&lt;p&gt;For those who are completely unfamiliar with the scripting for Adobe Photoshop, I will briefly describe what it involves. The standard tool for this is ExtendScript Toolkit which comes bundled with Photoshop. Some guys on the Internet mentioned that the tool is rather silly, and I have to sorely agree with them that it is completely true, but that’s what we have. It also has documentation on the function built into Photoshop, on the F1 key, which is as unwieldy as the editor itself, but at least it does its main function. The scripts themselves can be written in many languages, and personally I used JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/posts/android-resource-generation-with-photoshop-scripts/Adobe-ExtendScript-Toolkit.png&quot; width=&quot;800&quot; height=&quot;433&quot; alt=&quot;Adobe ExtendScript Toolkit&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;creating-icons-for-all-densities&quot;&gt;Creating icons for all densities&lt;/h3&gt;

&lt;p&gt;Returning to the matter at hand, all the scripts for working with resources can be divided into two categories: some of them directly launch the necessary actions (all of them start with “Make”), and the others serve as libraries with functions. The most important and and ubiquitous instrument is &lt;strong&gt;&lt;em&gt;MakeForAllDensities&lt;/em&gt;&lt;/strong&gt; which does exactly what says its name: it creates resources for all densities. The document which we use as the source has some requirements:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It should be created for the &lt;em&gt;mdpi&lt;/em&gt; densitiy. It is condidered the baseline, and then it is scaled to the required size.&lt;/li&gt;
  &lt;li&gt;The document should already be saved somewhere so that the script reads the filename correctly (and also determines whether this is a &lt;a href=&quot;http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch&quot;&gt;nine-patch&lt;/a&gt; or not by the postfix “.9”). It is best to save in a subfolder of the main Android project folder, this way the script will find the resources folder by itself.&lt;/li&gt;
  &lt;li&gt;An additional requirement: if this is a nine-patch, the lines should be drawn on a separate layer, the lowermost one.&lt;/li&gt;
  &lt;li&gt;And the image should certainly be vector and not raster, because otherwise there’s little point in scaling it with Photoshop instead of relying on Android. Just in case I should point out that nine-patch lines are an exception, and they can be raster.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all the requirements are met, the rest is easy: open the document in Photoshop and launch the script by double clicking. After it launches, it will ask to show where the folder with resources is (“res”). If the document is saved in a subfolder of the main project folder, it will find out where to save, and will finish up the rest by itself.&lt;/p&gt;

&lt;p&gt;The script itself looks very simple:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//@include ResizingAndSaving.jsx&lt;/span&gt;

&lt;span class=&quot;err&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;photoshop&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;detectFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;saveForAllDensities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Typical JavaScript, except for the first two weird lines. The first weird line looks like a common comment which is actually not a comment at all, but an import of a different file with the functions we need. This is the &lt;strong&gt;trick number one&lt;/strong&gt;, because in the standard JavaScript you can’t get by with things like this. The second weird line, as you can guess, hints that this is a script for Photoshop. As for what the rest of the lines do, we’re going to find that out by looking at the &lt;strong&gt;&lt;em&gt;ResizingAndSaving&lt;/em&gt;&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;I’m not going to give &lt;code class=&quot;highlighter-rouge&quot;&gt;detectFolder&lt;/code&gt; here as it has nothing too special in it: the function check if there is a “res” folder in the parent folder of the document’s folder, and returns it if it is found. If not, then the user will be asked. But then something more interesting begins:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;saveForAllDensities&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;computeNinePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&quot;-v&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable-mdpi&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable-hdpi&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable-xhdpi&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable-xxhdpi&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable-xxxhdpi&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;versionStr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I will answer the question in advance if someone has it: there’s no &lt;em&gt;ldpi&lt;/em&gt; density here because Google &lt;a href=&quot;http://developer.android.com/design/style/iconography.html&quot;&gt;doesn’t recommend creating resources for it explicitly&lt;/a&gt;. As it has been mentioned, the file could happen to be a nine-patch, and in terms of editing the file that means that it has a separate layer with the black lines on the sides. And we can’t just take these lines and scale them: we have to paint the pixels fully black or not paint them at all, and also we can’t touch the adjacent pixels. Besides, we have to take into account that the lines could not be continuous. That’s where the &lt;code class=&quot;highlighter-rouge&quot;&gt;computeNinePatchLines&lt;/code&gt; function comes in.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;computeNinePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;docName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getDocName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isNinePatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;docName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaCheckingFunctions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaIsEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);},&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaIsEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);},&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaIsEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);},&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaIsEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;maxPositions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaCheckingFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;findLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;maxPositions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaCheckingFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]));&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It is somewhat interesting to look into the function called areaIsEmpty():&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaIsEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;colorSamplers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;colorSampler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;colorSamplers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;colorSampler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;colorSamplers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;colorSampler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;move&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;areaEmpty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;colorSampler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rgb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hexValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;000000&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;areaEmpty&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;restoreState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;areaEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This function’s purpose is to check if the pixel is filled with black or not. But the thing is, Photoshop, as it turns out, is unable to tell us if the pixel is empty or not. Because of that we have to put a color sampler on it and check if an exception is going to be thrown. If yes, then the pixel indeed is empty. If not, then we can take a look at its color. That’s the &lt;strong&gt;trick number two&lt;/strong&gt;. The &lt;code class=&quot;highlighter-rouge&quot;&gt;findLines&lt;/code&gt; function, which is not shown here, simply applies &lt;code class=&quot;highlighter-rouge&quot;&gt;areaIsEmpty&lt;/code&gt; for all the pixels along each of the four edges of the screen and records their positions.&lt;/p&gt;

&lt;p&gt;After this we can scale the resources and save them into a folder.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;saveInFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;subFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ExportOptionsSaveForWeb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;format&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SaveDocumentType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PNG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PNG8&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;transparency&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
    &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;quality&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;activeDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;	
        &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resizeCanvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resizeCanvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;drawLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scaling&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ninePatchLines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scaling&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;activeDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exportDocument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;subFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.png&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ExportType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SAVEFORWEB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;restoreState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Everything is overall pretty clear here, but the way the picture is resized deserves a separate explanation. You’d think that there is a function &lt;code class=&quot;highlighter-rouge&quot;&gt;Document.resize&lt;/code&gt;, and you could simply call it, right? But nothing will come out of this: the layer styles are not scaled this way. We could record an action and then play it programmatically. This works, but this solution has a problem that we will have to also keep a library of actions in addition to the script itself which must be imported into Photoshop before launching the script, which is kind of inconvenient.&lt;/p&gt;

&lt;p&gt;Another solution is to use an interesting tool called &lt;strong&gt;&lt;em&gt;ScriptListener.8li&lt;/em&gt;&lt;/strong&gt;. It allows us to record all the actions done in Photoshop as a script regardless of whether these actions are in the standard API. The scripts that come out are rather inarticulate, but do their job perfectly. With a certain effort it is possible to find out specific functions of specific parameters and to create a working function out of the recorded actions. That’s how this incomprehensible, but working function came to be:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;relative&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idImgS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ImgS&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idWdth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Wdth&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPxl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;relative&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#Prc&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#Pxl&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putUnitDouble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idWdth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPxl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idscaleStyles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stringIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;scaleStyles&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idscaleStyles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idCnsP&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CnsP&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putBoolean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idCnsP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idIntr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Intr&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idIntp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Intp&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idbicubicSharper&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;stringIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;bicubicAutomatic&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putEnumerated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idIntr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idIntp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idbicubicSharper&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;executeAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idImgS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DialogModes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NO&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;That sums up the &lt;strong&gt;trick number three&lt;/strong&gt;. After we have the necessary size of the image, we can draw the nine-patch lines (if we need to), and the freshly made resource goes in the corresponding folder.&lt;/p&gt;

&lt;h3 id=&quot;creating-icons-for-the-action-bar&quot;&gt;Creating icons for the action bar&lt;/h3&gt;

&lt;p&gt;Besides MakeForAllDensities there are four scripts &lt;strong&gt;&lt;em&gt;MakeActionBarIcons&lt;/em&gt;&lt;/strong&gt;, which make the icons for the action bar: for the black and white theme, with and without the disabled state. They are used in the same manner as MakeForAllDensities with the exception that the document is now supposed to contain just one layer. The most important part for this layer is to maintain the shape of the icon, and the styles will be applied automatically.&lt;/p&gt;

&lt;p&gt;Now the difficulty is that Google has certain requirements for the button style depending on their state. If the button has just one state, then everything is simple and easy, but if it can be disabled, he have to devise a way to modify the layer appearance programmatically. In the case of action bar icons we have to know how we can change the layer opacity and color. There are no problems with the former, but with the latter the standard API shows its weak points again. That means we have to turn to our trusty ScriptListener.8li again. As a result of its use we got the function &lt;code class=&quot;highlighter-rouge&quot;&gt;setLayerColor&lt;/code&gt; in the Styles file which is going to help us with changing the color of the vector layer. I think the abracadabra in the function body is best to be omitted.&lt;/p&gt;

&lt;p&gt;Considering the action bar icons, nothing besides already mentioned is required to create them per se. But those who already looked into the &lt;strong&gt;&lt;em&gt;Styles&lt;/em&gt;&lt;/strong&gt; file, have already found out that there are lots of functions which came to be with the help of ScriptListener.8li, and which purpose is to manipulate layer effects. They were written for my own icons, for which I didn’t add the scripts into the repository. Therefore someone may find them to be not enough and will have to create more. Again, it is possible to record actions or to make some styles and apply them programmatically. But this is not really convenient, so it’s best to stick to the function again, especially now that we mastered ScriptListener.8li. And that’s when we’re going to have another quirk to deal with: if we create a script to add a certain effect to a layer and make a function out of it, we’ll find out that when we apply it, previous effects are gone. This is where the &lt;strong&gt;trick number four&lt;/strong&gt; comes useful. If we look closer at the beginning of the gibberish produced by ScriptListener.8li when we apply a layer effect, we’ll keep seeing the following lines:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idsetd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;setd&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idnull&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;null&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPrpr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Prpr&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLefx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Lefx&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPrpr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLefx&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLyr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Lyr &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idOrdn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Ordn&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idTrgt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Trgt&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putEnumerated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLyr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idOrdn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idTrgt&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;desc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putReference&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idnull&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;T   &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idScl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Scl &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPrc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#Prc&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;desc2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putUnitDouble&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idScl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idPrc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;100.000000&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;And the script is ended with the following chord:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLefx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;charIDToTypeID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Lefx&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;desc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;putObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idLefx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc2&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;executeAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;idsetd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;desc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DialogModes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NO&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The lines responsible for the creation of the style itself are the last four lines from the first portion of the code above, the ones which create &lt;code class=&quot;highlighter-rouge&quot;&gt;desc2&lt;/code&gt; and set the scale for the style. The rest is exactly what applies the style. Now that we know which lines do this, we can separate veins from meat and cut the boilerplate code from the code which applies the effect itself. The repeated lines have been placed into special functions in &lt;strong&gt;&lt;em&gt;Styles&lt;/em&gt;&lt;/strong&gt; which are used in the following way:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Create new style&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;addColorOverlay&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xFF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Apply the effect&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;addStroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//Apply one more effect&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;applyStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//And, finally, apply the whole style&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now we’ve got the instruments in our hands, it’s about time to use them. I have to remind that all these miraculous things were contrived to apply different styles to the resource depending on its state. The &lt;code class=&quot;highlighter-rouge&quot;&gt;makeIcons&lt;/code&gt; function in &lt;strong&gt;&lt;em&gt;MenuIcons&lt;/em&gt;&lt;/strong&gt; does exactly this: it applies different styles to the icon for the action bar and saves the results. I give the most important part here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;makeStateful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;selectorData&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;state_enabled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;disabled&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;na&quot;&gt;postfix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;normal&quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;makeSelectorXml&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;selectorData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;drawable&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleFunctions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;applyActionBarItemStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;whiteTheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)}];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfixes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;normal&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;makeStateful&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;styleFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unshift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;applyActionBarItemStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;whiteTheme&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)});&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;postfixes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;unshift&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;disabled&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;saveStyledDrawables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;outputFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;styleFunctions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;postfixes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The first part of the function create a selector for our resource. You can read more about selectors in the &lt;a href=&quot;http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList&quot;&gt;Android documentation&lt;/a&gt;. In our case we have two states for the action bar: when the button is disabled and when it is in the normal condition. Correspondingly, an array describing the states is passed into the function &lt;code class=&quot;highlighter-rouge&quot;&gt;makeSelectorXml&lt;/code&gt;. The objects have a field called postfix and, if required, one or more fields beginning with “state_”. After that, &lt;code class=&quot;highlighter-rouge&quot;&gt;makeSelectorXml&lt;/code&gt; makes an XML-file of the selector out of this monster which goes into the drawables folder.&lt;/p&gt;

&lt;p&gt;The second part of the function creates two arrays: one of them creates function which apply the styles for the states, and the second one contains postfixes corresponding to the states. Each style applying function has the style argument at its disposal. It is exactly that object which comes out of the &lt;code class=&quot;highlighter-rouge&quot;&gt;newStyle&lt;/code&gt;, which we were struggling with no so long ago. There’s no need to call &lt;code class=&quot;highlighter-rouge&quot;&gt;applyStyle&lt;/code&gt;, the &lt;code class=&quot;highlighter-rouge&quot;&gt;saveStyledDrawavles&lt;/code&gt; will take care of everything. The functions &lt;code class=&quot;highlighter-rouge&quot;&gt;makeSelectorXml&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;saveStyledDrawables&lt;/code&gt; shouldn’t be put here, I think, because there’s nothing in them except for plain and boring JavaScript.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;So this is how it is possible to not draw a bunch of icons, and use a ready solution instead to cook up everything from a single image. You could use Android Asset Studio, of course, but the scripting way has its advantages. First of all, you can create scripts for your own icons which are simply absent in a third party tool (which is exactly why I started writing all this stuff). Secondly, having to upload a file to the website, dancing around the settings, and then downloading the images and shoving them into the necessary folders is not exactly as easy as just double clicking a script so it does all properly by itself. Besides that, Android Asset Studio doesn’t wish to work with PSDs directly (at least at the moment of writing this article), doesn’t see the difference between a common button and a nine patch, and batch file processing is a can’t do.&lt;/p&gt;

&lt;p&gt;I hope the article will be useful for those who develop applications for Android, and also for the ones who want to learn how to write scripts for Adobe Photoshop.&lt;/p&gt;

&lt;h2 id=&quot;some-useful-links&quot;&gt;Some useful links&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;https://bitbucket.org/DrMetallius/photoshop-scripts-for-android-resources&quot;&gt;Project page on BitBucket&lt;/a&gt; - that’s what this whole article is about.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.android.com/design/style/iconography.html&quot;&gt;Iconography of Android&lt;/a&gt; - everyone has read this, I think, but if not, this should be fixed as soon as possible.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch&quot;&gt;Nine patches in Android&lt;/a&gt; - some information about what a nine-patch is.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList&quot;&gt;Selectors for drawables with state&lt;/a&gt; - official documentation on the stateful drawables.&lt;/li&gt;
&lt;/ol&gt;</content><author><name>Alexander Gazarov</name></author><summary type="html">A little foreword would be proper, I guess. As it is known, when developing for Android, you have to keep in mind that you should create resources for all the pixel densities. Originally there were only three of them: ldpi, mdpi, and hdpi. However, the progress waits for no one: pixel densities have been growing to crazy numbers, and Google has been slyly adding the letter “x” and got to xxxhdpi by now, which means that now there are six major screen configurations. But even that’s not all, because some resources have several different states. Buttons on the action panel have two states, and that would be decent enough, but common buttons have much more of them. There are several ways out of this situation: nag your artist, let multiple density support slide and hope that the system is going to somehow handle resource scaling on its own, or you could also do what programmers like to do the most: automation. There are various tools which can help with this. The most advanced one is probably Android Asset Studio. But the icons are, of course, drawn only for the common cases, and if you need to draw something custom, with unique styles, it is a poor helper. And that’s where we have something to rescue us: scripting support in a fairly well-known instrument, Adobe Photoshop. In order to simplify the whole process, your humble servant has written several scripts for myself just for the cases like this, and now I’m sharing them with the readers. This article is where I’m going to describe how they work and how they are used. All the sources can be grabbed on BitBucket, and here I will show major points of interest and also I will shed some light on various tricks of working with Photoshop scripts which could be not obvious for beginners.</summary></entry><entry><title type="html">About the blog, the site, and myself</title><link href="https://malcolmsoft.com/posts/about-site-and-myself" rel="alternate" type="text/html" title="About the blog, the site, and myself" /><published>2014-01-23T21:43:04+04:00</published><updated>2014-01-23T21:43:04+04:00</updated><id>https://malcolmsoft.com/posts/about-site-and-myself</id><content type="html" xml:base="https://malcolmsoft.com/posts/about-site-and-myself">&lt;p&gt;&lt;img width=&quot;120&quot; height=&quot;120&quot; src=&quot;/img/malcolm-soft.png&quot; style=&quot;float: right; margin-left: 10px;&quot; alt=&quot;Site logo&quot; /&gt; So, here’s my website! Here you will find information about &lt;strong&gt;myself&lt;/strong&gt;, &lt;strong&gt;my projects&lt;/strong&gt;, and also a good share of my thoughts and different &lt;strong&gt;stuff I want to share&lt;/strong&gt; (if you read the posts, that is). Most of my time is spent programming for mobile devices. Today this means that I write mostly for Android. It is certainly possible that it will change in some future because you never know what new developments in IT can surprise you with, but for now Android is my primary area of interest.&lt;/p&gt;

&lt;!--cut--&gt;

&lt;p&gt;That certainly doesn’t mean I don’t do anything else. There is a lot of interesting stuff around. We always love to try out this and that, right? So that’s what I do: experiment with different stuff, such as programming languages, frameworks, tools and so on. And some of these experiments find their way here (if they are worthy enough, of course, and I’m in the right mood to write).&lt;/p&gt;

&lt;h2 id=&quot;and-this-is-also-my-blog&quot;&gt;And this is also my blog&lt;/h2&gt;

&lt;p&gt;… which means that I write about the stuff. Something I experiment with, as I mentioned, or something interesting I find - my personal take on the things. I have to admit that I criticize things a lot. As a wise man once wrote, &lt;a href=&quot;http://www.codinghorror.com/blog/2004/10/we-make-shitty-software-with-bugs.html&quot;&gt;everything we create sucks&lt;/a&gt;. At least, to some extent. That includes our software, tools we use, and programming languages (and they are tools too). But &lt;strong&gt;that doesn’t matter&lt;/strong&gt; as long as we know the weak spots and work on them. Don’t take it personally if I mentioned your tool unfavorably too!&lt;/p&gt;

&lt;h2 id=&quot;my-nicknames&quot;&gt;My nicknames&lt;/h2&gt;

&lt;p&gt;&lt;img width=&quot;80&quot; height=&quot;80&quot; alt=&quot;My avatar&quot; src=&quot;/img/malcolm.png&quot; style=&quot;float: left; margin-right: 10px;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you read the &lt;a href=&quot;/about-me&quot;&gt;page about me&lt;/a&gt;, you should’ve noticed that I mentioned two of my nicknames: &lt;strong&gt;Malcolm&lt;/strong&gt; and &lt;strong&gt;Dr. Metallius&lt;/strong&gt;. The first one is a nickname which also gave the name for this website. The name is that uncommon, and quite far from my real name. Only those who played Unreal Tournament in the days of its glory will know it’s &lt;a href=&quot;http://liandri.beyondunreal.com/Malcolm&quot;&gt;that Malcolm&lt;/a&gt;. By the way, I really hope the days of UT come back to us, but I digress.&lt;/p&gt;

&lt;p&gt;Unfortunately, it’s also usually taken on the websites (did I mention that this name is not uncommon?). So when it is, &lt;strong&gt;Dr. Metallius&lt;/strong&gt; is at your disposal. I happen to like thrash metal music, and I also play an electric guitar, so now you know where this nick comes from. The name also starts with an “M”, so I don’t even have to change my avatar! You can see it on the left.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-contact-me&quot;&gt;How do you contact me?&lt;/h2&gt;

&lt;p&gt;Plenty of contact links are available at the &lt;a href=&quot;/about-me&quot;&gt;page about me&lt;/a&gt;. The most obvious one is the email, I’ll put it here too: &lt;strong&gt;alexander [dot] gazarov [at] gmail [dot] com&lt;/strong&gt;.&lt;/p&gt;</content><author><name>Alexander Gazarov</name></author><summary type="html">So, here’s my website! Here you will find information about myself, my projects, and also a good share of my thoughts and different stuff I want to share (if you read the posts, that is). Most of my time is spent programming for mobile devices. Today this means that I write mostly for Android. It is certainly possible that it will change in some future because you never know what new developments in IT can surprise you with, but for now Android is my primary area of interest.</summary></entry></feed>