forked from mia/Aegisub
1fb4f58ff2
Originally committed to SVN as r1399.
160 lines
No EOL
3.4 KiB
C++
160 lines
No EOL
3.4 KiB
C++
/*
|
|
* 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);
|
|
};
|
|
} |