summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY12
-rw-r--r--Makefile4
-rw-r--r--README7
-rw-r--r--bitmap.c103
-rw-r--r--bitmap.h16
-rw-r--r--cache.c53
-rw-r--r--cache.h135
-rw-r--r--i18n.c40
-rw-r--r--render.c9
-rw-r--r--setup.c14
-rw-r--r--setup.h3
-rw-r--r--text2skin.c19
12 files changed, 199 insertions, 216 deletions
diff --git a/HISTORY b/HISTORY
index c4c1520..d554e3d 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,18 @@
VDR Plugin 'text2skin' Revision History
---------------------------------------
+2004-06-18: Version 0.0.6
+
+- reimplemented image cache (fixes segfaults and speeds up image loading)
+- fixed a recursion wenn de-initializing ImageMagick (crashes on exit)
+- reverted the changes in ImageMagick-loader that concerned palettes
+ (obviously some versions of ImageMagick are BROKEN!!! I am using 5.5.7 which
+ works fine. Version 5.4.7 shows random errors)
+- reimplemented "Flush image cache" into the setup menu
+- included -lMagick into Makefile as a workaround for Debian (and others
+ possibly)
+- fixed display of scrollbar
+
2004-06-16: Version 0.0.5
- fixed disappearing Scrolltext when Message was displayed
diff --git a/Makefile b/Makefile
index 3d35506..43845ce 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ HAVE_IMAGEMAGICK=1
# DO NOT EDIT BELOW THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING
# -------------------------------------------------------------
#
-# $Id: Makefile,v 1.11 2004/06/16 18:46:50 lordjaxom Exp $
+# $Id: Makefile,v 1.12 2004/06/18 16:08:11 lordjaxom Exp $
#
# The official name of this plugin.
@@ -56,7 +56,7 @@ endif
ifdef HAVE_IMAGEMAGICK
DEFINES += -DHAVE_IMAGEMAGICK
- LIBS += -lMagick++
+ LIBS += -lMagick -lMagick++
endif
ifdef DEBUG
diff --git a/README b/README
index 1faba7d..eff9559 100644
--- a/README
+++ b/README
@@ -65,13 +65,6 @@ root@linux # cd ../..
root@linux # make plugins
root@linux # ./vdr -P text2skin
-If you are using VDR 1.3.10, your have to apply a patch to the sources of VDR.
-This patch will hopefully be included in VDR 1.3.11.
-
-root@linux # patch -p1 < PLUGINS/src/text2skin/patches/vdr-1.3.10-scroller.diff
-root@linux # make vdr
-root@linux # ./vdr -P text2skin
-
If you are using VDR 1.3.9, you also have to apply a patch to the sources. This
patch will be included in VDR 1.3.10.
diff --git a/bitmap.c b/bitmap.c
index 3aa91a5..0137289 100644
--- a/bitmap.c
+++ b/bitmap.c
@@ -1,5 +1,5 @@
/*
- * $Id: bitmap.c,v 1.16 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: bitmap.c,v 1.17 2004/06/18 16:08:11 lordjaxom Exp $
*/
#include "bitmap.h"
@@ -14,13 +14,40 @@
using namespace Magick;
#endif
-template<>
-void cImageCache::Delete(string &key, cText2SkinBitmap *&value) {
- delete value;
-}
+cText2SkinCache cText2SkinBitmap::mCache(Text2SkinSetup.MaxCacheFill);
-cImageCache cText2SkinBitmap::mCache(Text2SkinSetup.MaxCacheFill);
-bool cText2SkinBitmap::mFirstTime = true;
+cText2SkinBitmap *cText2SkinBitmap::Load(const char *Filename, int Alpha) {
+ if (mCache.Contains(Filename))
+ return mCache[Filename];
+ else {
+ cText2SkinBitmap *bmp = new cText2SkinBitmap;
+ int len = strlen(Filename);
+ bool result = false;
+ if (len > 4) {
+ if (strcmp(Filename + len - 4, ".xpm") == 0)
+ result = bmp->LoadXpm(Filename, Alpha);
+ else {
+#ifdef HAVE_IMLIB2
+ result = bmp->LoadImlib(Filename, Alpha);
+#else
+# ifdef HAVE_IMAGEMAGICK
+ result = bmp->LoadMagick(Filename, Alpha);
+# endif
+#endif
+ }
+ //else
+ //esyslog("ERROR: text2skin: unknown file format for %s", Filename);
+ } else
+ esyslog("ERROR: text2skin: filename %s too short to identify format", Filename);
+
+ if (result) {
+ bmp->SetAlpha(Alpha);
+ return (mCache[Filename] = bmp);
+ } else
+ delete bmp;
+ }
+ return false;
+}
cText2SkinBitmap::cText2SkinBitmap(void) {
mCurrent = 0;
@@ -40,7 +67,6 @@ cBitmap &cText2SkinBitmap::Get(int &UpdateIn) {
time_t upd, cur = time_ms();
int diff;
if (mLastGet == 0) {
- Dprintf("lastget was %d\n", mLastGet);
mLastGet = cur;
upd = mDelay;
} else if ((diff = cur - mLastGet) >= mDelay) {
@@ -51,12 +77,9 @@ cBitmap &cText2SkinBitmap::Get(int &UpdateIn) {
upd = mDelay - diff;
}
- Dprintf("delay: %d, diff %d\n", mDelay, diff);
-
if (UpdateIn == 0 || UpdateIn > upd)
UpdateIn = upd;
- Dprintf("Get: returning frame %d\n", mCurrent);
return *mBitmaps[mCurrent];
}
@@ -75,39 +98,6 @@ void cText2SkinBitmap::SetAlpha(int Alpha) {
}
}
-cText2SkinBitmap *cText2SkinBitmap::Load(const char *Filename, int Alpha) {
- if (mCache.Contains(Filename))
- return mCache[Filename];
- else {
- cText2SkinBitmap *bmp = new cText2SkinBitmap;
- int len = strlen(Filename);
- bool result = false;
- if (len > 4) {
- if (strcmp(Filename + len - 4, ".xpm") == 0)
- result = bmp->LoadXpm(Filename, Alpha);
- else {
-#ifdef HAVE_IMLIB2
- result = bmp->LoadImlib(Filename, Alpha);
-#else
-# ifdef HAVE_IMAGEMAGICK
- result = bmp->LoadMagick(Filename, Alpha);
-# endif
-#endif
- }
- //else
- //esyslog("ERROR: text2skin: unknown file format for %s", Filename);
- } else
- esyslog("ERROR: text2skin: filename %s too short to identify format", Filename);
-
- if (result) {
- bmp->SetAlpha(Alpha);
- return (mCache[Filename] = bmp);
- } else
- delete bmp;
- }
- return false;
-}
-
bool cText2SkinBitmap::LoadXpm(const char *Filename, int Alpha) {
cBitmap *bmp = new cBitmap(1,1,1);
if (bmp->LoadXpm(Filename)) {
@@ -147,9 +137,6 @@ bool cText2SkinBitmap::LoadImlib(const char *Filename, int Alpha) {
#ifdef HAVE_IMAGEMAGICK
bool cText2SkinBitmap::LoadMagick(const char *Filename, int Alpha) {
- if (mFirstTime)
- InitializeMagick("text2skin");
-
vector<Image> images;
cBitmap *bmp = NULL;
try {
@@ -169,28 +156,14 @@ bool cText2SkinBitmap::LoadMagick(const char *Filename, int Alpha) {
return false;
}
bmp = new cBitmap(w, h, (*it).depth());
+ Dprintf("this image has %d colors\n", (*it).totalColors());
- if ((*it).classType() == PseudoClass) {
- int total = (*it).totalColors();
- for (int ic = 0; ic < (int)total; ++ic) {
- Color c = (*it).colorMap(ic);
- tColor col = (~(c.alphaQuantum() * 255 / MaxRGB) << 24) | ((c.redQuantum() * 255 / MaxRGB) << 16) | ((c.greenQuantum() * 255 / MaxRGB) << 8) | (c.blueQuantum() * 255 / MaxRGB);
- bmp->SetColor(ic, col);
- }
- }
-
const PixelPacket *pix = (*it).getConstPixels(0, 0, w, h);
- const IndexPacket *idx = (*it).getConstIndexes();
for (int iy = 0; iy < h; ++iy) {
for (int ix = 0; ix < w; ++ix) {
- if ((*it).classType() == PseudoClass) {
- bmp->SetIndex(ix, iy, *idx);
- ++idx;
- } else {
- tColor col = (~(pix->opacity * 255 / MaxRGB) << 24) | ((pix->red * 255 / MaxRGB) << 16) | ((pix->green * 255 / MaxRGB) << 8) | (pix->blue * 255 / MaxRGB);
- bmp->DrawPixel(ix, iy, col);
- ++pix;
- }
+ tColor col = (~(pix->opacity * 255 / MaxRGB) << 24) | ((pix->red * 255 / MaxRGB) << 16) | ((pix->green * 255 / MaxRGB) << 8) | (pix->blue * 255 / MaxRGB);
+ bmp->DrawPixel(ix, iy, col);
+ ++pix;
}
}
mBitmaps.push_back(bmp);
diff --git a/bitmap.h b/bitmap.h
index 44a3e1b..79c44e7 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -1,5 +1,5 @@
/*
- * $Id: bitmap.h,v 1.11 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: bitmap.h,v 1.12 2004/06/18 16:08:11 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_BITMAP_H
@@ -9,13 +9,9 @@
#include "cache.h"
#include <vdr/osd.h>
-class cText2SkinBitmap;
-typedef cText2SkinCache<string,cText2SkinBitmap*> cImageCache;
-
class cText2SkinBitmap {
private:
- static cImageCache mCache;
- static bool mFirstTime;
+ static cText2SkinCache mCache;
vector<cBitmap*> mBitmaps;
int mCurrent;
@@ -27,12 +23,14 @@ private:
public:
static cText2SkinBitmap *Load(const char *Filename, int Alpha = 0);
+ static void ResetCache(void) { mCache.Reset(); }
static void FlushCache(void) { mCache.Flush(); }
virtual ~cText2SkinBitmap();
+ void Reset(void) { mCurrent = 0; mLastGet = 0; }
cBitmap &Get(int &UpdateIn);
- void SetColor(int Index, tColor Color) { mBitmaps[mCurrent]->SetColor(Index, Color); }
+ void SetColor(int Index, tColor Color);
void SetAlpha(int Alpha);
bool LoadXpm(const char *Filename, int Alpha);
@@ -44,4 +42,8 @@ public:
#endif
};
+inline void cText2SkinBitmap::SetColor(int Index, tColor Color) {
+ mBitmaps[mCurrent]->SetColor(Index, Color);
+}
+
#endif // VDR_TEXT2SKIN_BITMAP_H
diff --git a/cache.c b/cache.c
index 1182e9e..6c3f99a 100644
--- a/cache.c
+++ b/cache.c
@@ -1,6 +1,57 @@
/*
- * $Id: cache.c,v 1.1 2004/06/05 01:40:13 lordjaxom Exp $
+ * $Id: cache.c,v 1.2 2004/06/18 16:08:11 lordjaxom Exp $
*/
#include "cache.h"
+#include "bitmap.h"
+
+cText2SkinCache::cText2SkinCache(int MaxItems) {
+ mMaxItems = MaxItems;
+}
+
+cText2SkinCache::~cText2SkinCache() {
+ Flush();
+}
+
+void cText2SkinCache::Delete(const key_type &Key, data_type &Data) {
+ delete Data;
+}
+
+void cText2SkinCache::Flush(void) {
+ mUsage.clear();
+ item_iterator it = mItems.begin();
+ for (; it != mItems.end(); ++it)
+ Delete((*it).first, (*it).second);
+ mItems.clear();
+}
+
+void cText2SkinCache::Reset(void) {
+ item_iterator it = mItems.begin();
+ for (; it != mItems.end(); ++it)
+ (*it).second->Reset();
+}
+
+cText2SkinCache::data_type &cText2SkinCache::operator[](const key_type &Key) {
+ item_iterator it = mItems.find(Key);
+ if (it != mItems.end()) {
+ usage_iterator ut = mUsage.begin();
+ for (; ut != mUsage.end(); ++ut) {
+ if ((*ut) == Key) {
+ mUsage.erase(ut);
+ break;
+ }
+ }
+ mUsage.push_back(Key);
+ } else {
+ if ((int)mItems.size() == mMaxItems) {
+ usage_iterator ut = mUsage.begin();
+ Delete(*ut, mItems[*ut]);
+ mItems.erase(*ut);
+ mUsage.erase(mUsage.begin());
+ }
+ it = mItems.insert(item_map::value_type(Key, data_type())).first;
+ mUsage.push_back(Key);
+ }
+ return (*it).second;
+}
diff --git a/cache.h b/cache.h
index 1fd0811..3f48de8 100644
--- a/cache.h
+++ b/cache.h
@@ -1,5 +1,5 @@
/*
- * $Id: cache.h,v 1.4 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: cache.h,v 1.5 2004/06/18 16:08:11 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_CACHE_HPP
@@ -8,133 +8,38 @@
#include "common.h"
#include <vdr/tools.h>
-// template class generic cache
+class cText2SkinBitmap;
-template<class K,class D>
class cText2SkinCache {
private:
- struct Item {
- K _key;
- D _data;
- time_t _lastUsed;
+ typedef string key_type;
+ typedef cText2SkinBitmap* data_type;
- Item *_next;
- Item *_prev;
+ typedef map<key_type,data_type> item_map;
+ typedef item_map::iterator item_iterator;
+ typedef vector<key_type> usage_list;
+ typedef usage_list::iterator usage_iterator;
- Item() { _next = _prev = NULL; }
- };
+ item_map mItems;
+ usage_list mUsage;
+ int mMaxItems;
- typedef map <K,Item*> DataMap;
-
- DataMap _items;
- int _maxItems;
- Item *_first;
- Item *_last;
-
- void Unlink(Item *item);
- void Update(Item *item);
- void Delete(Item *item);
- void Delete(K &key, D &data);
+protected:
+ void Delete(const key_type &Key, data_type &Data);
public:
- cText2SkinCache(int maxItems);
+ cText2SkinCache(int MaxItems);
~cText2SkinCache();
+ void Reset(void);
void Flush(void);
- bool Contains(const K &key);
- D &operator[](const K &key);
+ bool Contains(const key_type &Key);
+ data_type &operator[](const key_type &Key);
+ uint Count(void) { return mItems.size(); }
};
-template<class K,class D>
-inline void cText2SkinCache<K,D>::Unlink(Item *item) {
- if (item == _first) {
- _first = item->_next;
- if (_first)
- _first->_prev = NULL;
- else
- _last = NULL;
- } else if (item == _last) {
- _last = item->_prev;
- _last->_next = NULL;
- } else {
- item->_prev->_next = item->_next;
- item->_next->_prev = item->_prev;
- }
-}
-
-template<class K,class D>
-inline void cText2SkinCache<K,D>::Delete(Item *item) {
- Delete(item->_key, item->_data);
- delete item;
-}
-
-template<class K,class D>
-inline void cText2SkinCache<K,D>::Update(Item *item) {
- item->_lastUsed = time_ms();
- if (item->_next != NULL || item->_prev != NULL)
- Unlink(item);
-
- item->_next = NULL;
- item->_prev = _last;
- if (_last)
- _last->_next = item;
- _last = item;
- if (!_first)
- _first = item;
-
- while ((int)_items.size() > _maxItems) {
- Item *aged = _first;
- _items.erase(aged->_key);
- Unlink(aged);
- Delete(aged);
- }
-}
-
-template<class K,class D>
-inline bool cText2SkinCache<K,D>::Contains(const K &key) {
- return (_items.find(key) != _items.end());
-}
-
-template<class K,class D>
-cText2SkinCache<K,D>::cText2SkinCache(int maxItems) {
- _maxItems = maxItems;
- _first = _last = NULL;
-}
-
-template<class K,class D>
-cText2SkinCache<K,D>::~cText2SkinCache() {
- Flush();
-}
-
-template<class K,class D>
-void cText2SkinCache<K,D>::Delete(K &key, D &Data) {
- abort();
-}
-
-template<class K,class D>
-void cText2SkinCache<K,D>::Flush(void) {
- Item *cur = _first;
- while (cur) {
- Item *tmp = cur->_next;
- _items.erase(cur->_key);
- Unlink(cur);
- Delete(cur);
- cur = tmp;
- }
-}
-
-template<class K,class D>
-D &cText2SkinCache<K,D>::operator[](const K &key) {
- Item *item;
- if (Contains(key)) {
- item = _items[key];
- } else {
- item = new Item;
- item->_key = key;
- _items[key] = item;
- }
- Update(item);
- return item->_data;
+inline bool cText2SkinCache::Contains(const key_type &Key) {
+ return mItems.find(Key) != mItems.end();
}
#endif // VDR_TEXT2SKIN_CACHE_HPP
diff --git a/i18n.c b/i18n.c
index affc848..e298d22 100644
--- a/i18n.c
+++ b/i18n.c
@@ -1,5 +1,5 @@
/*
- * $Id: i18n.c,v 1.7 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: i18n.c,v 1.8 2004/06/18 16:08:11 lordjaxom Exp $
*/
#include "i18n.h"
@@ -24,6 +24,44 @@ const tI18nPhrase Phrases[] = {
"",
""
},
+ { "Flush image cache",
+ "Bildspeicher leeren",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Tyhjennä kuvat välimuistista",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ },
+ { "Flushing image cache...",
+ "Bildspeicher wird geleert...",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Tyhjennetään välimuistia...",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ },
{ "Max. image cache size",
"Max. Größe des Bildspeichers",
"",
diff --git a/render.c b/render.c
index e778dfc..0978e9a 100644
--- a/render.c
+++ b/render.c
@@ -1,5 +1,5 @@
/*
- * $Id: render.c,v 1.31 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: render.c,v 1.33 2004/06/18 16:41:08 lordjaxom Exp $
*/
#include "render.h"
@@ -99,7 +99,7 @@ cText2SkinRender::~cText2SkinRender() {
}
delete mScroller;
delete mOsd;
- cText2SkinBitmap::FlushCache();
+ cText2SkinBitmap::ResetCache();
}
void cText2SkinRender::Action(void) {
@@ -247,6 +247,7 @@ void cText2SkinRender::DrawBackground(const POINT &Pos, const SIZE &Size, const
if (Path != "") {
char *p;
asprintf(&p, "%s/%s/%s", SkinPath(), mData->Skin().c_str(), Path.c_str());
+ Dprintf("Trying to load image: %s\n", p);
if ((bmp = cText2SkinBitmap::Load(p, Alpha)) != NULL) {
if (Bg) bmp->SetColor(0, *Bg);
if (Fg) bmp->SetColor(1, *Fg);
@@ -378,13 +379,13 @@ void cText2SkinRender::DrawScrollbar(const POINT &Pos, const SIZE &Size, int Off
POINT sp = Pos;
SIZE ss = Size;
sp.y += Size.h * Offset / Total;
- ss.h -= Size.h * (Shown - 2) / Total;
+ ss.h = Size.h * Shown / Total;
DrawRectangle(sp, ss, Fg);
} else {
POINT sp = Pos;
SIZE ss = Size;
sp.x += Size.w * Offset / Total;
- ss.w -= Size.w * (Shown - 2) / Total;
+ ss.w = Size.w * Shown / Total;
DrawRectangle(sp, ss, Fg);
}
}
diff --git a/setup.c b/setup.c
index 45b4ee8..3a96131 100644
--- a/setup.c
+++ b/setup.c
@@ -1,5 +1,5 @@
/*
- * $Id: setup.c,v 1.3 2004/06/12 21:16:18 lordjaxom Exp $
+ * $Id: setup.c,v 1.4 2004/06/18 16:08:11 lordjaxom Exp $
*/
#include "setup.h"
@@ -23,6 +23,7 @@ bool cText2SkinSetup::SetupParse(const char *Name, const char *Value) {
cText2SkinSetupPage::cText2SkinSetupPage(void) {
mData = Text2SkinSetup;
+ Add(new cOsdItem(tr("Flush image cache"), osUser1));
Add(new cMenuEditIntItem(tr("Max. image cache size"), &mData.MaxCacheFill));
}
@@ -34,3 +35,14 @@ void cText2SkinSetupPage::Store(void) {
Text2SkinSetup = mData;
}
+eOSState cText2SkinSetupPage::ProcessKey(eKeys Key) {
+ eOSState state = cMenuSetupPage::ProcessKey(Key);
+ if (state == osUser1) {
+ Skins.Message(mtInfo, tr("Flushing image cache..."));
+ cText2SkinBitmap::FlushCache();
+ Skins.Message(mtInfo, NULL);
+ return osContinue;
+ }
+ return state;
+}
+
diff --git a/setup.h b/setup.h
index b60c60c..c726190 100644
--- a/setup.h
+++ b/setup.h
@@ -1,5 +1,5 @@
/*
- * $Id: setup.h,v 1.2 2004/06/12 19:16:11 lordjaxom Exp $
+ * $Id: setup.h,v 1.3 2004/06/18 16:08:11 lordjaxom Exp $
*/
#ifndef VDR_TEXT2SKIN_SETUP_H
@@ -26,6 +26,7 @@ public:
virtual ~cText2SkinSetupPage();
virtual void Store(void);
+ eOSState ProcessKey(eKeys Key);
};
extern cText2SkinSetup Text2SkinSetup;
diff --git a/text2skin.c b/text2skin.c
index c974236..6822797 100644
--- a/text2skin.c
+++ b/text2skin.c
@@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
- * $Id: text2skin.c,v 1.20 2004/06/16 18:46:50 lordjaxom Exp $
+ * $Id: text2skin.c,v 1.21 2004/06/18 16:08:11 lordjaxom Exp $
*/
#include "text2skin.h"
@@ -11,32 +11,27 @@
#include "i18n.h"
#include "loader.h"
-const char *cText2SkinPlugin::VERSION = "0.0.5";
+const char *cText2SkinPlugin::VERSION = "0.0.6";
const char *cText2SkinPlugin::THEMEVERSION = "0.0.2";
const char *cText2SkinPlugin::DESCRIPTION = "Loader for text-based skins";
-cText2SkinPlugin::cText2SkinPlugin(void)
-{
+cText2SkinPlugin::cText2SkinPlugin(void) {
}
-cText2SkinPlugin::~cText2SkinPlugin()
-{
+cText2SkinPlugin::~cText2SkinPlugin() {
}
-bool cText2SkinPlugin::Start(void)
-{
+bool cText2SkinPlugin::Start(void) {
RegisterI18n(Phrases);
cText2SkinLoader::Start();
return true;
}
-cMenuSetupPage *cText2SkinPlugin::SetupMenu(void)
-{
+cMenuSetupPage *cText2SkinPlugin::SetupMenu(void) {
return new cText2SkinSetupPage;
}
-bool cText2SkinPlugin::SetupParse(const char *Name, const char *Value)
-{
+bool cText2SkinPlugin::SetupParse(const char *Name, const char *Value) {
return Text2SkinSetup.SetupParse(Name, Value);
}