class_IconTheme.inc 11.94 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2011-2016  FusionDirectory
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
class ThemeFileParsingException extends Exception
/*!
 * \brief Icon theme directory
class IconThemeDir
  /* Nominal (unscaled) size of the icons in this directory.
   * Required. */
  private $Size;
  /* Specifies the minimum (unscaled) size that the icons in this directory can be scaled to.
   * Defaults to the value of Size if not present. */
  private $MinSize;
  /* Specifies the maximum (unscaled) size that the icons in this directory can be scaled to.
   * Defaults to the value of Size if not present. */
  private $MaxSize;
  /* The type of icon sizes for the icons in this directory.
   * Valid types are Fixed, Scalable and Threshold.
   * The type decides what other keys in the section are used.
   * If not specified, the default is Threshold. */
  private $Type      = 'Threshold';
  /* The icons in this directory can be used if the size differ at most this much from the desired (unscaled) size.
   * Defaults to 2 if not present. */
  private $Threshold = 2;
  function __construct ($infos)
    $this->Size     = $infos['Size'];
    $this->MinSize  = $infos['Size'];
    $this->MaxSize  = $infos['Size'];
    foreach (['Type', 'MaxSize', 'MinSize', 'Threshold'] as $key) {
      if (isset($infos[$key])) {
        $this->$key = $infos[$key];
    /* Thanks to this Threshold and Scaled are the same */
    if ($this->Type == 'Threshold') {
      $this->MinSize = $this->Size - $this->Threshold;
      $this->MaxSize = $this->Size + $this->Threshold;
  function MatchesSize ($size)
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
switch ($this->Type) { case 'Fixed': return ($this->Size == $size); case 'Threshold': case 'Scalable': default: return (($this->MinSize <= $size) && ($size <= $this->MaxSize)); } } function SizeDistance ($size) { switch ($this->Type) { case 'Fixed': return abs($this->Size - $size); case 'Threshold': case 'Scalable': default: if ($size < $this->MinSize) { return $this->MinSize - $size; } if ($size > $this->MaxSize) { return $size - $this->MaxSize; } return 0; } } } /*! * \brief Icon theme */ class IconTheme { private $subdirs = []; private $path; private $parent; function __construct ($folder, $default_parent) { $this->path = $folder; $datas = @parse_ini_file($folder.'/index.theme', TRUE, INI_SCANNER_RAW); if ($datas === FALSE) { throw new ThemeFileParsingException('Error while parsing theme file'); } if (isset($datas['Icon Theme']['Directories']) && !empty($datas['Icon Theme']['Directories'])) { $dirs = preg_split('/,/', $datas['Icon Theme']['Directories']); foreach ($dirs as $name) { if (isset($datas[$name])) { $this->subdirs[strtolower($datas[$name]['Context'])][$name] = new IconThemeDir($datas[$name]); } } } if (isset($datas['Icon Theme']['Inherits'])) { $this->parent = $datas['Icon Theme']['Inherits']; } else { $this->parent = $default_parent; } } function FindIcon ($context, $icon, $size) { $context = strtolower($context); return $this->FindIconHelper($context, $icon, $size); } function FindIconHelper ($context, $icon, $size) { $filename = $this->LookupIcon($context, $icon, $size);
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
if ($filename != NULL) { return $filename; } if (isset(static::$fallbacks[$context.'/'.$icon])) { foreach (static::$fallbacks[$context.'/'.$icon] as $fallback) { $filename = $this->LookupIcon($fallback[0], $fallback[1], $size); if ($filename != NULL) { return $filename; } } } if ($this->parent !== NULL) { $parentTheme = $this->findTheme($this->parent); if ($parentTheme === NULL) { $parentTheme = $this->findTheme(static::$default_theme); } return $parentTheme->FindIconHelper($context, $icon, $size); } return NULL; } function LookupIcon ($context, $iconname, $size) { if (!isset($this->subdirs[$context])) { return NULL; } foreach ($this->subdirs[$context] as $path => &$subdir) { if ($subdir->MatchesSize($size)) { foreach (static::$extensions as $extension) { $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension; if (file_exists($filename)) { return $filename; } } } } unset($subdir); if (static::$find_closest) { $minimal_size = PHP_INT_MAX; foreach ($this->subdirs[$context] as $path => &$subdir) { if (($sizedistance = $subdir->SizeDistance($size)) < $minimal_size) { foreach (static::$extensions as $extension) { $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension; if (file_exists($filename)) { $closest_filename = $filename; $minimal_size = $sizedistance; } } } } unset($subdir); if (isset($closest_filename)) { return $closest_filename; } } return NULL; } static public $default_theme = 'breezy'; static public $extensions = ['png', 'xpm', 'svg']; static public $find_closest = FALSE; /* We store themes in the session. To do otherwise, override these methods. */ static public $session_var = 'IconThemes'; static public function loadThemes ($path) { $themes = [];