Aegisub/vsfilter/libssf/Renderer.h

160 lines
3.4 KiB
C
Raw Normal View History

/*
* 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 T>
class Cache
{
protected:
StringMapW<T> m_key2obj;
CAtlList<CStringW> 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<T>::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<FontWrapper*>
{
public:
FontCache() : Cache(20) {}
FontWrapper* Create(HDC hDC, const LOGFONT& lf);
};
class GlyphPathCache : public Cache<GlyphPath*>
{
public:
GlyphPathCache() : Cache(100) {}
GlyphPath* Create(HDC hDC, const FontWrapper* f, WCHAR c);
};
class Row : public CAutoPtrList<Glyph>
{
public:
int ascent, descent, border, width;
Row() {ascent = descent = border = width = 0;}
};
class RenderedSubtitle
{
public:
CRect m_spdrc;
CRect m_clip;
CAutoPtrList<Glyph> 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<RenderedSubtitle*>
{
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<SubRect>
{
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<Subtitle>& subs);
RenderedSubtitle* Lookup(const Subtitle* s, const CSize& vs, const CRect& vr);
};
}