diff options
-rw-r--r-- | HISTORY | 12 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | README | 7 | ||||
-rw-r--r-- | bitmap.c | 103 | ||||
-rw-r--r-- | bitmap.h | 16 | ||||
-rw-r--r-- | cache.c | 53 | ||||
-rw-r--r-- | cache.h | 135 | ||||
-rw-r--r-- | i18n.c | 40 | ||||
-rw-r--r-- | render.c | 9 | ||||
-rw-r--r-- | setup.c | 14 | ||||
-rw-r--r-- | setup.h | 3 | ||||
-rw-r--r-- | text2skin.c | 19 |
12 files changed, 199 insertions, 216 deletions
@@ -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 @@ -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 @@ -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. @@ -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); @@ -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 @@ -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; +} @@ -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 @@ -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", "", @@ -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); } } @@ -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; +} + @@ -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); } |