I've been working on adding support for HiDPI screens. Part of it has landed in wayland already, some is work-in-progress in Gtk+. Generally how this work is that on very high resolution monitors we "scale" the UI so that code works in the old "low dpi" pixels, but we then render it with a scaling factor.
For icons we can't just scale as that would not look very nice, so instead we need to supply alternative higher resolution data. Things kind of work already, like you can pick 96x96 icons when rendering 48x48 icons at scale 2. However, in many cases the larger icons have a lot more detail that don't really look very well when rendering at the higher scale. For instance some sort icons have text in them which is very hard to read, or borders become really thin. So, attached to the mail is a patch to the icon theme spec that adds a "Scale" property to the icon directories. With this one could have icons for size "48" in both scale 1 and 2.
>From c321e1d3eb3c1f7b0ecc3b10af7976902a73b901 Mon Sep 17 00:00:00 2001 From: Alexander Larsson <[email protected]> Date: Tue, 2 Jul 2013 15:20:48 +0200 Subject: [PATCH] icon-theme-spec: Add icon scale support This adds support for "pre-scaled" icons aimed at higher resolution displays. For instance, an icon at scale 2 and size 48 (48@2x) would have the same kind of detail as a 48@1x icon, but a pixel size of 96x96. A a 96@1x icon would also be 96x96 but would have more details that would be hard to see on a high resolution screen. --- spec/icon-theme-spec.xml | 122 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 35 deletions(-) diff --git a/spec/icon-theme-spec.xml b/spec/icon-theme-spec.xml index 622352d..78ffc74 100644 --- a/spec/icon-theme-spec.xml +++ b/spec/icon-theme-spec.xml @@ -5,8 +5,8 @@ <article id="index"> <articleinfo> <title>Icon Theme Specification</title> - <releaseinfo>Version 0.11</releaseinfo> - <date>February 7 2006</date> + <releaseinfo>Version 0.13</releaseinfo> + <date>July 2 2013</date> <authorgroup> <author> <firstname>Alexander</firstname> @@ -82,6 +82,21 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term>Icon scale</term> + <listitem> + <para> + Icons can have a target scale, describing what scale factor + they are designed for. For instance, an icon with a + directory size of 48 but scale 2 would be 96x96 pixels, but + designed to have the same level of detail as a 48x48 icon at + scale 1. This is useful on very high resolution displays + where a 48x48 icon would be too small (or ugly upscaled) and + a normal 96x96 icon would have a lot of detail that would + not be visible on the high resolution monitor. + </para> + </listitem> + </varlistentry> </variablelist> </sect1> @@ -126,7 +141,7 @@ <para> In the theme directory are also a set of subdirectories containing image files. Each directory contains icons designed for a certain - nominal icon size, as described by the index.theme file. The + nominal icon size and scale, as described by the index.theme file. The subdirectories are allowed to be several levels deep, e.g. the subdirectory "48x48/apps" in the theme "hicolor" would end up at $basedir/hicolor/48x48/apps. @@ -256,12 +271,21 @@ <row> <entry>Size</entry> <entry> - Nominal size of the icons in this directory. + Nominal (unscaled) size of the icons in this directory. </entry> <entry>integer</entry> <entry>YES</entry> </row> <row> + <entry>Scale</entry> + <entry> + Target scale of of the icons in this + directory. Defaults to the value 1 if not present. + </entry> + <entry>integer</entry> + <entry>NO</entry> + </row> + <row> <entry>Context</entry> <entry> The context the icon is normally used in. This @@ -285,7 +309,7 @@ <row> <entry>MaxSize</entry> <entry> - Specifies the maximum size that the icons in this + Specifies the maximum (unscaled) size that the icons in this directory can be scaled to. Defaults to the value of Size if not present. </entry> @@ -296,7 +320,7 @@ <row> <entry>MinSize</entry> <entry> - Specifies the minimum size that the icons in this + Specifies the minimum (unscaled) size that the icons in this directory can be scaled to. Defaults to the value of Size if not present. </entry> @@ -308,7 +332,7 @@ <entry>Threshold</entry> <entry> The icons in this directory can be used if the size differ - at most this much from the desired size. Defaults to 2 if not + at most this much from the desired (unscaled) size. Defaults to 2 if not present. </entry> <entry>integer</entry> @@ -447,7 +471,7 @@ The icon lookup mechanism has two global settings, the list of base directories and the internal name of the current theme. Given these we need to specify how to look up an icon file from the icon - name and the nominal size. + name, the nominal size and the scale. </para> <para> The lookup is done first in the current theme, and then @@ -473,19 +497,19 @@ The exact algorithm (in pseudocode) for looking up an icon in a theme (if the implementation supports SVG) is: <programlisting> -FindIcon(icon, size) { - filename = FindIconHelper(icon, size, user selected theme); +FindIcon(icon, size, scale) { + filename = FindIconHelper(icon, size, scale, user selected theme); if filename != none return filename - filename = FindIconHelper(icon, size, "hicolor"); + filename = FindIconHelper(icon, size, scale, "hicolor"); if filename != none return filename return LookupFallbackIcon (icon) } -FindIconHelper(icon, size, theme) { - filename = LookupIcon (icon, size, theme) +FindIconHelper(icon, size, scale, theme) { + filename = LookupIcon (icon, size, scale, theme) if filename != none return filename @@ -493,7 +517,7 @@ FindIconHelper(icon, size, theme) { parents = theme.parents for parent in parents { - filename = FindIconHelper (icon, size, parent) + filename = FindIconHelper (icon, size, scale, parent) if filename != none return filename } @@ -502,11 +526,11 @@ FindIconHelper(icon, size, theme) { </programlisting> With the following helper functions: <programlisting> -LookupIcon (iconname, size, theme) { +LookupIcon (iconname, size, scale, theme) { for each subdir in $(theme subdir list) { for each directory in $(basename list) { for extension in ("png", "svg", "xpm") { - if DirectoryMatchesSize(subdir, size) { + if DirectoryMatchesSize(subdir, size, scale) { filename = directory/$(themename)/subdir/iconname.extension if exist filename return filename @@ -519,9 +543,9 @@ LookupIcon (iconname, size, theme) { for each directory in $(basename list) { for extension in ("png", "svg", "xpm") { filename = directory/$(themename)/subdir/iconname.extension - if exist filename and DirectorySizeDistance(subdir, size) < minimal_size { + if exist filename and DirectorySizeDistance(subdir, size, scale) < minimal_size { closest_filename = filename - minimal_size = DirectorySizeDistance(subdir, size) + minimal_size = DirectorySizeDistance(subdir, size, scale) } } } @@ -541,8 +565,10 @@ LookupFallbackIcon (iconname) { return none } -DirectoryMatchesSize(subdir, iconsize) { +DirectoryMatchesSize(subdir, iconsize, iconscale) { read Type and size data from subdir + if Scale != iconscale + return False; if Type is Fixed return Size == iconsize if Type is Scaled @@ -551,21 +577,21 @@ DirectoryMatchesSize(subdir, iconsize) { return Size - Threshold <= iconsize <= Size + Threshold } -DirectorySizeDistance(subdir, size) { +DirectorySizeDistance(subdir, iconsize, iconscale) { read Type and size data from subdir if Type is Fixed - return abs(Size - iconsize) + return abs(Size*Scale - iconsize*iconscale) if Type is Scaled - if iconsize < MinSize - return MinSize - iconsize - if iconsize > MaxSize - return iconsize - MaxSize + if iconsize*iconscale < MinSize*Scale + return MinSize*Scale - iconsize*iconscale + if iconsize*iconscale > MaxSize*Scale + return iconsize*iconscale - MaxSize*Scale return 0 if Type is Threshold - if iconsize < Size - Threshold - return MinSize - iconsize - if iconsize > Size + Threshold - return iconsize - MaxSize + if iconsize*iconscale < (Size - Threshold)*Scale + return MinSize*Scale - iconsize*iconscale + if iconsize*iconsize > (Size + Threshold)*Scale + return iconsize*iconsize - MaxSize*Scale return 0 } </programlisting> @@ -578,12 +604,12 @@ DirectorySizeDistance(subdir, size) { function that finds the first of a list of icon names in the inheritance hierarchy. I.E. It would look something like this: <programlisting> -FindBestIcon(iconList, size) { - filename = FindBestIconHelper(iconList, size, user selected theme); +FindBestIcon(iconList, size, scale) { + filename = FindBestIconHelper(iconList, size, scale, user selected theme); if filename != none return filename - filename = FindBestIconHelper(iconList, size, "hicolor"); + filename = FindBestIconHelper(iconList, size, scale, "hicolor"); if filename != none return filename @@ -594,7 +620,7 @@ FindBestIcon(iconList, size) { } return none; } -FindBestIconHelper(iconList, size, theme) { +FindBestIconHelper(iconList, size, scale, theme) { for icon in iconList { filename = LookupIcon (icon, size, theme) if filename != none @@ -605,7 +631,7 @@ FindBestIconHelper(iconList, size, theme) { parents = theme.parents for parent in parents { - filename = FindBestIconHelper (iconList, size, parent) + filename = FindBestIconHelper (iconList, size, scale, parent) if filename != none return filename } @@ -627,7 +653,7 @@ Name[sv]=Björk Comment=Icon theme with a wooden look Comment[sv]=Träinspirerat ikontema Inherits=wood,default -Directories=48x48/apps,48x48/mimetypes,32x32/apps,scalable/apps,scalable/mimetypes +Directories=48x48/apps,48x48@2/apps48x48/mimetypes,32x32/apps,32x32@2/apps,scalable/apps,scalable/mimetypes [scalable/apps] Size=48 @@ -648,11 +674,23 @@ Size=32 Type=Fixed Context=Applications +[32x32@2/apps] +Size=32 +Scale=2 +Type=Fixed +Context=Applications + [48x48/apps] Size=48 Type=Fixed Context=Applications +[48x48@2/apps] +Size=48 +Scale=2 +Type=Fixed +Context=Applications + [48x48/mimetypes] Size=48 Type=Fixed @@ -664,7 +702,9 @@ birch/scalable/apps/mozilla.svg birch/scalable/mimetypes/mime_text_plain.svg birch/scalable/mimetypes/mime_text_plain.icon birch/48x48/apps/mozilla.png +birch/48x48@2/apps/mozilla.png birch/32x32/apps/mozilla.png +birch/32x32@2/apps/mozilla.png birch/48x48/mimetypes/mime_text_plain.png birch/48x48/mimetypes/mime_text_plain.icon</programlisting> Where birch/scalable/mimetypes/mime_text_plain.icon contains: @@ -742,6 +782,18 @@ AttachPoints=20,20|40,40|50,10|10,50</programlisting> <appendix id="changes"> <title>Change history</title> <formalpara> + <title>Version 0.13, July 2 2013, Alexander Larsson</title> + <para> + <itemizedlist> + <listitem> + <para> + Add icon Scales. + </para> + </listitem> + </itemizedlist> + </para> + </formalpara> + <formalpara> <title>Version 0.12, 24 December 2006, Octavio Alvarez</title> <para> <itemizedlist> -- 1.8.1.4
_______________________________________________ xdg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xdg
