add oversampler
This commit is contained in:
274
oversampling/WDL/lice/lice_text.h
Normal file
274
oversampling/WDL/lice/lice_text.h
Normal file
@@ -0,0 +1,274 @@
|
||||
#ifndef _LICE_TEXT_H_
|
||||
#define _LICE_TEXT_H_
|
||||
|
||||
#include "lice.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include "../swell/swell.h"
|
||||
#endif
|
||||
#include "../heapbuf.h"
|
||||
|
||||
#define LICE_FONT_FLAG_VERTICAL 1 // rotate text to vertical (do not set the windows font to vertical though)
|
||||
#define LICE_FONT_FLAG_VERTICAL_BOTTOMUP 2
|
||||
|
||||
#define LICE_FONT_FLAG_PRECALCALL 4
|
||||
//#define LICE_FONT_FLAG_ALLOW_NATIVE 8
|
||||
#define LICE_FONT_FLAG_FORCE_NATIVE 1024
|
||||
|
||||
#define LICE_FONT_FLAG_FX_BLUR 16
|
||||
#define LICE_FONT_FLAG_FX_INVERT 32
|
||||
#define LICE_FONT_FLAG_FX_MONO 64 // faster but no AA/etc
|
||||
|
||||
#define LICE_FONT_FLAG_FX_SHADOW 128 // these imply MONO
|
||||
#define LICE_FONT_FLAG_FX_OUTLINE 256
|
||||
|
||||
#define LICE_FONT_FLAG_OWNS_HFONT 512
|
||||
|
||||
// could do a mask for these flags
|
||||
#define LICE_FONT_FLAGS_HAS_FX(flag) \
|
||||
(flag&(LICE_FONT_FLAG_VERTICAL|LICE_FONT_FLAG_VERTICAL_BOTTOMUP| \
|
||||
LICE_FONT_FLAG_FX_BLUR|LICE_FONT_FLAG_FX_INVERT|LICE_FONT_FLAG_FX_MONO| \
|
||||
LICE_FONT_FLAG_FX_SHADOW|LICE_FONT_FLAG_FX_OUTLINE))
|
||||
|
||||
#define LICE_DT_NEEDALPHA 0x80000000 // include in DrawText() if the output alpha channel is important
|
||||
#define LICE_DT_USEFGALPHA 0x40000000 // uses alpha channel in fg color
|
||||
|
||||
class LICE_IFont
|
||||
{
|
||||
public:
|
||||
virtual ~LICE_IFont() {}
|
||||
|
||||
virtual void SetFromHFont(HFONT font, int flags=0)=0; // hfont must REMAIN valid, unless LICE_FONT_FLAG_PRECALCALL or LICE_FONT_FLAG_OWNS_HFONT set (OWNS means LICE_IFont will clean up hfont on font change or exit)
|
||||
|
||||
virtual LICE_pixel SetTextColor(LICE_pixel color)=0;
|
||||
virtual LICE_pixel SetBkColor(LICE_pixel color)=0;
|
||||
virtual LICE_pixel SetEffectColor(LICE_pixel color)=0;
|
||||
virtual int SetBkMode(int bkmode)=0;
|
||||
virtual void SetCombineMode(int combine, float alpha=1.0f)=0;
|
||||
|
||||
virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags)=0;
|
||||
|
||||
virtual LICE_pixel GetTextColor()=0;
|
||||
virtual HFONT GetHFont()=0;
|
||||
virtual int GetLineHeight()=0;
|
||||
virtual void SetLineSpacingAdjust(int amt)=0;
|
||||
};
|
||||
|
||||
|
||||
#ifndef LICE_TEXT_NO_DECLARE_CACHEDFONT
|
||||
|
||||
class LICE_CachedFont : public LICE_IFont
|
||||
{
|
||||
public:
|
||||
LICE_CachedFont();
|
||||
virtual ~LICE_CachedFont();
|
||||
|
||||
virtual void SetFromHFont(HFONT font, int flags=0);
|
||||
|
||||
virtual LICE_pixel SetTextColor(LICE_pixel color) { LICE_pixel ret=m_fg; m_fg=color; return ret; }
|
||||
virtual LICE_pixel SetBkColor(LICE_pixel color) { LICE_pixel ret=m_bg; m_bg=color; return ret; }
|
||||
virtual LICE_pixel SetEffectColor(LICE_pixel color) { LICE_pixel ret=m_effectcol; m_effectcol=color; return ret; }
|
||||
virtual int SetBkMode(int bkmode) { int bk = m_bgmode; m_bgmode=bkmode; return bk; }
|
||||
virtual void SetCombineMode(int combine, float alpha=1.0f) { m_comb=combine; m_alpha=alpha; }
|
||||
|
||||
virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags)
|
||||
{
|
||||
return DrawTextImpl(bm,str,strcnt,rect,dtFlags);
|
||||
}
|
||||
|
||||
virtual LICE_pixel GetTextColor() { return m_fg; }
|
||||
virtual HFONT GetHFont() { return m_font; }
|
||||
virtual int GetLineHeight() { return m_line_height; }
|
||||
|
||||
virtual void SetLineSpacingAdjust(int amt) { m_lsadj=amt; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool DrawGlyph(LICE_IBitmap *bm, unsigned short c, int xpos, int ypos, const RECT *clipR);
|
||||
int DrawTextImpl(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags); // cause swell defines DrawText to SWELL_DrawText etc
|
||||
|
||||
bool RenderGlyph(unsigned short idx);
|
||||
|
||||
const char *NextWordBreak(const char *str, int strcnt, int w);
|
||||
|
||||
LICE_pixel m_fg,m_bg,m_effectcol;
|
||||
int m_bgmode;
|
||||
int m_comb;
|
||||
float m_alpha;
|
||||
int m_flags;
|
||||
|
||||
int m_line_height,m_lsadj;
|
||||
struct charEnt
|
||||
{
|
||||
int base_offset; // offset in m_cachestore+1, so 1=offset0, 0=unset, -1=failed to render
|
||||
int width, height;
|
||||
int advance;
|
||||
int charid; // used by m_extracharlist
|
||||
int left_extra;
|
||||
};
|
||||
charEnt *findChar(unsigned short c);
|
||||
|
||||
charEnt m_lowchars[128]; // first 128 chars cached here
|
||||
WDL_TypedBuf<charEnt> m_extracharlist;
|
||||
WDL_TypedBuf<unsigned char> m_cachestore;
|
||||
|
||||
static int _charSortFunc(const void *a, const void *b);
|
||||
|
||||
HFONT m_font;
|
||||
|
||||
};
|
||||
|
||||
#endif // !LICE_TEXT_NO_DECLARE_CACHEDFONT
|
||||
|
||||
#ifndef LICE_TEXT_NO_MULTIDPI
|
||||
class __LICE_dpiAwareFont : public LICE_IFont
|
||||
{
|
||||
struct rec {
|
||||
LICE_IFont *cache;
|
||||
int sz;
|
||||
};
|
||||
WDL_TypedBuf<rec> m_list; // used entries are at end of list, most recently used last. sz=0 for unused
|
||||
|
||||
int (*m_getflags)(int);
|
||||
int m_flags;
|
||||
LICE_pixel m_fg, m_bg, m_effectcol;
|
||||
int m_bgmode, m_comb;
|
||||
float m_alpha;
|
||||
int m_lsadj;
|
||||
|
||||
public:
|
||||
LOGFONT m_lf;
|
||||
|
||||
|
||||
// LICE_IFont interface
|
||||
virtual void SetFromHFont(HFONT font, int flags=0) { }
|
||||
|
||||
virtual LICE_pixel SetTextColor(LICE_pixel color) { LICE_pixel ret=m_fg; m_fg=color; return ret; }
|
||||
virtual LICE_pixel SetBkColor(LICE_pixel color) { LICE_pixel ret=m_bg; m_bg=color; return ret; }
|
||||
virtual LICE_pixel SetEffectColor(LICE_pixel color) { LICE_pixel ret=m_effectcol; m_effectcol=color; return ret; }
|
||||
virtual int SetBkMode(int bkmode) { int bk = m_bgmode; m_bgmode=bkmode; return bk; }
|
||||
virtual void SetCombineMode(int combine, float alpha=1.0f) { m_comb=combine; m_alpha=alpha; }
|
||||
|
||||
virtual int DrawText(LICE_IBitmap *bm, const char *str, int strcnt, RECT *rect, UINT dtFlags)
|
||||
{
|
||||
LICE_IFont *f = get(bm);
|
||||
if (!f) return 0;
|
||||
if (!(dtFlags & DT_CALCRECT))
|
||||
{
|
||||
f->SetTextColor(m_fg);
|
||||
f->SetBkColor(m_bg);
|
||||
f->SetEffectColor(m_effectcol);
|
||||
f->SetBkMode(m_bgmode);
|
||||
f->SetCombineMode(m_comb,m_alpha);
|
||||
f->SetLineSpacingAdjust(m_lsadj);
|
||||
}
|
||||
return f->DrawText(bm,str,strcnt,rect,dtFlags);
|
||||
}
|
||||
|
||||
virtual LICE_pixel GetTextColor() { return m_fg; }
|
||||
virtual HFONT GetHFont() { return NULL; }
|
||||
virtual int GetLineHeight() { return GetLineHeightDPI(NULL); }
|
||||
|
||||
virtual void SetLineSpacingAdjust(int amt) { m_lsadj=amt; }
|
||||
|
||||
__LICE_dpiAwareFont(int maxsz)
|
||||
{
|
||||
memset(&m_lf,0,sizeof(m_lf));
|
||||
m_getflags = NULL;
|
||||
m_flags=0;
|
||||
m_fg=m_bg=m_effectcol=0;
|
||||
m_bgmode=TRANSPARENT;
|
||||
m_comb=0;
|
||||
m_alpha=1.0;
|
||||
m_lsadj=0;
|
||||
|
||||
rec *l = m_list.ResizeOK(maxsz);
|
||||
if (l) memset(l,0,sizeof(*l)*maxsz);
|
||||
}
|
||||
~__LICE_dpiAwareFont()
|
||||
{
|
||||
for (int x = 0; x < m_list.GetSize(); x ++) delete m_list.Get()[x].cache;
|
||||
}
|
||||
void SetFromLogFont(LOGFONT *lf, int (*get_flags)(int))
|
||||
{
|
||||
m_lf = *lf;
|
||||
m_getflags = get_flags;
|
||||
m_flags = get_flags ? get_flags(0) : 0;
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
int x = m_list.GetSize()-1;
|
||||
rec *t = m_list.Get();
|
||||
while (x>=0 && t[x].sz) t[x--].sz=0;
|
||||
}
|
||||
|
||||
LICE_IFont *get_for_sc(int fsc)
|
||||
{
|
||||
int use_flag = m_getflags ? m_getflags(0) & ~LICE_FONT_FLAG_PRECALCALL : 0;
|
||||
if (m_flags != use_flag)
|
||||
{
|
||||
m_flags = use_flag;
|
||||
clear();
|
||||
}
|
||||
|
||||
int ht = m_lf.lfHeight, ht2 = m_lf.lfWidth;
|
||||
if (fsc && fsc != 256)
|
||||
{
|
||||
ht = (ht * fsc) / 256;
|
||||
ht2 = (ht2 * fsc) / 256;
|
||||
use_flag |= LICE_FONT_FLAG_FORCE_NATIVE;
|
||||
}
|
||||
|
||||
int x = m_list.GetSize()-1;
|
||||
rec *t = m_list.Get();
|
||||
while (x>=0 && t[x].sz != ht && t[x].sz) x--;
|
||||
if (x<0) t[x=0].sz = 0; // if list full, use oldest item
|
||||
|
||||
// move to end of list
|
||||
if (x != m_list.GetSize()-1)
|
||||
{
|
||||
rec tmp = t[x];
|
||||
m_list.Delete(x);
|
||||
m_list.Add(tmp);
|
||||
}
|
||||
|
||||
t = m_list.Get() + m_list.GetSize() - 1;
|
||||
if (!t->cache) t->cache = __CreateFont();
|
||||
if (!t->sz && t->cache)
|
||||
{
|
||||
t->sz = ht;
|
||||
LOGFONT lf = m_lf;
|
||||
lf.lfHeight = ht;
|
||||
lf.lfWidth = ht2;
|
||||
#ifdef _WIN32
|
||||
if (!(m_flags & LICE_FONT_FLAG_FORCE_NATIVE) && abs(lf.lfHeight) <= 14) lf.lfQuality = NONANTIALIASED_QUALITY;
|
||||
#endif
|
||||
t->cache->SetFromHFont(CreateFontIndirect(&lf), LICE_FONT_FLAG_OWNS_HFONT | use_flag);
|
||||
}
|
||||
|
||||
return t->cache;
|
||||
}
|
||||
LICE_IFont *get(LICE_IBitmap *bm)
|
||||
{
|
||||
return get_for_sc(bm ? (int)bm->Extended(LICE_EXT_GET_ANY_SCALING,NULL) : 0);
|
||||
}
|
||||
|
||||
|
||||
int GetLineHeightDPI(LICE_IBitmap *bm)
|
||||
{
|
||||
LICE_IFont *f = get(bm);
|
||||
return f ? f->GetLineHeight() : 10;
|
||||
}
|
||||
virtual LICE_IFont *__CreateFont()=0;
|
||||
};
|
||||
|
||||
template<class BASEFONT> class LICE_dpiAwareFont : public __LICE_dpiAwareFont {
|
||||
public:
|
||||
LICE_dpiAwareFont(int max) : __LICE_dpiAwareFont(max) { }
|
||||
virtual LICE_IFont *__CreateFont() { return new BASEFONT; }
|
||||
};
|
||||
#endif//LICE_TEXT_NO_MULTIDPI
|
||||
|
||||
#endif//_LICE_TEXT_H_
|
||||
Reference in New Issue
Block a user