changed skin handling and added themes support for skins

This commit is contained in:
louis 2014-10-03 15:54:23 +02:00
parent 7766972eec
commit 91a0681ab8
593 changed files with 495 additions and 144 deletions

View File

@ -9,3 +9,6 @@ Version 0.0.2
- added some more tokens with more detailed audio information in displaychannel -> statusinfo
- added hasVPS for current scheduling in displaychannel -> epginfo
- added common channel logo path for all skins
- changed skin handling so that every skin is directly shown in VDR OSD Menu
- added Theme support, each skin can now have various themes

View File

@ -160,6 +160,8 @@ install-themes:
install-skins:
mkdir -p $(DESTDIR)$(PLGRESDIR)/skins
cp -r skins/* $(DESTDIR)$(PLGRESDIR)/skins
mkdir -p $(DESTDIR)$(PLGRESDIR)/dtd
cp -r dtd/* $(DESTDIR)$(PLGRESDIR)/dtd
install: install-lib install-i18n install-themes install-skins

3
README
View File

@ -47,6 +47,9 @@ XML skins and epg images. The following paths can be set at startup:
-s <SKINPATH>, --skinpath=<SKINPATH>
Path to the XML skins (Default: <ResourceDirectory>/plugins/skindesigner/skins/)
-l <LOGOPATH>, --logopath=<LOGOPATH>
Path to common logo set for all skins (Default: <ResourceDirectory>/plugins/skindesigner/logos/)
-e path, --epgimages=path
Path to the epgimages (Default: <CacheDirectory>/epgimages/)

View File

@ -5,6 +5,7 @@
cDesignerConfig::cDesignerConfig() {
epgImagePathSet = false;
skinPathSet = false;
logoPathSet = false;
//Common
logoExtension = "png";
numLogosPerSizeInitial = 30;
@ -23,12 +24,14 @@ cDesignerConfig::~cDesignerConfig() {
void cDesignerConfig::SetPathes(void) {
if (!skinPathSet)
skinPath = cString::sprintf("%s/skins/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
if (!logoPathSet)
logoPath = cString::sprintf("%s/logos/", cPlugin::ResourceDirectory(PLUGIN_NAME_I18N));
if (!epgImagePathSet)
epgImagePath = cString::sprintf("%s/epgimages/", cPlugin::CacheDirectory(PLUGIN_NAME_I18N));
dsyslog("skindesigner: using Skin Directory %s", *skinPath);
dsyslog("skindesigner: using common ChannelLogo Directory %s", *logoPath);
dsyslog("skindesigner: using EPG Images Directory %s", *epgImagePath);
}
void cDesignerConfig::SetSkinPath(cString path) {
@ -36,11 +39,44 @@ void cDesignerConfig::SetSkinPath(cString path) {
skinPathSet = true;
}
void cDesignerConfig::SetLogoPath(cString path) {
logoPath = CheckSlashAtEnd(*path);
logoPathSet = true;
}
void cDesignerConfig::SetEpgImagePath(cString path) {
epgImagePath = CheckSlashAtEnd(*path);
epgImagePathSet = true;
}
void cDesignerConfig::ReadSkins(void) {
DIR *folder = NULL;
struct dirent *dirEntry;
folder = opendir(skinPath);
if (!folder) {
esyslog("skindesigner: no skins found in %s", *skinPath);
return;
}
while (dirEntry = readdir(folder)) {
string dirEntryName = dirEntry->d_name;
int dirEntryType = dirEntry->d_type;
if (!dirEntryName.compare(".") || !dirEntryName.compare("..") || dirEntryType != DT_DIR)
continue;
skins.push_back(dirEntryName);
}
dsyslog("skindesigner %d skins found in %s", skins.size(), *skinPath);
}
bool cDesignerConfig::GetSkin(string &skin) {
if (skinIterator == skins.end()) {
return false;
}
skin = *skinIterator;
skinIterator++;
return true;
}
void cDesignerConfig::SetChannelLogoSize(void) {
cImageLoader imgLoader;
imgLoader.DeterminateChannelLogoSize(logoWidth, logoHeight);

View File

@ -15,17 +15,23 @@ private:
cString CheckSlashAtEnd(std::string path);
bool epgImagePathSet;
bool skinPathSet;
bool logoPathSet;
public:
cDesignerConfig();
~cDesignerConfig();
bool SetupParse(const char *Name, const char *Value);
void SetSkinPath(cString path);
void SetEpgImagePath(cString path);
void SetPathes(void);
void SetSkinPath(cString path);
void SetLogoPath(cString path);
void SetEpgImagePath(cString path);
void ReadSkins(void);
void InitSkinIterator(void) { skinIterator = skins.begin(); };
bool GetSkin(string &skin);
void SetChannelLogoSize(void);
void CheckDecimalPoint(void);
cString logoExtension;
cString skinPath;
cString logoPath;
cString epgImagePath;
int numLogosPerSizeInitial;
int limitLogoCache;
@ -35,12 +41,14 @@ public:
int logoHeight;
bool replaceDecPoint;
char decPoint;
vector<string> skins;
vector<string>::iterator skinIterator;
};
#ifdef DEFINE_CONFIG
bool firstDisplay = true;
cDesignerConfig config;
cFontManager *fontManager;
cImageCache *imgCache;
cFontManager *fontManager = NULL;
cImageCache *imgCache = NULL;
cTheme Theme;
#else
extern bool firstDisplay;

View File

@ -1,20 +1,13 @@
#include "designer.h"
#include "libcore/helpers.h"
cSkinDesigner::cSkinDesigner(void) : cSkin("skindesigner", &::Theme) {
cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) {
init = true;
this->skin = skin;
backupSkin = NULL;
useBackupSkin = false;
SetOSDSize();
osdSkin = Setup.OSDSkin;
osdTheme = Setup.OSDTheme;
config.SetPathes();
config.SetChannelLogoSize();
config.CheckDecimalPoint();
fontManager = new cFontManager();
imgCache = new cImageCache();
globals = NULL;
channelTemplate = NULL;
menuTemplate = NULL;
@ -22,17 +15,7 @@ cSkinDesigner::cSkinDesigner(void) : cSkin("skindesigner", &::Theme) {
replayTemplate = NULL;
volumeTemplate = NULL;
audiotracksTemplate = NULL;
cStopWatch watch;
bool ok = LoadTemplates();
if (!ok) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
backupSkin = new cSkinLCARS();
useBackupSkin = true;
} else {
CacheTemplates();
watch.Stop("templates loaded and cache created");
}
dsyslog("skindesigner: skin %s started", skin.c_str());
}
cSkinDesigner::~cSkinDesigner(void) {
@ -44,10 +27,43 @@ cSkinDesigner::~cSkinDesigner(void) {
}
const char *cSkinDesigner::Description(void) {
return "SkinDesigner";
return skin.c_str();
}
void cSkinDesigner::Init(void) {
dsyslog("skindesigner: initializing skin %s", skin.c_str());
SetOSDSize();
osdSkin = Setup.OSDSkin;
osdTheme = Setup.OSDTheme;
config.SetChannelLogoSize();
config.CheckDecimalPoint();
if (fontManager)
delete fontManager;
fontManager = new cFontManager();
if (imgCache)
delete imgCache;
imgCache = new cImageCache();
imgCache->SetPathes();
cStopWatch watch;
bool ok = LoadTemplates();
if (!ok) {
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
backupSkin = new cSkinLCARS();
useBackupSkin = true;
} else {
CacheTemplates();
watch.Stop("templates loaded and cache created");
}
init = false;
}
cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) {
if (init) {
Init();
}
cSkinDisplayChannel *displayChannel = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -59,6 +75,9 @@ cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) {
}
cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) {
if (init) {
Init();
}
cSkinDisplayMenu *displayMenu = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -71,6 +90,9 @@ cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) {
}
cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) {
if (init) {
Init();
}
cSkinDisplayReplay *displayReplay = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -82,6 +104,9 @@ cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) {
}
cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) {
if (init) {
Init();
}
cSkinDisplayVolume *displayVolume = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -93,6 +118,9 @@ cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) {
}
cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
if (init) {
Init();
}
cSkinDisplayTracks *displayTracks = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -104,6 +132,9 @@ cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTrack
}
cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) {
if (init) {
Init();
}
cSkinDisplayMessage *displayMessage = NULL;
if (!useBackupSkin) {
ReloadCaches();
@ -261,6 +292,7 @@ void cSkinDesigner::CacheTemplates(void) {
dsyslog("skindesigner: fonts cached");
dsyslog("skindesigner: caching images...");
imgCache->Clear();
imgCache->SetPathes();
channelTemplate->CacheImages();
menuTemplate->CacheImages();
messageTemplate->CacheImages();

View File

@ -14,6 +14,8 @@
class cSkinDesigner : public cSkin {
private:
bool init;
string skin;
cSkinLCARS *backupSkin;
bool useBackupSkin;
cRect osdSize;
@ -34,7 +36,7 @@ private:
bool OsdSizeChanged(void);
bool ThemeChanged(void);
public:
cSkinDesigner(void);
cSkinDesigner(string skin);
virtual ~cSkinDesigner(void);
virtual const char *Description(void);
virtual cSkinDisplayChannel *DisplayChannel(bool WithInfo);
@ -43,6 +45,8 @@ public:
virtual cSkinDisplayVolume *DisplayVolume(void);
virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks);
virtual cSkinDisplayMessage *DisplayMessage(void);
void Init(void);
void ActivateBackupSkin(void) { useBackupSkin = true; };
void Reload(void);
void ListAvailableFonts(void);
};

View File

@ -97,6 +97,11 @@ bool FileExists(const string &path, const string &name, const string &ext) {
return (stat (fileName.str().c_str(), &buffer) == 0);
}
bool FolderExists(const string &path) {
struct stat buffer;
return stat(path.c_str(), &buffer) == 0 && S_ISDIR(buffer.st_mode);
}
bool FirstFileInFolder(string &path, string &extension, string &fileName) {
DIR *folder = NULL;
struct dirent *file;

View File

@ -13,6 +13,7 @@ std::string CutText(string &text, int width, string fontName, int fontSize);
std::string StrToLowerCase(string str);
bool isNumber(const string& s);
bool FileExists(const string &path, const string &name, const string &ext);
bool FolderExists(const string &path);
bool FirstFileInFolder(string &path, string &extension, string &fileName);
class splitstring : public std::string {

View File

@ -26,6 +26,21 @@ cImageCache::~cImageCache() {
}
}
void cImageCache::SetPathes(void) {
string logoPathSkin = *cString::sprintf("%s%s/themes/%s/logos/", *config.skinPath, Setup.OSDSkin, Setup.OSDTheme);
if (FolderExists(logoPathSkin)) {
logoPath = logoPathSkin;
} else {
logoPath = *config.logoPath;
}
iconPath = *cString::sprintf("%s%s/themes/%s/", *config.skinPath, Setup.OSDSkin, Setup.OSDTheme);
skinPartsPath = *cString::sprintf("%s%s/themes/%s/skinparts/", *config.skinPath, Setup.OSDSkin, Setup.OSDTheme);
dsyslog("skindesigner: using channel logo path %s", logoPath.c_str());
dsyslog("skindesigner: using icon path %s", iconPath.c_str());
dsyslog("skindesigner: using skinparts path %s", skinPartsPath.c_str());
}
void cImageCache::CacheLogo(int width, int height) {
if (config.numLogosPerSizeInitial == 0)
return;
@ -125,14 +140,13 @@ bool cImageCache::LogoExists(string channelID) {
const cChannel *channel = Channels.GetByChannelID(chanID);
if (!channel)
return false;
string logoPath = *cString::sprintf("%s%s/logos/", *config.skinPath, Setup.OSDTheme);
string logoLower = StrToLowerCase(channel->Name());
string logoExt = *config.logoExtension;
bool logoExists = FileExists(logoPath, logoLower, logoExt);
bool logoExists = FileExists(logoPath.c_str(), logoLower, logoExt);
if (logoExists) {
return true;
}
logoExists = FileExists(logoPath, channelID, logoExt);
logoExists = FileExists(logoPath.c_str(), channelID, logoExt);
if (logoExists) {
return true;
}
@ -265,8 +279,8 @@ bool cImageCache::LoadIcon(eImageType type, string name) {
subdir = "menuicons";
else if (type == itIcon)
subdir = "icons";
cString iconPath = cString::sprintf("%s%s/graphics/%s/", *config.skinPath, Setup.OSDTheme, *subdir);
success = LoadImage(name, *iconPath, "png");
cString subIconPath = cString::sprintf("%s%s/", iconPath.c_str(), *subdir);
success = LoadImage(name, *subIconPath, "png");
if (success) {
return true;
}
@ -276,21 +290,20 @@ bool cImageCache::LoadIcon(eImageType type, string name) {
bool cImageCache::LoadLogo(const cChannel *channel) {
if (!channel)
return false;
cString logoPath = cString::sprintf("%s%s/logos/", *config.skinPath, Setup.OSDTheme);
string channelID = StrToLowerCase(*(channel->GetChannelID().ToString()));
string logoLower = StrToLowerCase(channel->Name());
bool success = false;
success = LoadImage(channelID.c_str(), *logoPath, *config.logoExtension);
success = LoadImage(channelID.c_str(), logoPath.c_str(), *config.logoExtension);
if (success)
return true;
success = LoadImage(logoLower.c_str(), *logoPath, *config.logoExtension);
success = LoadImage(logoLower.c_str(), logoPath.c_str(), *config.logoExtension);
if (success)
return true;
return false;
}
bool cImageCache::LoadSeparatorLogo(string name) {
cString separatorPath = cString::sprintf("%s%s/logos/separatorlogos/", *config.skinPath, Setup.OSDTheme);
cString separatorPath = cString::sprintf("%sseparatorlogos/", logoPath.c_str());
string nameLower = StrToLowerCase(name.c_str());
bool success = false;
success = LoadImage(nameLower.c_str(), *separatorPath, *config.logoExtension);
@ -301,8 +314,7 @@ bool cImageCache::LoadSeparatorLogo(string name) {
bool cImageCache::LoadSkinpart(string name) {
bool success = false;
cString iconPath = cString::sprintf("%s%s/graphics/skinparts/", *config.skinPath, Setup.OSDTheme);
success = LoadImage(name, *iconPath, "png");
success = LoadImage(name, skinPartsPath.c_str(), "png");
if (success) {
return true;
}

View File

@ -18,6 +18,7 @@ public:
~cImageCache();
void Lock(void) { mutex.Lock(); }
void Unlock(void) { mutex.Unlock(); }
void SetPathes(void);
//channel logos
void CacheLogo(int width, int height);
cImage *GetLogo(string channelID, int width, int height);
@ -41,6 +42,9 @@ private:
static cMutex mutex;
static string items[16];
cImage *tempStaticLogo;
string logoPath;
string iconPath;
string skinPartsPath;
map<string, cImage*> iconCache;
map<string, cImage*> channelLogoCache;
map<string, cImage*> skinPartsCache;

View File

@ -27,7 +27,13 @@ bool cImageLoader::LoadImage(const char *path, int width, int height) {
}
void cImageLoader::DeterminateChannelLogoSize(int &width, int &height) {
cString logoPath = cString::sprintf("%s%s/logos/", *config.skinPath, Setup.OSDTheme);
cString logoPath;
cString logoPathSkin = cString::sprintf("%s%s/themes/%s/logos/", *config.skinPath, Setup.OSDSkin, Setup.OSDTheme);
if (FolderExists(*logoPathSkin)) {
logoPath = logoPathSkin;
} else {
logoPath = config.logoPath;
}
cString logoExt = config.logoExtension;
DIR *folder = NULL;
struct dirent *file;

View File

@ -177,11 +177,14 @@ void cXmlParser::DeleteDocument(void) {
string cXmlParser::GetPath(string xmlFile) {
string activeSkin = Setup.OSDSkin;
string theme = "default";
if (!activeSkin.compare("skindesigner")) {
theme = Setup.OSDTheme;
string activeTheme = Setup.OSDTheme;
string path = "";
if (!xmlFile.compare("globals.xml")) {
path = *cString::sprintf("%s%s/themes/%s/%s", *config.skinPath, activeSkin.c_str(), activeTheme.c_str(), xmlFile.c_str());
} else {
path = *cString::sprintf("%s%s/xmlfiles/%s", *config.skinPath, activeSkin.c_str(), xmlFile.c_str());
}
return *cString::sprintf("%s%s/xmlfiles/%s", *config.skinPath, theme.c_str(), xmlFile.c_str());
return path;
}
void cXmlParser::ParseGlobalColors(xmlNodePtr node) {

View File

@ -7,7 +7,6 @@
*/
#include <getopt.h>
#include <vdr/plugin.h>
#include <vdr/skinlcars.h>
#define DEFINE_CONFIG 1
#include "config.h"
@ -26,7 +25,7 @@ static const char *MAINMENUENTRY = "Skin Designer";
class cPluginSkinDesigner : public cPlugin {
private:
cSkinDesigner *skinDesigner;
vector<cSkinDesigner*> skins;
public:
cPluginSkinDesigner(void);
virtual ~cPluginSkinDesigner();
@ -51,7 +50,6 @@ public:
};
cPluginSkinDesigner::cPluginSkinDesigner(void) {
skinDesigner = NULL;
}
cPluginSkinDesigner::~cPluginSkinDesigner() {
@ -60,6 +58,7 @@ cPluginSkinDesigner::~cPluginSkinDesigner() {
const char *cPluginSkinDesigner::CommandLineHelp(void) {
return
" -s <SKINPATH>, --skinpath=<SKINPATH> Set directory where xml skins are stored\n"
" -l <LOGOPATH>, --logopath=<LOGOPATH> Set directory where a common logo set for all skins is stored\n"
" -e <EPGIMAGESPATH>, --epgimages=<IMAGESPATH> Set directory where epgimages are stored\n";
}
@ -67,16 +66,20 @@ bool cPluginSkinDesigner::ProcessArgs(int argc, char *argv[]) {
// Implement command line argument processing here if applicable.
static const struct option long_options[] = {
{ "epgimages", required_argument, NULL, 'e' },
{ "logopath", required_argument, NULL, 'l' },
{ "skinpath", required_argument, NULL, 's' },
{ 0, 0, 0, 0 }
};
int c;
while ((c = getopt_long(argc, argv, "e:s:", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "e:s:l:", long_options, NULL)) != -1) {
switch (c) {
case 'e':
config.SetEpgImagePath(cString(optarg));
break;
case 'l':
config.SetLogoPath(cString(optarg));
break;
case 's':
config.SetSkinPath(cString(optarg));
break;
@ -92,13 +95,24 @@ bool cPluginSkinDesigner::Initialize(void) {
}
bool cPluginSkinDesigner::Start(void) {
bool trueColorAvailable = true;
if (!cOsdProvider::SupportsTrueColor()) {
esyslog("skindesigner: No TrueColor OSD found! Using default Skin LCARS!");
return new cSkinLCARS();
trueColorAvailable = false;
} else
dsyslog("skindesigner: TrueColor OSD found");
skinDesigner = new cSkinDesigner();
return skinDesigner;
config.SetPathes();
config.ReadSkins();
config.InitSkinIterator();
string skin = "";
while (config.GetSkin(skin)) {
cSkinDesigner *newSkin = new cSkinDesigner(skin);
skins.push_back(newSkin);
if (!trueColorAvailable) {
newSkin->ActivateBackupSkin();
}
}
return true;
}
void cPluginSkinDesigner::Stop(void) {
@ -148,16 +162,26 @@ const char **cPluginSkinDesigner::SVDRPHelpPages(void) {
}
cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) {
cSkinDesigner *activeSkin = NULL;
for (vector<cSkinDesigner*>::iterator skin = skins.begin(); skin != skins.end(); skin++) {
string activeSkinName = Setup.OSDSkin;
string currentSkinName = (*skin)->Description();
if (!currentSkinName.compare(activeSkinName)) {
activeSkin = *skin;
break;
}
}
if (!activeSkin)
return NULL;
if (strcasecmp(Command, "RELD") == 0) {
if (skinDesigner) {
skinDesigner->Reload();
return "SKINDESIGNER reload of templates and caches forced.";
}
activeSkin->Reload();
return "SKINDESIGNER reload of templates and caches forced.";
} else if (strcasecmp(Command, "LSTF") == 0) {
if (skinDesigner) {
skinDesigner->ListAvailableFonts();
return "SKINDESIGNER available fonts listed in syslog.";
}
activeSkin->ListAvailableFonts();
return "SKINDESIGNER available fonts listed in syslog.";
}
return NULL;
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE globals SYSTEM "../../dtd/globals.dtd">
<!DOCTYPE globals SYSTEM "../../../../dtd/globals.dtd">
<globals>
<!--

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 958 B

After

Width:  |  Height:  |  Size: 958 B

View File

Before

Width:  |  Height:  |  Size: 386 B

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 458 B

View File

Before

Width:  |  Height:  |  Size: 413 B

After

Width:  |  Height:  |  Size: 413 B

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

View File

Before

Width:  |  Height:  |  Size: 958 B

After

Width:  |  Height:  |  Size: 958 B

View File

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 788 B

After

Width:  |  Height:  |  Size: 788 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 531 B

View File

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 861 B

After

Width:  |  Height:  |  Size: 861 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 859 B

After

Width:  |  Height:  |  Size: 859 B

View File

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

Before

Width:  |  Height:  |  Size: 665 B

After

Width:  |  Height:  |  Size: 665 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Some files were not shown because too many files have changed in this diff Show More