1 /*
2  * FTGL - OpenGL font library
3  *
4  * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
5  * Copyright (c) 2008 Sam Hocevar <sam@hocevar.net>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 #include "config.h"
28 
29 #include "FTGL/ftgl.h"
30 
31 #include "FTInternals.h"
32 #include "FTPixmapFontImpl.h"
33 #include "FTGL/FTLibrary.h"
34 
35 
36 //
37 //  FTPixmapFont
38 //
39 
40 
FTPixmapFont(char const * fontFilePath)41 FTPixmapFont::FTPixmapFont(char const *fontFilePath) :
42     FTFont(new FTPixmapFontImpl(this, fontFilePath))
43 {}
44 
45 
FTPixmapFont(const unsigned char * pBufferBytes,size_t bufferSizeInBytes)46 FTPixmapFont::FTPixmapFont(const unsigned char *pBufferBytes,
47                            size_t bufferSizeInBytes) :
48     FTFont(new FTPixmapFontImpl(this, pBufferBytes, bufferSizeInBytes))
49 {}
50 
51 
~FTPixmapFont()52 FTPixmapFont::~FTPixmapFont()
53 {}
54 
55 
MakeGlyph(FT_GlyphSlot ftGlyph)56 FTGlyph* FTPixmapFont::MakeGlyph(FT_GlyphSlot ftGlyph)
57 {
58     return new FTPixmapGlyph(ftGlyph);
59 }
60 
61 
62 //
63 //  FTPixmapFontImpl
64 //
65 
66 
FTPixmapFontImpl(FTFont * ftFont,const char * fontFilePath)67 FTPixmapFontImpl::FTPixmapFontImpl(FTFont *ftFont, const char* fontFilePath)
68 : FTFontImpl(ftFont, fontFilePath)
69 {
70     load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
71 }
72 
73 
FTPixmapFontImpl(FTFont * ftFont,const unsigned char * pBufferBytes,size_t bufferSizeInBytes)74 FTPixmapFontImpl::FTPixmapFontImpl(FTFont *ftFont,
75                                    const unsigned char *pBufferBytes,
76                                    size_t bufferSizeInBytes)
77 : FTFontImpl(ftFont, pBufferBytes, bufferSizeInBytes)
78 {
79     load_flags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP;
80 }
81 
82 
83 template <typename T>
RenderI(const T * string,const int len,FTPoint position,FTPoint spacing,int renderMode)84 inline FTPoint FTPixmapFontImpl::RenderI(const T* string, const int len,
85                                          FTPoint position, FTPoint spacing,
86                                          int renderMode)
87 {
88     // Protect GL_TEXTURE_2D, glPixelTransferf() and optionally GL_BLEND
89     glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT
90                   | GL_POLYGON_BIT);
91 
92     // Protect glPixelStorei() calls (made by FTPixmapGlyphImpl::RenderImpl).
93     glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
94 
95     // Needed on OSX
96     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
97 
98     if(FTLibrary::Instance().GetLegacyOpenGLStateSet())
99       {
100         glEnable(GL_BLEND);
101         /*
102          * Note: This is the historic legacy behaviour.
103          *
104          * A better blending function (see
105          * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=742469) is:
106          *
107          *   glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
108          *                       GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
109          *
110          * To use it, set
111          *
112          *   FTLibrary::Instance().LegacyOpenGLState(false);
113          *
114          * and set GL_BLEND and the blending function yourself.
115          */
116         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
117       }
118 
119     glDisable(GL_TEXTURE_2D);
120 
121     GLfloat ftglColour[4];
122     glGetFloatv(GL_CURRENT_RASTER_COLOR, ftglColour);
123 
124     glPixelTransferf(GL_RED_SCALE, ftglColour[0]);
125     glPixelTransferf(GL_GREEN_SCALE, ftglColour[1]);
126     glPixelTransferf(GL_BLUE_SCALE, ftglColour[2]);
127     glPixelTransferf(GL_ALPHA_SCALE, ftglColour[3]);
128 
129     FTPoint tmp = FTFontImpl::Render(string, len,
130                                      position, spacing, renderMode);
131 
132     glPopClientAttrib();
133     glPopAttrib();
134 
135     return tmp;
136 }
137 
138 
Render(const char * string,const int len,FTPoint position,FTPoint spacing,int renderMode)139 FTPoint FTPixmapFontImpl::Render(const char * string, const int len,
140                                  FTPoint position, FTPoint spacing,
141                                  int renderMode)
142 {
143     return RenderI(string, len, position, spacing, renderMode);
144 }
145 
146 
Render(const wchar_t * string,const int len,FTPoint position,FTPoint spacing,int renderMode)147 FTPoint FTPixmapFontImpl::Render(const wchar_t * string, const int len,
148                                  FTPoint position, FTPoint spacing,
149                                  int renderMode)
150 {
151     return RenderI(string, len, position, spacing, renderMode);
152 }
153 
154