1 #include "mof/Font.hpp"
4 #include "mof/ConsoleIO.hpp"
6 #include "mof/utilities.hpp"
8 #pragma comment(lib, "gdi32.lib")
10 const TCHAR* mof::Font::MS_GOTHIC = _T("
\82l
\82r
\83S
\83V
\83b
\83N");
11 const TCHAR* mof::Font::MS_P_GOTHIC = _T("
\82l
\82r
\82o
\83S
\83V
\83b
\83N");
18 std::vector<mof::tstring> additionalFontResources;
22 foreach( mof::tstring& filename , additionalFontResources )
24 RemoveFontResource( filename.c_str() );
31 int iOfs_x , iOfs_y , iBmp_w , iBmp_h , level , width;
35 GlyphData(GLYPHMETRICS& GM , TEXTMETRIC& TM , int _level , int bufSize){
36 iOfs_x = GM.gmptGlyphOrigin.x;
37 iOfs_y = TM.tmAscent - GM.gmptGlyphOrigin.y;
38 iBmp_w = GM.gmBlackBoxX + (4-(GM.gmBlackBoxX%4))%4;
39 iBmp_h = GM.gmBlackBoxY;
41 width = GM.gmCellIncX;
42 pBmpBuffer = new BYTE[bufSize];
51 struct mof::Font::Impl{
54 mof::tstring font_name_;
55 mof::font_context context_;
57 Impl(const TCHAR* font_name, size_t fontSize_, const mof::font_context& context)
58 : font_name_(font_name), hFont(NULL) ,fontSize(fontSize_), context_(context)
68 mof::Font::Font(const TCHAR* fontName , size_t size)
69 : m_pImpl(new Impl(fontName, size, mof::font_context()))
71 LOGFONT lf = {m_pImpl->fontSize , 0, 0, 0, FW_REGULAR, 0, 0, 0, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
72 CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY, DEFAULT_PITCH, "" };
73 //LOGFONT lf = {m_pImpl->fontSize , 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
74 // CLIP_DEFAULT_PRECIS , PROOF_QUALITY, FIXED_PITCH | FF_MODERN , "" };
75 strcpy_s(lf.lfFaceName , fontName );
77 if(!(m_pImpl->hFont = CreateFontIndirect(&lf))){
78 throw std::runtime_error("Failed --- CreateFontIndirect");
83 mof::Font::Font(const TCHAR* fontName , size_t size, const mof::font_context& context)
84 : m_pImpl(new Impl(fontName, size, context))
86 LOGFONT lf = {m_pImpl->fontSize , 0, 0, 0, FW_REGULAR, 0, 0, 0, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
87 CLIP_DEFAULT_PRECIS , DEFAULT_QUALITY, DEFAULT_PITCH, "" };
88 //LOGFONT lf = {m_pImpl->fontSize , 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
89 // CLIP_DEFAULT_PRECIS , PROOF_QUALITY, FIXED_PITCH | FF_MODERN , "" };
90 strcpy_s(lf.lfFaceName , fontName );
92 if(!(m_pImpl->hFont = CreateFontIndirect(&lf))){
93 throw std::runtime_error("Failed --- CreateFontIndirect");
101 mof::tstring mof::Font::name() const { return m_pImpl->font_name_; }
102 size_t mof::Font::size() const { return m_pImpl->fontSize; }
103 mof::font_context mof::Font::context() const { return m_pImpl->context_; }
105 mof::PixelMap* mof::Font::createText(const mof::tstring& text) const{
107 //
\83f
\83o
\83C
\83X
\83R
\83\93\83e
\83L
\83X
\83g
\8eæ
\93¾
108 //
\83f
\83o
\83C
\83X
\82É
\83t
\83H
\83\93\83g
\82ð
\8e\9d\82½
\82¹
\82È
\82¢
\82ÆGetGlyphOutline
\8aÖ
\90\94\82Í
\83G
\83\89\81[
\82Æ
\82È
\82é
109 HDC hdc = GetDC(NULL);
110 HFONT oldFont = static_cast<HFONT>(SelectObject(hdc , m_pImpl->hFont));
112 GetTextMetrics( hdc, &TM );
116 typedef std::list<GlyphData*>::iterator GDITR;
117 std::list<GlyphData*> glyphDataList;
118 for(int i = 0 ; text.c_str()[i] ; ){
121 //
\95¶
\8e\9a\83R
\81[
\83h
\8eæ
\93¾
124 // unicode
\82Ì
\8fê
\8d\87\81A
\95¶
\8e\9a\83R
\81[
\83h
\82Í
\92P
\8f\83\82É
\83\8f\83C
\83h
\95¶
\8e\9a\82ÌUINT
\95Ï
\8a·
\82Å
\82·
125 code = (UINT)str[i++];
127 //
\83}
\83\8b\83`
\83o
\83C
\83g
\95¶
\8e\9a\82Ì
\8fê
\8d\87\81A
128 // 1
\83o
\83C
\83g
\95¶
\8e\9a\82Ì
\83R
\81[
\83h
\82Í1
\83o
\83C
\83g
\96Ú
\82ÌUINT
\95Ï
\8a·
\81A
129 // 2
\83o
\83C
\83g
\95¶
\8e\9a\82Ì
\83R
\81[
\83h
\82Í[
\90æ
\93±
\83R
\81[
\83h]*256 + [
\95¶
\8e\9a\83R
\81[
\83h]
\82Å
\82·
130 if(IsDBCSLeadByte(text[i])){
131 code = (text[i] << 8) | (text[i+1] & 0xff); //
\95¶
\8e\9a
140 unsigned int spaceCode = (_T(" ")[0]);
141 unsigned int wSpaceCode = (_T("
\81@")[0] << 8) | (_T("
\81@")[1] & 0xff);
142 wSpaceCode &= 0x0000ffff;
145 //
\83t
\83H
\83\93\83g
\83r
\83b
\83g
\83}
\83b
\83v
\8eæ
\93¾
147 CONST MAT2 Mat = {{0,1},{0,0},{0,0},{0,1}};
148 DWORD size = GetGlyphOutline(hdc, code , GGO_GRAY8_BITMAP, &GM, 0, NULL, &Mat);
149 GlyphData* pGD = new GlyphData(GM , TM , 65 , size);
150 GetGlyphOutline(hdc, code, GGO_GRAY8_BITMAP, &GM, size, pGD->pBmpBuffer , &Mat);
152 if(code == spaceCode || code == wSpaceCode){
153 //
\8bó
\94\92\82Í
\89½
\8cÌ
\82©
\82¤
\82Ü
\82
\8f\91\82«
\8d\9e\82ß
\82È
\82¢
\82±
\82Æ
\82Ö
\82Ì
\91Î
\8f\88
156 glyphDataList.push_back(pGD);
157 sumWidth += pGD->width;//
\91S
\91Ì
\82Ì
\95\9d
158 maxHeight = max(maxHeight , TM.tmHeight);
162 //
\83f
\83o
\83C
\83X
\83R
\83\93\83e
\83L
\83X
\83g
\82Æ
\83t
\83H
\83\93\83g
\83n
\83\93\83h
\83\8b\82Ì
\8aJ
\95ú
163 SelectObject(hdc, oldFont);
164 ReleaseDC(NULL, hdc);
166 typedef mof::PixelMap::size_type size_type;
167 boost::array<size_type , 2> sizes = {{ sumWidth , maxHeight }};
168 mof::PixelMap* pPixelMap = new mof::PixelMap(sizes);
170 //
\83t
\83H
\83\93\83g
\8fî
\95ñ
\82Ì
\8f\91\82«
\8d\9e\82Ý
171 // iOfs_x, iOfs_y :
\8f\91\82«
\8fo
\82µ
\88Ê
\92u(
\8d¶
\8fã)
172 // iBmp_w, iBmp_h :
\83t
\83H
\83\93\83g
\83r
\83b
\83g
\83}
\83b
\83v
\82Ì
\95\9d\8d\82
173 // Level :
\83¿
\92l
\82Ì
\92i
\8aK (GGO_GRAY4_BITMAP
\82È
\82Ì
\82Å17
\92i
\8aK)
177 for(int y = 0 ; y < maxHeight ; y++){
178 for(int x = 0 ; x < sumWidth ; x++){
179 (*pPixelMap)[x][y] = 0;
183 mof::Color4f color = context().font_color;
185 mof::Color code = color.toColorCode();
186 for(GDITR itr = glyphDataList.begin() ; itr != glyphDataList.end() ; ++itr){
187 for(int y = (*itr)->iOfs_y; y < (*itr)->iOfs_y + (*itr)->iBmp_h; y++){
188 if(!(*itr)->valid)break;//
\8bó
\94\92\95¶
\8e\9a\82È
\82ç
\8f\91\82«
\8d\9e\82Ý
\82ð
\96³
\8e\8b\82·
\82é
189 for(int x = (*itr)->iOfs_x + hoseiX ; x < (*itr)->iOfs_x + (*itr)->iBmp_w + hoseiX && x < sumWidth ; x++){
190 Alpha = (255 * (*itr)->pBmpBuffer[x - ((*itr)->iOfs_x + hoseiX) + (*itr)->iBmp_w * ( y - (*itr)->iOfs_y ) ] ) / ((*itr)->level-1);
191 //Color = 0x00ffffff | (Alpha<<24);
192 Color = code | (Alpha<<24);
194 (*pPixelMap)[x][y] = Color;
198 hoseiX += (*itr)->width;
206 bool mof::Font::addFontResource(const mof::tstring& filename ){
207 g_fontManager.additionalFontResources.push_back(filename);
208 return AddFontResource( filename.c_str() ) ? true : false ;