OLD | NEW |
1 /* | 1 /* |
2 * $Id$ | 2 * $Id$ |
3 * | 3 * |
4 * ***** BEGIN GPL LICENSE BLOCK ***** | 4 * ***** BEGIN GPL LICENSE BLOCK ***** |
5 * | 5 * |
6 * This program is free software; you can redistribute it and/or | 6 * This program is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU General Public License | 7 * modify it under the terms of the GNU General Public License |
8 * as published by the Free Software Foundation; either version 2 | 8 * as published by the Free Software Foundation; either version 2 |
9 * of the License, or (at your option) any later version. | 9 * of the License, or (at your option) any later version. |
10 * | 10 * |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "KX_Scene.h" | 36 #include "KX_Scene.h" |
37 #include "KX_PythonInit.h" | 37 #include "KX_PythonInit.h" |
38 #include "BLI_math.h" | 38 #include "BLI_math.h" |
39 | 39 |
40 extern "C" { | 40 extern "C" { |
41 #include "BLF_api.h" | 41 #include "BLF_api.h" |
42 } | 42 } |
43 | 43 |
44 #define BGE_FONT_RES 100 | 44 #define BGE_FONT_RES 100 |
45 | 45 |
| 46 std::vector<STR_String> split_string(STR_String str) |
| 47 { |
| 48 std::vector<STR_String> text = std::vector<STR_String>(); |
| 49 |
| 50 /* Split the string upon new lines */ |
| 51 int begin=0, end=0; |
| 52 while (end < str.Length()) |
| 53 { |
| 54 if(str.GetAt(end) == '\n') |
| 55 { |
| 56 text.push_back(str.Mid(begin, end-begin)); |
| 57 begin = end+1; |
| 58 } |
| 59 end++; |
| 60 } |
| 61 //Now grab the last line |
| 62 text.push_back(str.Mid(begin, end-begin)); |
| 63 |
| 64 return text; |
| 65 } |
46 KX_FontObject::KX_FontObject( void* sgReplicationInfo, | 66 KX_FontObject::KX_FontObject( void* sgReplicationInfo, |
47 SG_Callbacks cal
lbacks, | 67 SG_Callbacks cal
lbacks, |
48 RAS_IRenderTools
* rendertools, | 68 RAS_IRenderTools
* rendertools, |
49 Object *ob): | 69 Object *ob): |
50 KX_GameObject(sgReplicationInfo, callbacks), | 70 KX_GameObject(sgReplicationInfo, callbacks), |
51 m_object(ob), | 71 m_object(ob), |
52 m_dpi(72), | 72 m_dpi(72), |
53 m_resolution(1.f), | 73 m_resolution(1.f), |
54 m_rendertools(rendertools) | 74 m_rendertools(rendertools) |
55 { | 75 { |
56 Curve *text = static_cast<Curve *> (ob->data); | 76 Curve *text = static_cast<Curve *> (ob->data); |
57 » m_text = text->str; | 77 » m_text = split_string(text->str); |
58 m_fsize = text->fsize; | 78 m_fsize = text->fsize; |
| 79 m_line_spacing = text->linedist; |
| 80 m_offset = MT_Vector3(text->xof, text->yof, 0); |
59 | 81 |
60 /* FO_BUILTIN_NAME != "default" */ | 82 /* FO_BUILTIN_NAME != "default" */ |
61 /* I hope at some point Blender (2.5x) can have a single font */ | 83 /* I hope at some point Blender (2.5x) can have a single font */ |
62 /* with unicode support for ui and OB_FONT */ | 84 /* with unicode support for ui and OB_FONT */ |
63 /* once we have packed working we can load the FO_BUILTIN_NAME font
*/ | 85 /* once we have packed working we can load the FO_BUILTIN_NAME font
*/ |
64 const char* filepath = text->vfont->name; | 86 const char* filepath = text->vfont->name; |
65 if (strcmp(FO_BUILTIN_NAME, filepath) == 0) | 87 if (strcmp(FO_BUILTIN_NAME, filepath) == 0) |
66 filepath = "default"; | 88 filepath = "default"; |
67 | 89 |
68 /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix
for that. */ | 90 /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix
for that. */ |
(...skipping 21 matching lines...) Expand all Loading... |
90 } | 112 } |
91 | 113 |
92 void KX_FontObject::ProcessReplica() | 114 void KX_FontObject::ProcessReplica() |
93 { | 115 { |
94 KX_GameObject::ProcessReplica(); | 116 KX_GameObject::ProcessReplica(); |
95 KX_GetActiveScene()->AddFont(this); | 117 KX_GetActiveScene()->AddFont(this); |
96 } | 118 } |
97 | 119 |
98 void KX_FontObject::DrawText() | 120 void KX_FontObject::DrawText() |
99 { | 121 { |
| 122 /* Allow for some logic brick control */ |
| 123 if(this->GetProperty("text")) |
| 124 m_text = split_string(this->GetProperty("text")->GetText()); |
| 125 |
100 /* only draws the text if visible */ | 126 /* only draws the text if visible */ |
101 if(this->GetVisible() == 0) return; | 127 if(this->GetVisible() == 0) return; |
102 | 128 |
103 /* update the animated color */ | 129 /* update the animated color */ |
104 this->GetObjectColor().getValue(m_color); | 130 this->GetObjectColor().getValue(m_color); |
105 | 131 |
106 /* XXX 2DO - handle multiple lines */ | |
107 /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolut
ion directly */ | 132 /* HARDCODED MULTIPLICATION FACTOR - this will affect the render resolut
ion directly */ |
108 float RES = BGE_FONT_RES * m_resolution; | 133 float RES = BGE_FONT_RES * m_resolution; |
109 | 134 |
110 float size = m_fsize * m_object->size[0] * RES; | 135 float size = m_fsize * m_object->size[0] * RES; |
111 float aspect = 1.f / (m_object->size[0] * RES); | 136 float aspect = 1.f / (m_object->size[0] * RES); |
112 | 137 |
113 » m_rendertools->RenderText3D(m_fontid, m_text, int(size), m_dpi, m_color,
this->GetOpenGLMatrix(), aspect); | 138 » /* Get a working copy of the OpenGLMatrix to use */ |
| 139 » double mat[16]; |
| 140 » memcpy(mat, this->GetOpenGLMatrix(), sizeof(double)*16); |
| 141 |
| 142 » /* Account for offset */ |
| 143 » MT_Vector3 offset = this->NodeGetWorldOrientation() * m_offset; |
| 144 » mat[12] += offset[0]; mat[13] += offset[1]; mat[14] += offset[2]; |
| 145 |
| 146 » /* Orient the spacing vector */ |
| 147 » MT_Vector3 spacing = MT_Vector3(0, m_fsize*m_line_spacing, 0); |
| 148 » spacing =this->NodeGetWorldOrientation() * spacing; |
| 149 |
| 150 » /* Draw each line, taking spacing into consideration */ |
| 151 » for(int i=0; i<m_text.size(); ++i) |
| 152 » { |
| 153 » » if (i!=0) |
| 154 » » { |
| 155 » » » mat[12] -= spacing[0]; |
| 156 » » » mat[13] -= spacing[1]; |
| 157 » » » mat[14] -= spacing[2]; |
| 158 » » } |
| 159 » » m_rendertools->RenderText3D(m_fontid, m_text[i], int(size), m_dp
i, m_color, mat, aspect); |
| 160 » } |
114 } | 161 } |
115 | 162 |
116 #ifdef WITH_PYTHON | 163 #ifdef WITH_PYTHON |
117 | 164 |
118 /* ------------------------------------------------------------------------- */ | 165 /* ------------------------------------------------------------------------- */ |
119 /* Python Integration Hooks
*/ | 166 /* Python Integration Hooks
*/ |
120 /* ------------------------------------------------------------------------- */ | 167 /* ------------------------------------------------------------------------- */ |
121 | 168 |
122 PyTypeObject KX_FontObject::Type = { | 169 PyTypeObject KX_FontObject::Type = { |
123 PyVarObject_HEAD_INIT(NULL, 0) | 170 PyVarObject_HEAD_INIT(NULL, 0) |
(...skipping 21 matching lines...) Expand all Loading... |
145 &KX_GameObject::Type, | 192 &KX_GameObject::Type, |
146 0,0,0,0,0,0, | 193 0,0,0,0,0,0, |
147 py_base_new | 194 py_base_new |
148 }; | 195 }; |
149 | 196 |
150 PyMethodDef KX_FontObject::Methods[] = { | 197 PyMethodDef KX_FontObject::Methods[] = { |
151 {NULL,NULL} //Sentinel | 198 {NULL,NULL} //Sentinel |
152 }; | 199 }; |
153 | 200 |
154 PyAttributeDef KX_FontObject::Attributes[] = { | 201 PyAttributeDef KX_FontObject::Attributes[] = { |
155 » KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text),
//arbitrary limit. 280 = 140 unicode chars in unicode | 202 » //KX_PYATTRIBUTE_STRING_RW("text", 0, 280, false, KX_FontObject, m_text[
0]), //arbitrary limit. 280 = 140 unicode chars in unicode |
| 203 » KX_PYATTRIBUTE_RW_FUNCTION("text", KX_FontObject, pyattr_get_text, pyatt
r_set_text), |
156 KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsiz
e), | 204 KX_PYATTRIBUTE_FLOAT_RW("size", 0.0001f, 10000.0f, KX_FontObject, m_fsiz
e), |
157 KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject,
m_resolution), | 205 KX_PYATTRIBUTE_FLOAT_RW("resolution", 0.0001f, 10000.0f, KX_FontObject,
m_resolution), |
158 /* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi),
*/// no real need for expose this I think | 206 /* KX_PYATTRIBUTE_INT_RW("dpi", 0, 10000, false, KX_FontObject, m_dpi),
*/// no real need for expose this I think |
159 { NULL } //Sentinel | 207 { NULL } //Sentinel |
160 }; | 208 }; |
161 | 209 |
| 210 PyObject* KX_FontObject::pyattr_get_text(void *self_v, const KX_PYATTRIBUTE_DEF
*attrdef) |
| 211 { |
| 212 KX_FontObject* self= static_cast<KX_FontObject*>(self_v); |
| 213 STR_String str = STR_String(); |
| 214 for(int i=0; i<self->m_text.size(); ++i) |
| 215 { |
| 216 if(i!=0) |
| 217 str += '\n'; |
| 218 str += self->m_text[i]; |
| 219 } |
| 220 return PyUnicode_FromString(str.ReadPtr()); |
| 221 } |
| 222 |
| 223 int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrd
ef, PyObject *value) |
| 224 { |
| 225 KX_FontObject* self= static_cast<KX_FontObject*>(self_v); |
| 226 if(!PyUnicode_Check(value)) |
| 227 return PY_SET_ATTR_FAIL; |
| 228 char* chars = _PyUnicode_AsString(value); |
| 229 self->m_text = split_string(STR_String(chars)); |
| 230 return PY_SET_ATTR_SUCCESS; |
| 231 } |
| 232 |
162 #endif // WITH_PYTHON | 233 #endif // WITH_PYTHON |
OLD | NEW |