xoreos  0.0.5
abcfont.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/scopedptr.h"
26 #include "src/common/ustring.h"
27 #include "src/common/error.h"
28 #include "src/common/readstream.h"
29 
30 #include "src/aurora/resman.h"
31 
35 
38 
39 namespace Graphics {
40 
41 namespace Aurora {
42 
43 ABCFont::ABCFont(const Common::UString &name) : _base(0) {
44  _texture = TextureMan.get(name);
45 
46  load(name);
47 
48  _mesh = static_cast<Mesh::MeshFont *>(MeshMan.getMesh("defaultMeshFont"));
49  _material = new Shader::ShaderMaterial(ShaderMan.getShaderObject("default/text.frag", Shader::SHADER_FRAGMENT), "text");
50  Shader::ShaderSampler *sampler;
51  sampler = (Shader::ShaderSampler *)(_material->getVariableData("sampler_0_id"));
52  sampler->handle = _texture;
53  _renderable = new Shader::ShaderRenderable(SurfaceMan.getSurface("textSurface"), _material, _mesh);
54 }
55 
57  delete _renderable;
58  delete _material;
59 }
60 
61 float ABCFont::getHeight() const {
62  return 32.0f;
63 }
64 
65 float ABCFont::getWidth(uint32 c) const {
66  const Char &cC = findChar(c);
67 
68  return cC.spaceL + cC.width + cC.spaceR;
69 }
70 
71 void ABCFont::draw(uint32 c) const {
72  TextureMan.set(_texture);
73 
74  const Char &cC = findChar(c);
75 
76  glTranslatef(cC.spaceL, 0.0f, 0.0f);
77 
78  glBegin(GL_QUADS);
79  for (int i = 0; i < 4; i++) {
80  glTexCoord2f(cC.tX[i], cC.tY[i]);
81  glVertex2f (cC.vX[i], cC.vY[i]);
82  }
83  glEnd();
84 
85  glTranslatef(cC.width + cC.spaceR, 0.0f, 0.0f);
86 }
87 
88 void ABCFont::renderBind(const glm::mat4 &transform) const {
89  glUseProgram(_renderable->getProgram()->glid);
94  _mesh->renderBind();
95 }
96 
97 void ABCFont::render(uint32 c, float &x, float &y, float *rgba) const {
98  const Char &cC = findChar(c);
99 
100  x += cC.spaceL;
101 
102  float v_pos[12];
103  float v_uv[8];
104  float v_rgba[4*4];
105 
106  for (int i = 0; i < 4; ++i) {
107  v_uv[i*2] = cC.tX[i];
108  v_uv[i*2 +1] = cC.tY[i];
109  v_pos[i*3] = x + cC.vX[i];
110  v_pos[i*3 +1] = y + cC.vY[i];
111  v_pos[i*3 +2] = 0.0f;
112  v_rgba[i*4] = rgba[0];
113  v_rgba[i*4 +1] = rgba[1];
114  v_rgba[i*4 +2] = rgba[2];
115  v_rgba[i*4 +3] = rgba[3];
116  }
117  _mesh->render(v_pos, v_uv, v_rgba);
118  x += cC.width + cC.spaceR;
119 }
120 
121 void ABCFont::renderUnbind() const {
122  _mesh->renderUnbind();
123 
126  glUseProgram(0);
127 }
128 
129 void ABCFont::load(const Common::UString &name) {
131  if (!abc)
132  throw Common::Exception("No such font \"%s\"", name.c_str());
133 
134  // Init the invalid char
135  _invalid.dataX = 0;
136  _invalid.dataY = 0;
137  _invalid.width = 0;
138  _invalid.spaceL = 0;
139  _invalid.spaceR = 0;
140 
141  _invalid.tX[0] = 0.0f; _invalid.tY[0] = 0.0f;
142  _invalid.tX[1] = 0.0f; _invalid.tY[1] = 0.0f;
143  _invalid.tX[2] = 0.0f; _invalid.tY[2] = 0.0f;
144  _invalid.tX[3] = 0.0f; _invalid.tY[3] = 0.0f;
145  _invalid.vX[0] = 0.0f; _invalid.vY[0] = 0.0f;
146  _invalid.vX[1] = 0.0f; _invalid.vY[1] = 0.0f;
147  _invalid.vX[2] = 0.0f; _invalid.vY[2] = 0.0f;
148  _invalid.vX[3] = 0.0f; _invalid.vY[3] = 0.0f;
149 
150  bool hasInvalid = false;
151 
152  if (abc->size() != 524280)
153  throw Common::Exception("Invalid font (%u)", (uint)abc->size());
154 
155  _base = abc->readByte();
156 
157  abc->skip(7); // Probably random garbage
158 
159  // Read the ASCII character
160  for (int i = 1; i < 128; i++) {
161  Char &c = _ascii[i];
162 
163  readCharDesc(c, *abc);
164  calcCharVertices(c);
165 
166  // Points to the "invalid character"
167  if (!hasInvalid && (c.dataX == 0) && (c.dataY == 0)) {
168  _invalid = c;
169  hasInvalid = true;
170  }
171  }
172 
173  // Read the UTF16 extended characters
174  for (int i = 128; i < 65535; i++) {
175  Char c;
176 
177  readCharDesc(c, *abc);
178 
179  // Points to the "invalid character"
180  if ((c.dataX == 0) && (c.dataY == 0)) {
181  if (!hasInvalid) {
182  calcCharVertices(c);
183  _invalid = c;
184  hasInvalid = true;
185  }
186 
187  continue;
188  }
189 
190  calcCharVertices(c);
191  _extended.insert(std::make_pair(Common::UString::fromUTF16((uint16) i), c));
192  }
193 }
194 
196  uint32 offset = abc.readUint32LE();
197  byte plane = abc.readByte();
198 
199  c.spaceL = abc.readByte();
200  c.width = abc.readByte();
201  c.spaceR = abc.readByte();
202 
203  if (((offset % 1024) != 0) || (plane > 3))
204  throw Common::Exception("Invalid char data (%d, %d)", offset, plane);
205 
206  c.dataX = plane * 32;
207  c.dataY = (offset / 1024) * 32;
208 }
209 
211  const float w = _texture.getTexture().getWidth();
212  const float h = _texture.getTexture().getHeight();
213 
214  const float vW = c.width;
215  const float vH = 32.0f;
216  const float tW = vW / w;
217  const float tH = vH / h;
218 
219  const float tX = c.dataX / w;
220  const float tY = c.dataY / h;
221 
222  c.tX[0] = tX ; c.tY[0] = tY + tH;
223  c.tX[1] = tX + tW; c.tY[1] = tY + tH;
224  c.tX[2] = tX + tW; c.tY[2] = tY ;
225  c.tX[3] = tX ; c.tY[3] = tY ;
226 
227  c.vX[0] = 0.0f ; c.vY[0] = 0.0f ;
228  c.vX[1] = 0.0f + vW; c.vY[1] = 0.0f ;
229  c.vX[2] = 0.0f + vW; c.vY[2] = 0.0f + vH;
230  c.vX[3] = 0.0f ; c.vY[3] = 0.0f + vH;
231 }
232 
235  return _ascii[c];
236 
237  std::map<uint32, Char>::const_iterator ch = _extended.find(c);
238  if (ch == _extended.end())
239  return _invalid;
240 
241  return ch->second;
242 }
243 
244 } // End of namespace Aurora
245 
246 } // End of namespace Graphics
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
void render(float *pos, float *uv, float *rgba)
Dynamic data prior to render call.
Definition: meshfont.cpp:96
virtual void render(uint32 c, float &x, float &y, float *rgba) const
Definition: abcfont.cpp:97
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
A class holding an UTF-8 string.
Definition: ustring.h:48
#define TextureMan
Shortcut for accessing the texture manager.
Definition: textureman.h:127
#define SurfaceMan
Shortcut for accessing the shader manager.
Definition: surfaceman.h:74
void * getVariableData(uint32 index) const
The Aurora texture manager.
uint32 getHeight() const
Definition: texture.cpp:80
std::map< uint32, Char > _extended
Definition: abcfont.h:91
void calcCharVertices(Char &c)
Definition: abcfont.cpp:210
Exception that provides a stack of explanations.
Definition: error.h:36
A simple scoped smart pointer template.
An ABC/SBM font, as used by Jade Empire.
ABCFont(const Common::UString &name)
Definition: abcfont.cpp:43
void bindProgram(Shader::ShaderProgram *program)
Shader::ShaderRenderable * _renderable
Definition: abcfont.h:85
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
Graphics::Aurora::TextureHandle handle
Definition: shader.h:176
uint16_t uint16
Definition: types.h:202
void readCharDesc(Char &c, Common::SeekableReadStream &abc)
Definition: abcfont.cpp:195
void load(const Common::UString &name)
Definition: abcfont.cpp:129
void renderUnbind()
Definition: mesh.cpp:227
Mesh::MeshFont * _mesh
Definition: abcfont.h:83
The global shader surface manager.
The global mesh manager.
StackException Exception
Definition: error.h:59
void bindProgram(Shader::ShaderProgram *program)
const Char & findChar(uint32 c) const
Definition: abcfont.cpp:233
Basic reading stream interfaces.
Shader::ShaderMaterial * _material
Definition: abcfont.h:84
uint32 getWidth() const
Definition: texture.cpp:76
void renderBind()
Follows the steps of renderImmediate, but broken into different functions.
Definition: mesh.cpp:177
Unicode string handling.
#define MeshMan
Shortcut for accessing the shader manager.
Definition: meshman.h:74
Shader sampler is used to bind a texture to a texture unit.
Definition: shader.h:174
virtual void renderUnbind() const
Definition: abcfont.cpp:121
static bool isASCII(uint32 c)
Is the character an ASCII character?
Definition: ustring.cpp:785
A texture as used in the Aurora engines.
A font character.
Definition: abcfont.h:71
#define ShaderMan
Shortcut for accessing the shader manager.
Definition: shader.h:293
uint32_t uint32
Definition: types.h:204
Font, character descriptions.
Definition: types.h:334
float getHeight() const
Return the height of a character.
Definition: abcfont.cpp:61
virtual void renderBind(const glm::mat4 &transform) const
Bind the font for rendering.
Definition: abcfont.cpp:88
void draw(uint32 c) const
Draw this character.
Definition: abcfont.cpp:71
Interface for a seekable & readable data stream.
Definition: readstream.h:265
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
The global resource manager for Aurora resources.
uint8 byte
Definition: types.h:209
float getWidth(uint32 c) const
Return the width of a character.
Definition: abcfont.cpp:65
unsigned int uint
Definition: types.h:211
TextureHandle _texture
Definition: abcfont.h:82
static uint32 fromUTF16(uint16 c)
Definition: ustring.cpp:809