cucumber merge, multiline font object:

revisions: 38384,38387,38403,38404,38407,42997,42998

#42998 by dfelinto
BGE Font Object - fix for offset
(scaling also has to be taken into account here)

#42997 by dfelinto
Font Object Multiline fix.
The offset was totally wrong when object had scale[1] != 1

#38407 by kupoman
Changing the "text" property of a KX_FontObject now changes the text. This allows for control of a FontObject through logic bricks.

#38404 by kupoman
KX_FontObject now supports the x and y offset options.

#38403 by kupoman
KX_FontObject now makes use of the font's line spacing option, and correctly accounts for rotation and font size when applying the spacing.

#38387 by kupoman
The KX_FontObject text attribute is working again.

#38384 by kupoman
Primitive support for the new line character added to KX_FontObjects. The line spacing is fixed, and does not work when the FontObject is rotated. Also, the text attribute has been temporarily disabled, as it needs some updating to support the multiline changes.
This commit is contained in:
Dalai Felinto 2011-12-30 12:28:51 +00:00
parent 2c43f99c0a
commit c52f780021
2 changed files with 80 additions and 5 deletions

@ -41,6 +41,26 @@ extern "C" {
#define BGE_FONT_RES 100
std::vector<STR_String> split_string(STR_String str)
{
std::vector<STR_String> text = std::vector<STR_String>();
/* Split the string upon new lines */
int begin=0, end=0;
while (end < str.Length())
{
if(str.GetAt(end) == '\n')
{
text.push_back(str.Mid(begin, end-begin));
begin = end+1;
}
end++;
}
//Now grab the last line
text.push_back(str.Mid(begin, end-begin));
return text;
}
KX_FontObject::KX_FontObject( void* sgReplicationInfo,
SG_Callbacks callbacks,
RAS_IRenderTools* rendertools,
@ -52,8 +72,10 @@ KX_FontObject::KX_FontObject( void* sgReplicationInfo,
m_rendertools(rendertools)
{
Curve *text = static_cast<Curve *> (ob->data);
m_text = text->str;
m_text = split_string(text->str);
m_fsize = text->fsize;
m_line_spacing = text->linedist;
m_offset = MT_Vector3(text->xof, text->yof, 0);
/* FO_BUILTIN_NAME != "default" */
/* I hope at some point Blender (2.5x) can have a single font */
@ -95,20 +117,45 @@ void KX_FontObject::ProcessReplica()
void KX_FontObject::DrawText()
{
/* Allow for some logic brick control */
if(this->GetProperty("text"))
m_text = split_string(this->GetProperty("text")->GetText());
/* only draws the text if visible */
if(this->GetVisible() == 0) return;
/* update the animated color */
this->GetObjectColor().getValue(m_color);
/* XXX 2DO - handle multiple lines */
/* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolution directly */
float RES = BGE_FONT_RES * m_resolution;
float size = m_fsize * m_object->size[0] * RES;
float aspect = 1.f / (m_object->size[0] * RES);
m_rendertools->RenderText3D(m_fontid, m_text, int(size), m_dpi, m_color, this->GetOpenGLMatrix(), aspect);
/* Get a working copy of the OpenGLMatrix to use */
double mat[16];
memcpy(mat, this->GetOpenGLMatrix(), sizeof(double)*16);
/* Account for offset */
MT_Vector3 offset = this->NodeGetWorldOrientation() * m_offset * this->NodeGetWorldScaling();
mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2];
/* Orient the spacing vector */
MT_Vector3 spacing = MT_Vector3(0, m_fsize*m_line_spacing, 0);
spacing = this->NodeGetWorldOrientation() * spacing * this->NodeGetWorldScaling()[1];
/* Draw each line, taking spacing into consideration */
for(int i=0; i<m_text.size(); ++i)
{
if (i!=0)
{
mat[12] -= spacing[0];
mat[13] -= spacing[1];
mat[14] -= spacing[2];
}
m_rendertools->RenderText3D(m_fontid, m_text[i], int(size), m_dpi, m_color, mat, aspect);
}
}
#ifdef WITH_PYTHON
@ -150,11 +197,35 @@ PyMethodDef KX_FontObject::Methods[] = {
};
PyAttributeDef KX_FontObject::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text), //arbitrary limit. 280 = 140 unicode chars in unicode
//KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text[0]), //arbitrary limit. 280 = 140 unicode chars in unicode
KX_PYATTRIBUTE_RW_FUNCTION("text", KX_FontObject, pyattr_get_text, pyattr_set_text),
KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsize),
KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject, m_resolution),
/* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi), */// no real need for expose this I think
{ NULL } //Sentinel
};
PyObject* KX_FontObject::pyattr_get_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
{
KX_FontObject* self= static_cast<KX_FontObject*>(self_v);
STR_String str = STR_String();
for(int i=0; i<self->m_text.size(); ++i)
{
if(i!=0)
str += '\n';
str += self->m_text[i];
}
return PyUnicode_FromString(str.ReadPtr());
}
int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
{
KX_FontObject* self= static_cast<KX_FontObject*>(self_v);
if(!PyUnicode_Check(value))
return PY_SET_ATTR_FAIL;
char* chars = _PyUnicode_AsString(value);
self->m_text = split_string(STR_String(chars));
return PY_SET_ATTR_SUCCESS;
}
#endif // WITH_PYTHON

@ -57,13 +57,15 @@ public:
virtual void ProcessReplica();
protected:
STR_String m_text;
std::vector<STR_String> m_text;
Object* m_object;
int m_fontid;
int m_dpi;
float m_fsize;
float m_resolution;
float m_color[4];
float m_line_spacing;
MT_Vector3 m_offset;
class RAS_IRenderTools* m_rendertools; //needed for drawing routine
@ -76,6 +78,8 @@ public:
*/
#ifdef WITH_PYTHON
static PyObject* pyattr_get_text(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef);
static int pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
#endif
};