OSDN Git Service

rm latex/
[moflib/moflib.git] / oldmof / Font.cpp
1 #include "mof/Font.hpp"
2 #include <list>
3 #include <windows.h>
4 #include "mof/ConsoleIO.hpp"
5 #include <vector>
6 #include "mof/utilities.hpp"
7
8 const TCHAR* mof::Font::MS_GOTHIC = _T("\82l\82\83S\83V\83b\83N");
9 const TCHAR* mof::Font::MS_P_GOTHIC = _T("\82l\82\82o\83S\83V\83b\83N");
10
11
12 namespace
13 {
14     struct FontManager 
15     {
16         std::vector<mof::tstring> additionalFontResources;
17         
18         ~FontManager()
19         {
20             foreach( mof::tstring& filename , additionalFontResources )
21             {
22                 RemoveFontResource( filename.c_str() );
23             }
24         }
25     } g_fontManager;
26 }
27
28 struct GlyphData{
29     int iOfs_x , iOfs_y , iBmp_w , iBmp_h , level , width;
30     BYTE* pBmpBuffer;
31     bool valid;
32
33    GlyphData(GLYPHMETRICS& GM , TEXTMETRIC& TM , int _level , int bufSize){
34         iOfs_x = GM.gmptGlyphOrigin.x;
35         iOfs_y = TM.tmAscent - GM.gmptGlyphOrigin.y;
36         iBmp_w = GM.gmBlackBoxX + (4-(GM.gmBlackBoxX%4))%4;
37         iBmp_h = GM.gmBlackBoxY;
38         level = _level;
39         width =  GM.gmCellIncX;
40         pBmpBuffer = new BYTE[bufSize];
41         valid = true;
42    }
43
44    ~GlyphData(){
45         delete[] pBmpBuffer;
46    }
47 };
48
49 struct mof::Font::Impl{
50     HFONT hFont;
51     size_t fontSize;
52
53     Impl(size_t fontSize_)
54         : hFont(NULL) ,fontSize(fontSize_)
55     {
56     }
57
58     ~Impl(){
59         DeleteObject(hFont);
60     }
61
62 };
63
64 mof::Font::Font(const TCHAR* fontName , size_t size)
65 : m_pImpl(new Impl(size))
66 {
67     LOGFONT lf = {m_pImpl->fontSize , 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
68         CLIP_DEFAULT_PRECIS , PROOF_QUALITY, FIXED_PITCH | FF_MODERN , "" };
69     strcpy_s(lf.lfFaceName , fontName );
70
71     if(!(m_pImpl->hFont = CreateFontIndirect(&lf))){
72        throw std::runtime_error("Failed --- CreateFontIndirect");
73     }
74
75     
76
77 }
78
79 mof::Font::~Font(){
80     
81 }
82
83    
84
85 mof::PixelMap* mof::Font::createText(const mof::tstring& text) const{
86
87     // \83f\83o\83C\83X\83R\83\93\83e\83L\83X\83g\8eæ\93¾
88     // \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é
89     HDC hdc = GetDC(NULL);
90     HFONT oldFont = static_cast<HFONT>(SelectObject(hdc , m_pImpl->hFont));
91     TEXTMETRIC TM;
92     GetTextMetrics( hdc, &TM );
93
94     int sumWidth = 0;
95     int maxHeight = 0;
96     typedef std::list<GlyphData*>::iterator GDITR;
97     std::list<GlyphData*> glyphDataList;
98     for(int i = 0 ; text.c_str()[i] ; ){
99
100
101         // \95\8e\9a\83R\81[\83h\8eæ\93¾
102         UINT code = 0;
103         #if _UNICODE
104             // 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·
105             code = (UINT)str[i++];
106         #else
107             // \83}\83\8b\83`\83o\83C\83g\95\8e\9a\82Ì\8fê\8d\87\81A
108             // 1\83o\83C\83g\95\8e\9a\82Ì\83R\81[\83h\82Í1\83o\83C\83g\96Ú\82ÌUINT\95Ï\8a·\81A
109             // 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·
110             if(IsDBCSLeadByte(text[i])){
111                 code = (text[i] << 8) | (text[i+1] & 0xff); // \95\8e\9a
112                 code &= 0x0000ffff;
113                 i += 2;
114             }
115             else{
116                 code = text[i++];
117             }
118         #endif
119
120         unsigned int spaceCode = (_T(" ")[0]);
121         unsigned int wSpaceCode = (_T("\81@")[0] << 8) | (_T("\81@")[1] & 0xff);
122         wSpaceCode &= 0x0000ffff;
123
124
125         // \83t\83H\83\93\83g\83r\83b\83g\83}\83b\83v\8eæ\93¾
126         GLYPHMETRICS GM;
127         CONST MAT2 Mat = {{0,1},{0,0},{0,0},{0,1}};
128         DWORD size = GetGlyphOutline(hdc, code , GGO_GRAY8_BITMAP, &GM, 0, NULL, &Mat);
129         GlyphData* pGD = new GlyphData(GM , TM , 65 , size);
130         GetGlyphOutline(hdc, code, GGO_GRAY8_BITMAP, &GM, size, pGD->pBmpBuffer , &Mat);
131
132         if(code == spaceCode || code == wSpaceCode){
133             //\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
134             pGD->valid = false;
135         }
136         glyphDataList.push_back(pGD);
137         sumWidth += pGD->width;//\91S\91Ì\82Ì\95\9d
138         maxHeight = max(maxHeight , TM.tmHeight);
139     }
140     
141     // \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ú
142     SelectObject(hdc, oldFont);
143     ReleaseDC(NULL, hdc);
144
145     typedef mof::PixelMap::size_type size_type;
146     boost::array<size_type , 2> sizes = {{ sumWidth , maxHeight }};
147     mof::PixelMap* pPixelMap = new mof::PixelMap(sizes);
148
149     // \83t\83H\83\93\83g\8fî\95ñ\82Ì\8f\91\82«\8d\9e\82Ý
150     // iOfs_x, iOfs_y : \8f\91\82«\8fo\82µ\88Ê\92u(\8d\8fã)
151     // iBmp_w, iBmp_h : \83t\83H\83\93\83g\83r\83b\83g\83}\83b\83v\82Ì\95\9d\8d\82
152     // Level : \83¿\92l\82Ì\92i\8aK (GGO_GRAY4_BITMAP\82È\82Ì\82Å17\92i\8aK)
153
154     DWORD Alpha, Color;
155     int hoseiX = 0;
156     for(int y = 0 ; y < maxHeight ; y++){
157         for(int x = 0 ; x < sumWidth ; x++){
158             (*pPixelMap)[x][y] = 0;
159         }
160     }
161     for(GDITR itr = glyphDataList.begin() ; itr != glyphDataList.end() ; ++itr){
162        for(int y = (*itr)->iOfs_y ;  y < (*itr)->iOfs_y + (*itr)->iBmp_h ;  y++){
163             if(!(*itr)->valid)break;//\8bó\94\92\95\8e\9a\82È\82ç\8f\91\82«\8d\9e\82Ý\82ð\96³\8e\8b\82·\82é
164             for(int x = (*itr)->iOfs_x + hoseiX ; x < (*itr)->iOfs_x + (*itr)->iBmp_w + hoseiX && x < sumWidth ;  x++){
165                 Alpha = (255 * (*itr)->pBmpBuffer[x - ((*itr)->iOfs_x + hoseiX) + (*itr)->iBmp_w * ( y - (*itr)->iOfs_y ) ] ) / ((*itr)->level-1);
166                 Color = 0x00ffffff | (Alpha<<24);
167                 
168                 (*pPixelMap)[x][y] = Color;
169                 
170             }
171        }
172        hoseiX += (*itr)->width;
173        delete *itr;
174    }
175
176     return pPixelMap;
177 }
178
179
180 bool mof::Font::addFontResource(const mof::tstring& filename ){
181     g_fontManager.additionalFontResources.push_back(filename);
182     return AddFontResource( filename.c_str() ) ? true : false ;
183 }