35 m_glyphHeight = fontNode->
valueAt<
int>(
"height");
36 m_yOffset = fontNode->
valueAt(
"y-offset", 0);
37 m_firstGlyph = fontNode->
valueAt(
"first-glyph", 32);
38 m_glyphSpacing = fontNode->
valueAt(
"spacing",
Size(0,0));
39 int spaceWidth = fontNode->
valueAt(
"space-width", glyphSize.
width());
45 for(
int glyph = m_firstGlyph; glyph < 256; ++glyph)
46 m_glyphsSize[glyph] =
Size(node->value<
int>(), m_glyphHeight);
48 calculateGlyphsWidthsAutomatically(
Image::load(textureFile), glyphSize);
52 m_glyphsSize[32].
setWidth(spaceWidth);
53 m_glyphsSize[160].
setWidth(spaceWidth);
59 m_glyphsSize[(
uchar)
'\n'] =
Size(1, m_glyphHeight);
72 for(
int glyph = m_firstGlyph; glyph < 256; ++glyph) {
73 m_glyphsTextureCoords[glyph].
setRect(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.
width(),
74 ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.
height(),
75 m_glyphsSize[glyph].
width(),
83 Rect screenCoords(startPos, boxSize);
99 if(!screenCoords.
isValid() || !m_texture)
102 int textLenght = text.length();
108 for(
int i = 0; i < textLenght; ++i) {
109 int glyph = (
uchar)text[i];
116 Rect glyphScreenCoords(glyphsPositions[i], m_glyphsSize[glyph]);
117 Rect glyphTextureCoords = m_glyphsTextureCoords[glyph];
137 if(glyphScreenCoords.
bottom() < 0 || glyphScreenCoords.
right() < 0)
141 if(glyphScreenCoords.
top() < 0) {
142 glyphTextureCoords.
setTop(glyphTextureCoords.
top() - glyphScreenCoords.
top());
143 glyphScreenCoords.
setTop(0);
145 if(glyphScreenCoords.
left() < 0) {
146 glyphTextureCoords.
setLeft(glyphTextureCoords.
left() - glyphScreenCoords.
left());
154 if(!screenCoords.
intersects(glyphScreenCoords))
158 if(glyphScreenCoords.
bottom() > screenCoords.
bottom()) {
162 if(glyphScreenCoords.
right() > screenCoords.
right()) {
168 coordsBuffer.
addRect(glyphScreenCoords, glyphTextureCoords);
177 static std::vector<Point> glyphsPositions(1);
178 static std::vector<int> lineWidths(1);
180 int textLength = text.length();
181 int maxLineWidth = 0;
187 if(textLength == 0) {
189 textBoxSize->
resize(0,m_glyphHeight);
190 return glyphsPositions;
194 if(textLength > (
int)glyphsPositions.size())
195 glyphsPositions.resize(textLength);
200 for(i = 0; i< textLength; ++i) {
201 glyph = (
uchar)text[i];
203 if(glyph == (
uchar)
'\n') {
205 if(lines+1 > (
int)lineWidths.size())
206 lineWidths.resize(lines+1);
207 lineWidths[lines] = 0;
208 }
else if(glyph >= 32) {
209 lineWidths[lines] += m_glyphsSize[glyph].
width() ;
210 if((i+1 != textLength && text[i+1] !=
'\n'))
211 lineWidths[lines] += m_glyphSpacing.
width();
212 maxLineWidth = std::max<int>(maxLineWidth, lineWidths[lines]);
217 Point virtualPos(0, m_yOffset);
219 for(i = 0; i < textLength; ++i) {
220 glyph = (
uchar)text[i];
223 if(glyph == (
uchar)
'\n' || i == 0) {
224 if(glyph == (
uchar)
'\n') {
225 virtualPos.
y += m_glyphHeight + m_glyphSpacing.
height();
231 virtualPos.
x = (maxLineWidth - lineWidths[lines]);
233 virtualPos.
x = (maxLineWidth - lineWidths[lines]) / 2;
240 glyphsPositions[i] = virtualPos;
243 if(glyph >= 32 && glyph != (
uchar)
'\n') {
244 virtualPos.
x += m_glyphsSize[glyph].
width() + m_glyphSpacing.
width();
249 textBoxSize->
setWidth(maxLineWidth);
250 textBoxSize->
setHeight(virtualPos.
y + m_glyphHeight);
253 return glyphsPositions;
263 void BitmapFont::calculateGlyphsWidthsAutomatically(
const ImagePtr& image,
const Size& glyphSize)
268 int numHorizontalGlyphs = image->getSize().width() / glyphSize.
width();
269 auto texturePixels = image->getPixels();
272 for(
int glyph = m_firstGlyph; glyph< 256; ++glyph) {
273 Rect glyphCoords(((glyph - m_firstGlyph) % numHorizontalGlyphs) * glyphSize.
width(),
274 ((glyph - m_firstGlyph) / numHorizontalGlyphs) * glyphSize.
height(),
277 int width = glyphSize.
width();
278 for(
int x = glyphCoords.left(); x <= glyphCoords.right(); ++x) {
279 int filledPixels = 0;
281 for(
int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) {
282 if(texturePixels[(y * image->getSize().width() * 4) + (x*4) + 3] != 0)
286 width = x - glyphCoords.left() + 1;
289 m_glyphsSize[glyph].
resize(width, m_glyphHeight);
297 std::vector<std::string> words;
301 for(
const auto &word: wordsSplit) {
303 if(wordWidth > maxWidth) {
305 for(
uint j=0;j<word.length();++j) {
306 std::string candidate = newWord + word[j];
307 if(j != word.length() - 1)
311 if(candidateWidth > maxWidth) {
313 words.push_back(newWord);
320 words.push_back(newWord);
322 words.push_back(word);
326 for(
const auto &word: words) {
327 std::string candidate = line + word;
330 if(candidateWidth > maxWidth) {
332 outText += line.substr(0, line.length()-1) +
"\n";
340 outText = outText.substr(0, outText.length()-1);