1 /*
2  * FTGL - OpenGL font library
3  *
4  * Copyright (c) 2001-2004 Henry Maddocks <ftgl@opengl.geek.nz>
5  * Copyright (c) 2008 Éric Beets <ericbeets@free.fr>
6  * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining
9  * a copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be
17  * included in all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #include "../config.h"
29 
30 #include "FTGL/ftgl.h"
31 
32 #include "../FTInternals.h"
33 #include "FTOutlineGlyphImpl.h"
34 #include "../FTVectoriser.h"
35 
36 
37 //
38 //  FTGLOutlineGlyph
39 //
40 
41 
FTOutlineGlyph(FT_GlyphSlot glyph,float outset,bool useDisplayList)42 FTOutlineGlyph::FTOutlineGlyph(FT_GlyphSlot glyph, float outset,
43                                bool useDisplayList) :
44     FTGlyph(new FTOutlineGlyphImpl(glyph, outset, useDisplayList))
45 {}
46 
47 
~FTOutlineGlyph()48 FTOutlineGlyph::~FTOutlineGlyph()
49 {}
50 
51 
Render(const FTPoint & pen,int renderMode)52 const FTPoint& FTOutlineGlyph::Render(const FTPoint& pen, int renderMode)
53 {
54     FTOutlineGlyphImpl *myimpl = dynamic_cast<FTOutlineGlyphImpl *>(impl);
55     return myimpl->RenderImpl(pen, renderMode);
56 }
57 
58 
59 //
60 //  FTGLOutlineGlyphImpl
61 //
62 
63 
FTOutlineGlyphImpl(FT_GlyphSlot glyph,float _outset,bool useDisplayList)64 FTOutlineGlyphImpl::FTOutlineGlyphImpl(FT_GlyphSlot glyph, float _outset,
65                                        bool useDisplayList)
66 :   FTGlyphImpl(glyph),
67     glList(0)
68 {
69     if(ft_glyph_format_outline != glyph->format)
70     {
71         err = 0x14; // Invalid_Outline
72         return;
73     }
74 
75     vectoriser = new FTVectoriser(glyph);
76 
77     if((vectoriser->ContourCount() < 1) || (vectoriser->PointCount() < 3))
78     {
79         delete vectoriser;
80         vectoriser = NULL;
81         return;
82     }
83 
84     outset = _outset;
85 
86     if(useDisplayList)
87     {
88         glList = glGenLists(1);
89         glNewList(glList, GL_COMPILE);
90 
91         DoRender();
92 
93         glEndList();
94 
95         delete vectoriser;
96         vectoriser = NULL;
97     }
98 }
99 
100 
~FTOutlineGlyphImpl()101 FTOutlineGlyphImpl::~FTOutlineGlyphImpl()
102 {
103     if(glList)
104     {
105         glDeleteLists(glList, 1);
106     }
107     else if(vectoriser)
108     {
109         delete vectoriser;
110     }
111 }
112 
113 
RenderImpl(const FTPoint & pen,int renderMode)114 const FTPoint& FTOutlineGlyphImpl::RenderImpl(const FTPoint& pen,
115                                               int renderMode)
116 {
117     glTranslatef(pen.Xf(), pen.Yf(), pen.Zf());
118     if(glList)
119     {
120         glCallList(glList);
121     }
122     else if(vectoriser)
123     {
124         DoRender();
125     }
126     glTranslatef(-pen.Xf(), -pen.Yf(), -pen.Zf());
127 
128     return advance;
129 }
130 
131 
DoRender()132 void FTOutlineGlyphImpl::DoRender()
133 {
134     for(unsigned int c = 0; c < vectoriser->ContourCount(); ++c)
135     {
136         const FTContour* contour = vectoriser->Contour(c);
137 
138         glBegin(GL_LINE_LOOP);
139             for(unsigned int i = 0; i < contour->PointCount(); ++i)
140             {
141                 FTPoint point = FTPoint(contour->Point(i).X() + contour->Outset(i).X() * outset,
142                                         contour->Point(i).Y() + contour->Outset(i).Y() * outset,
143                                         0);
144                 glVertex2f(point.Xf() / 64.0f, point.Yf() / 64.0f);
145             }
146         glEnd();
147     }
148 }
149 
150