1 /*
2 * FTGL - OpenGL font library
3 *
4 * Copyright (c) 2008 Sam Hocevar <sam@zoy.org>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #include "../config.h"
27
28 #include <string>
29
30 #include "FTGL/ftgl.h"
31
32 #include "../FTInternals.h"
33 #include "FTBufferGlyphImpl.h"
34
35
36 //
37 // FTGLBufferGlyph
38 //
39
40
FTBufferGlyph(FT_GlyphSlot glyph,FTBuffer * buffer)41 FTBufferGlyph::FTBufferGlyph(FT_GlyphSlot glyph, FTBuffer *buffer) :
42 FTGlyph(new FTBufferGlyphImpl(glyph, buffer))
43 {}
44
45
~FTBufferGlyph()46 FTBufferGlyph::~FTBufferGlyph()
47 {}
48
49
Render(const FTPoint & pen,int renderMode)50 const FTPoint& FTBufferGlyph::Render(const FTPoint& pen, int renderMode)
51 {
52 FTBufferGlyphImpl *myimpl = dynamic_cast<FTBufferGlyphImpl *>(impl);
53 return myimpl->RenderImpl(pen, renderMode);
54 }
55
56
57 //
58 // FTGLBufferGlyphImpl
59 //
60
61
FTBufferGlyphImpl(FT_GlyphSlot glyph,FTBuffer * p)62 FTBufferGlyphImpl::FTBufferGlyphImpl(FT_GlyphSlot glyph, FTBuffer *p)
63 : FTGlyphImpl(glyph),
64 has_bitmap(false),
65 buffer(p)
66 {
67 err = FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL);
68 if(err || glyph->format != ft_glyph_format_bitmap)
69 {
70 return;
71 }
72
73 bitmap = glyph->bitmap;
74 pixels = new unsigned char[bitmap.pitch * bitmap.rows];
75 memcpy(pixels, bitmap.buffer, bitmap.pitch * bitmap.rows);
76
77 if(bitmap.width && bitmap.rows)
78 {
79 has_bitmap = true;
80 corner = FTPoint(glyph->bitmap_left, glyph->bitmap_top);
81 }
82 }
83
84
~FTBufferGlyphImpl()85 FTBufferGlyphImpl::~FTBufferGlyphImpl()
86 {
87 delete[] pixels;
88 }
89
90
RenderImpl(const FTPoint & pen,int renderMode)91 const FTPoint& FTBufferGlyphImpl::RenderImpl(const FTPoint& pen, int renderMode)
92 {
93 if(has_bitmap)
94 {
95 FTPoint pos(buffer->Pos() + pen + corner);
96 int dx = (int)(pos.Xf() + 0.5f);
97 int dy = buffer->Height() - (int)(pos.Yf() + 0.5f);
98 unsigned char * dest = buffer->Pixels() + dx + dy * buffer->Width();
99
100 for(int y = 0; y < bitmap.rows; y++)
101 {
102 // FIXME: change the loop bounds instead of doing this test
103 if(y + dy < 0 || y + dy >= buffer->Height()) continue;
104
105 for(int x = 0; x < bitmap.width; x++)
106 {
107 if(x + dx < 0 || x + dx >= buffer->Width()) continue;
108
109 unsigned char p = pixels[y * bitmap.pitch + x];
110
111 if(p)
112 {
113 dest[y * buffer->Width() + x] = p;
114 }
115 }
116 }
117 }
118
119 return advance;
120 }
121
122