add FontSourceWin.cpp/.h

This commit is contained in:
hyzboy 2020-06-29 11:06:47 +08:00
parent 18f68df9be
commit 6c3dba9dc2
5 changed files with 248 additions and 59 deletions

View File

@ -1,54 +0,0 @@
#ifndef HGL_GRAPH_FONT_BITMAP_CACHE_INCLUDE
#define HGL_GRAPH_FONT_BITMAP_CACHE_INCLUDE
#include<hgl/type/StrChar.h>
#include<hgl/type/Map.h>
#include<hgl/graph/font/Font.h>
using namespace hgl;
namespace hgl
{
namespace graph
{
/**
*
*/
class FontBitmapCache
{
/**
*
*/
struct Bitmap
{
int count; //使用次数
int x,y; //图像显示偏移
int w,h; //图像尺寸
int adv_x,adv_y;//字符尺寸
uint8 *data;
};//struct Bitmap
protected:
Font fnt;
MapObject<u32char,FontBitmapCache::Bitmap> chars_bitmap; ///<字符位图
protected:
virtual bool MakeCharBitmap(FontBitmapCache::Bitmap *,u32char)=0; ///<产生字体数据
virtual int GetLineHeight()const=0; ///<取得行高
public:
FontBitmapCache(const Font &f){fnt=f;}
virtual ~FontBitmapCache()=default;
FontBitmapCache::Bitmap *GetCharBitmap(const u32char &); ///<取得字符位图数据
};//class FontBitmapCache
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_FONT_BITMAP_CACHE_INCLUDE

View File

@ -0,0 +1,54 @@
#ifndef HGL_GRAPH_FONT_SOURCE_INCLUDE
#define HGL_GRAPH_FONT_SOURCE_INCLUDE
#include<hgl/type/StrChar.h>
#include<hgl/type/Map.h>
#include<hgl/graph/font/Font.h>
using namespace hgl;
namespace hgl
{
namespace graph
{
/**
*
*/
struct FontBitmap
{
int count; //使用次数
int x,y; //图像显示偏移
int w,h; //图像尺寸
int adv_x,adv_y;//字符尺寸
uint8 *data;
};//struct FontBitmap
/**
*
*/
class FontSource
{
protected:
Font fnt;
MapObject<u32char,FontBitmap> chars_bitmap; ///<字符位图
protected:
virtual bool MakeCharBitmap(FontBitmap *,u32char)=0; ///<产生字体数据
virtual int GetLineHeight()const=0; ///<取得行高
public:
FontSource(const Font &f){fnt=f;}
virtual ~FontSource()=default;
FontBitmap *GetCharBitmap(const u32char &); ///<取得字符位图数据
};//class FontSource
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_FONT_SOURCE_INCLUDE

View File

@ -1,24 +1,24 @@
#include<hgl/graph/font/FontBitmapCache.h>
#include<hgl/graph/font/FontSource.h>
namespace hgl
{
namespace graph
{
FontBitmapCache::Bitmap *FontBitmapCache::GetCharBitmap(const u32char &ch)
FontBitmap *FontSource::GetCharBitmap(const u32char &ch)
{
if(!this)
return(nullptr);
if(hgl::isspace(ch))return(nullptr); //不能显示的数据或是空格
FontBitmapCache::Bitmap *bmp;
FontBitmap *bmp;
if(chars_bitmap.Get(ch,bmp))
return bmp;
bmp=new FontBitmapCache::Bitmap;
bmp=new FontBitmap;
memset(bmp,0,sizeof(FontBitmapCache::Bitmap));
memset(bmp,0,sizeof(FontBitmap));
if(!MakeCharBitmap(bmp,ch))
{

View File

@ -0,0 +1,150 @@
#include"FontSourceWin.h"
namespace hgl
{
namespace graph
{
namespace
{
void Convert8BitGrey(uint8 *dst,uint8 *src,int w,int h,int line_bytes)
{
int pos;
uint8 *sp=src,*p;
while(h--)
{
pos=w;
p=sp;
while(pos--)
{
if(*p==64)*dst=255;
else *dst=(*p)<<2;
dst++;
p++;
}
sp+=line_bytes;
}
}
void ConvertBitmap(uint8 *dst,uint8 *src,int w,int h,int line_bytes)
{
uint8 *sp=src,*p;
uint8 bit;
while(h--)
{
p=sp;
bit=1<<7;
for(int i=0;i<w;i++)
{
*dst++=(*p&bit)?255:0;
if(bit==0x01)
{
bit=1<<7;
p++;
}
else bit>>=1;
}
sp+=line_bytes;
}//while(h--)
}
}//namespace
FontSource *CreateWinBitmapFont(const Font &f)
{
return(new WinBitmapFont(f));
}
WinBitmapFont::WinBitmapFont(const Font &f):FontSource(f)
{
hdc=CreateCompatibleDC(0);
LineHeight=(fnt.height*GetDeviceCaps(hdc,LOGPIXELSY))/72;
LineDistance=(LineHeight-fnt.height)/2;
hfont=CreateFont( -fnt.height,
fnt.width,
0,
0,
fnt.bold?FW_BOLD:FW_REGULAR,
fnt.italic,
false,
0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,
FF_DONTCARE,
fnt.name);
SelectObject(hdc,hfont);
if(!fnt.anti||fnt.height<=10) //<=10象素强制用无抗矩齿字体
ggo=GGO_BITMAP;
else
ggo=GGO_GRAY8_BITMAP;
buffer_size=fnt.width*fnt.height*4;
buffer=new uint8[buffer_size];
}
WinBitmapFont::~WinBitmapFont()
{
delete[] buffer;
DeleteObject(hfont);
DeleteDC(hdc);
}
bool WinBitmapFont::MakeCharBitmap(FontBitmap *bmp,u32char ch)
{
if(ch>0xFFFF)
return(false);
memset(&gm,0,sizeof(GLYPHMETRICS));
memset(&mat,0,sizeof(MAT2));
mat.eM11.value = 1;
mat.eM22.value = 1;
const int size=GetGlyphOutline(hdc,ch,ggo,&gm,0,0,&mat);
if(size<=0)return(false);
if(size>buffer_size)
{
delete[] buffer;
buffer_size=size;
buffer=new uint8[buffer_size];
}
GetGlyphOutline(hdc,ch,ggo,&gm,buffer_size,buffer,&mat);
bmp->w=gm.gmBlackBoxX;
bmp->h=gm.gmBlackBoxY;
bmp->x=gm.gmptGlyphOrigin.x;
bmp->y=fnt.height-gm.gmptGlyphOrigin.y-LineDistance;
bmp->adv_x=gm.gmCellIncX;
bmp->adv_y=gm.gmCellIncY;
bmp->data=new uint8[bmp->w*bmp->h];
if(ggo==GGO_GRAY8_BITMAP)
Convert8BitGrey(bmp->data,buffer,gm.gmBlackBoxX,gm.gmBlackBoxY,size/bmp->h);
else
ConvertBitmap(bmp->data,buffer,gm.gmBlackBoxX,gm.gmBlackBoxY,size/bmp->h);
return(true);
}
}//namespace graph
}//namespace hgl

View File

@ -0,0 +1,39 @@
#ifndef HGL_GRAPH_FONT_SOURCE_WINDOWS_INCLUDE
#define HGL_GRAPH_FONT_SOURCE_WINDOWS_INCLUDE
#include<hgl/graph/font/FontSource.h>
#include<windows.h>
namespace hgl
{
namespace graph
{
class WinBitmapFont:public FontSource
{
HDC hdc;
HFONT hfont;
GLYPHMETRICS gm;
MAT2 mat;
uint ggo;
unsigned char *buffer;
int buffer_size;
protected:
int LineHeight;
int LineDistance;
public:
WinBitmapFont(const Font &);
~WinBitmapFont();
bool MakeCharBitmap(FontBitmap *,u32char) override; ///<产生字体数据
int GetLineHeight()const override{return LineHeight;} ///<取得行高
};//class WinBitmapFont
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_FONT_SOURCE_WINDOWS_INCLUDE