jubilant-funicular
FontMap.cpp
1 #include <algorithm>
2 
3 #include "nta/SpriteFont.h"
4 #include "nta/Random.h"
5 
6 namespace nta {
8  m_rects = new CharRect[NUM_PRINTABLE_CHARS];
9  for (int i = 0; i < NUM_PRINTABLE_CHARS; i++) {
10  m_rects[i].addedToMap = false;
11  }
12  }
13  FontMap::~FontMap() {
14  delete[] m_rects;
15  }
16  glm::vec2 FontMap::getBoundingDimensions() const {
17  float minX = 999, maxX = -999, minY = 999, maxY = -999;
18  std::for_each(m_rects, m_rects+NUM_PRINTABLE_CHARS, [&](const CharRect& r) {
19  minX = std::min(r.topLeft.x, minX);
20  maxX = std::max(r.topLeft.x+r.dimensions.x, maxX);
21  minY = std::min(r.topLeft.y-r.dimensions.y, minY);
22  maxY = std::max(r.topLeft.y, maxY);
23  });
24  return glm::vec2(maxX-minX, maxY-minY);
25  }
26  bool FontMap::isOverlapping(const CharRect& rect) const {
27  return std::any_of(m_rects, m_rects+NUM_PRINTABLE_CHARS, [&](const CharRect& r) {
28  if (r.addedToMap) {
29  glm::vec4 rectC(rect.topLeft.x+rect.dimensions.x/2, rect.topLeft.y-rect.dimensions.y/2, rect.dimensions.x/2.f, rect.dimensions.y/2.f);
30  glm::vec4 rC(r.topLeft.x+r.dimensions.x/2, r.topLeft.y-r.dimensions.y/2, r.dimensions.x/2.f, r.dimensions.y/2.f);
31  glm::vec4 displacement = rectC-rC;
32  if (fabs(displacement.x) < rectC[2]+rC[2] && fabs(displacement.y) < rectC[3]+rC[3]) {
33  return true;
34  }
35  }
36  return false;
37  });
38  }
39  void FontMap::addRect(char c, crvec2 dimensions) {
40  CharRect newRect;
41  if (!std::any_of(m_rects, m_rects+NUM_PRINTABLE_CHARS, [](const CharRect& cr){return cr.addedToMap;})) {
42  newRect = {glm::vec2(0), dimensions, true};
43  } else do {
44  CharRect existingRect;
45  do {
46  existingRect = m_rects[Random::randInt(NUM_PRINTABLE_CHARS)];
47  } while(!existingRect.addedToMap);
48  float width = dimensions.x;
49  float height = dimensions.y;
50  int relPos = Random::randInt(4);
51  switch(relPos) {
52  //top
53  case 0: newRect = {glm::vec2(existingRect.topLeft.x, existingRect.topLeft.y+height), dimensions, true}; break;
54  //bot
55  case 1: newRect = {glm::vec2(existingRect.topLeft.x, existingRect.topLeft.y-existingRect.dimensions.y), dimensions, true}; break;
56  //left
57  case 2: newRect = {glm::vec2(existingRect.topLeft.x-width, existingRect.topLeft.y), dimensions, true}; break;
58  //right
59  case 3: newRect = {glm::vec2(existingRect.topLeft.x+existingRect.dimensions.x, existingRect.topLeft.y), dimensions, true}; break;
60  }
61  } while (isOverlapping(newRect));
62  m_rects[c-FIRST_PRINTABLE_CHAR] = newRect;
63  }
64  void FontMap::position() {
65  glm::vec2 topLeft = m_rects[0].topLeft;
66  std::for_each(m_rects, m_rects+NUM_PRINTABLE_CHARS, [&](const CharRect& rect) {
67  if (rect.topLeft.x < topLeft.x) {
68  topLeft.x = rect.topLeft.x;
69  }
70  if (rect.topLeft.y > topLeft.y) {
71  topLeft.y = rect.topLeft.y;
72  }
73  });
74  //translate so topLeft is (0,0)
75  std::for_each(m_rects, m_rects+NUM_PRINTABLE_CHARS, [&](CharRect& rect) {
76  rect.topLeft -= topLeft;
77  });
78  }
79 }
nta::FontMap::CharRect
a rectangle representing the location of a char in the FontMap
Definition: SpriteFont.h:29
nta::FontMap::isOverlapping
bool isOverlapping(const CharRect &rect) const
returns whether or not rect is overlapping with any existing CharRect
Definition: FontMap.cpp:26
nta::FontMap::FontMap
FontMap()
constructor and destructor
Definition: FontMap.cpp:7
nta
Definition: Animation2D.h:6
nta::FontMap::m_rects
CharRect * m_rects
the rectangles making up the FontMap
Definition: SpriteFont.h:40
nta::FontMap::getBoundingDimensions
glm::vec2 getBoundingDimensions() const
returns the dimensions of the rectangle that contains the FontMap
Definition: FontMap.cpp:16