/* * Copyright (C) 2003-2006 Gabest * http://www.gabest.org * * 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, 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * http://www.gnu.org/copyleft/gpl.html * */ #pragma once #include "StringMap.h" #include "Glyph.h" namespace ssf { template class Cache { protected: StringMapW m_key2obj; CAtlList m_objs; size_t m_limit; public: Cache(size_t limit) {m_limit = max(1, limit);} virtual ~Cache() {RemoveAll();} void RemoveAll() { POSITION pos = m_key2obj.GetStartPosition(); while(pos) delete m_key2obj.GetNextValue(pos); m_key2obj.RemoveAll(); m_objs.RemoveAll(); } void Add(const CStringW& key, T& obj, bool fFlush = true) { if(StringMapW::CPair* p = m_key2obj.Lookup(key)) delete p->m_value; else m_objs.AddTail(key); m_key2obj[key] = obj; if(fFlush) Flush(); } void Flush() { while(m_objs.GetCount() > m_limit) { CStringW key = m_objs.RemoveHead(); ASSERT(m_key2obj.Lookup(key)); delete m_key2obj[key]; m_key2obj.RemoveKey(key); } } bool Lookup(const CStringW& key, T& val) { return m_key2obj.Lookup(key, val) && val; } void Invalidate(const CStringW& key) { T val; if(m_key2obj.Lookup(key, val)) { delete val; m_key2obj[key] = NULL; } } }; class FontCache : public Cache { public: FontCache() : Cache(20) {} FontWrapper* Create(HDC hDC, const LOGFONT& lf); }; class GlyphPathCache : public Cache { public: GlyphPathCache() : Cache(100) {} GlyphPath* Create(HDC hDC, const FontWrapper* f, WCHAR c); }; class Row : public CAutoPtrList { public: int ascent, descent, border, width; Row() {ascent = descent = border = width = 0;} }; class RenderedSubtitle { public: CRect m_spdrc; CRect m_clip; CAutoPtrList m_glyphs; RenderedSubtitle(const CRect& spdrc, const CRect& clip) : m_spdrc(spdrc), m_clip(clip) {} virtual ~RenderedSubtitle() {} CRect Draw(SubPicDesc& spd) const; }; class RenderedSubtitleCache : public Cache { public: RenderedSubtitleCache() : Cache(10) {} }; class SubRect { public: CRect rect; float layer; SubRect() {} SubRect(const CRect& r, float l) : rect(r), layer(l) {} }; class SubRectAllocator : public StringMapW { CSize vs; CRect vr; public: void UpdateTarget(const CSize& vs, const CRect& vr); void GetRect(CRect& rect, const Subtitle* s, const Align& align, int tlb, int brb); }; class Renderer { HDC m_hDC; FontCache m_fc; GlyphPathCache m_gpc; RenderedSubtitleCache m_rsc; SubRectAllocator m_sra; public: Renderer(); virtual ~Renderer(); void NextSegment(const CAutoPtrList& subs); RenderedSubtitle* Lookup(const Subtitle* s, const CSize& vs, const CRect& vr); }; }