summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/render/binpacker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/render/binpacker.cpp')
-rw-r--r--src/osd/modules/render/binpacker.cpp302
1 files changed, 151 insertions, 151 deletions
diff --git a/src/osd/modules/render/binpacker.cpp b/src/osd/modules/render/binpacker.cpp
index 2054dfa54cf..fcd126f5c14 100644
--- a/src/osd/modules/render/binpacker.cpp
+++ b/src/osd/modules/render/binpacker.cpp
@@ -11,185 +11,185 @@
bool rectangle_packer::pack(const std::vector<packable_rectangle>& rects, std::vector<std::vector<packed_rectangle>>& packs, int pack_size)
{
- clear();
-
- m_pack_size = pack_size;
-
- // Add rects to member array, and check to make sure none is too big
- for (size_t rect = 0; rect < rects.size(); rect++)
- {
- m_rects.push_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
- }
-
- // Sort from greatest to least area
- std::sort(m_rects.rbegin(), m_rects.rend());
-
- // Pack
- while (m_num_packed < (int)m_rects.size())
- {
- int i = m_packs.size();
- m_packs.push_back(rectangle(m_pack_size));
- m_roots.push_back(i);
- if (!fill(i))
- {
+ clear();
+
+ m_pack_size = pack_size;
+
+ // Add rects to member array, and check to make sure none is too big
+ for (size_t rect = 0; rect < rects.size(); rect++)
+ {
+ m_rects.push_back(rectangle(0, 0, rects[rect].width(), rects[rect].height(), rects[rect].hash(), rects[rect].format(), rects[rect].rowpixels(), rects[rect].palette(), rects[rect].base()));
+ }
+
+ // Sort from greatest to least area
+ std::sort(m_rects.rbegin(), m_rects.rend());
+
+ // Pack
+ while (m_num_packed < (int)m_rects.size())
+ {
+ int i = m_packs.size();
+ m_packs.push_back(rectangle(m_pack_size));
+ m_roots.push_back(i);
+ if (!fill(i))
+ {
return false;
}
- }
+ }
- // Write out
- packs.resize(m_roots.size());
- for (size_t i = 0; i < m_roots.size(); ++i)
- {
- packs[i].clear();
- add_pack_to_array(m_roots[i], packs[i]);
- }
+ // Write out
+ packs.resize(m_roots.size());
+ for (size_t i = 0; i < m_roots.size(); ++i)
+ {
+ packs[i].clear();
+ add_pack_to_array(m_roots[i], packs[i]);
+ }
- return true;
+ return true;
}
void rectangle_packer::clear()
{
- m_pack_size = 0;
- m_num_packed = 0;
- m_rects.clear();
- m_packs.clear();
- m_roots.clear();
+ m_pack_size = 0;
+ m_num_packed = 0;
+ m_rects.clear();
+ m_packs.clear();
+ m_roots.clear();
}
bool rectangle_packer::fill(int pack)
{
- // For each rect
- for (size_t rect = 0; rect < m_rects.size(); ++rect)
- {
- // If it's not already packed
- if (!m_rects[rect].packed)
- {
- // If it fits in the current working area
- if (fits(m_rects[rect], m_packs[pack]))
- {
- // Store in lower-left of working area, split, and recurse
- m_num_packed++;
- split(pack, rect);
- fill(m_packs[pack].children[0]);
- fill(m_packs[pack].children[1]);
- return true;
- }
- }
- }
- return false;
+ // For each rect
+ for (size_t rect = 0; rect < m_rects.size(); ++rect)
+ {
+ // If it's not already packed
+ if (!m_rects[rect].packed)
+ {
+ // If it fits in the current working area
+ if (fits(m_rects[rect], m_packs[pack]))
+ {
+ // Store in lower-left of working area, split, and recurse
+ m_num_packed++;
+ split(pack, rect);
+ fill(m_packs[pack].children[0]);
+ fill(m_packs[pack].children[1]);
+ return true;
+ }
+ }
+ }
+ return false;
}
void rectangle_packer::split(int pack, int rect)
{
- // Split the working area either horizontally or vertically with respect
- // to the rect we're storing, such that we get the largest possible child
- // area.
-
- rectangle left = m_packs[pack];
- rectangle right = m_packs[pack];
- rectangle bottom = m_packs[pack];
- rectangle top = m_packs[pack];
-
- left.y += m_rects[rect].h;
- left.w = m_rects[rect].w;
- left.h -= m_rects[rect].h;
-
- right.x += m_rects[rect].w;
- right.w -= m_rects[rect].w;
-
- bottom.x += m_rects[rect].w;
- bottom.h = m_rects[rect].h;
- bottom.w -= m_rects[rect].w;
-
- top.y += m_rects[rect].h;
- top.h -= m_rects[rect].h;
-
- int max_lr_area = left.get_area();
- if (right.get_area() > max_lr_area)
- {
- max_lr_area = right.get_area();
- }
-
- int max_bt_area = bottom.get_area();
- if (top.get_area() > max_bt_area)
- {
- max_bt_area = top.get_area();
- }
-
- if (max_lr_area > max_bt_area)
- {
- if (left.get_area() > right.get_area())
- {
- m_packs.push_back(left);
- m_packs.push_back(right);
- }
- else
- {
- m_packs.push_back(right);
- m_packs.push_back(left);
- }
- }
- else
- {
- if (bottom.get_area() > top.get_area())
- {
- m_packs.push_back(bottom);
- m_packs.push_back(top);
- }
- else
- {
- m_packs.push_back(top);
- m_packs.push_back(bottom);
- }
- }
-
- // This pack area now represents the rect we've just stored, so save the
- // relevant info to it, and assign children.
- m_packs[pack].w = m_rects[rect].w;
- m_packs[pack].h = m_rects[rect].h;
- m_packs[pack].hash = m_rects[rect].hash;
- m_packs[pack].format = m_rects[rect].format;
- m_packs[pack].rowpixels = m_rects[rect].rowpixels;
- m_packs[pack].palette = m_rects[rect].palette;
- m_packs[pack].base = m_rects[rect].base;
- m_packs[pack].children[0] = m_packs.size() - 2;
- m_packs[pack].children[1] = m_packs.size() - 1;
-
- // Done with the rect
- m_rects[rect].packed = true;
+ // Split the working area either horizontally or vertically with respect
+ // to the rect we're storing, such that we get the largest possible child
+ // area.
+
+ rectangle left = m_packs[pack];
+ rectangle right = m_packs[pack];
+ rectangle bottom = m_packs[pack];
+ rectangle top = m_packs[pack];
+
+ left.y += m_rects[rect].h;
+ left.w = m_rects[rect].w;
+ left.h -= m_rects[rect].h;
+
+ right.x += m_rects[rect].w;
+ right.w -= m_rects[rect].w;
+
+ bottom.x += m_rects[rect].w;
+ bottom.h = m_rects[rect].h;
+ bottom.w -= m_rects[rect].w;
+
+ top.y += m_rects[rect].h;
+ top.h -= m_rects[rect].h;
+
+ int max_lr_area = left.get_area();
+ if (right.get_area() > max_lr_area)
+ {
+ max_lr_area = right.get_area();
+ }
+
+ int max_bt_area = bottom.get_area();
+ if (top.get_area() > max_bt_area)
+ {
+ max_bt_area = top.get_area();
+ }
+
+ if (max_lr_area > max_bt_area)
+ {
+ if (left.get_area() > right.get_area())
+ {
+ m_packs.push_back(left);
+ m_packs.push_back(right);
+ }
+ else
+ {
+ m_packs.push_back(right);
+ m_packs.push_back(left);
+ }
+ }
+ else
+ {
+ if (bottom.get_area() > top.get_area())
+ {
+ m_packs.push_back(bottom);
+ m_packs.push_back(top);
+ }
+ else
+ {
+ m_packs.push_back(top);
+ m_packs.push_back(bottom);
+ }
+ }
+
+ // This pack area now represents the rect we've just stored, so save the
+ // relevant info to it, and assign children.
+ m_packs[pack].w = m_rects[rect].w;
+ m_packs[pack].h = m_rects[rect].h;
+ m_packs[pack].hash = m_rects[rect].hash;
+ m_packs[pack].format = m_rects[rect].format;
+ m_packs[pack].rowpixels = m_rects[rect].rowpixels;
+ m_packs[pack].palette = m_rects[rect].palette;
+ m_packs[pack].base = m_rects[rect].base;
+ m_packs[pack].children[0] = m_packs.size() - 2;
+ m_packs[pack].children[1] = m_packs.size() - 1;
+
+ // Done with the rect
+ m_rects[rect].packed = true;
}
bool rectangle_packer::fits(rectangle& rect1, const rectangle& rect2)
{
- // Check to see if rect1 fits in rect2
-
- if (rect1.w <= rect2.w && rect1.h <= rect2.h)
- {
- return true;
- }
- else
- {
- return false;
- }
+ // Check to see if rect1 fits in rect2
+
+ if (rect1.w <= rect2.w && rect1.h <= rect2.h)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
void rectangle_packer::add_pack_to_array(int pack, std::vector<packed_rectangle>& array) const
{
- if (m_packs[pack].hash != 0)
- {
+ if (m_packs[pack].hash != 0)
+ {
array.push_back(packed_rectangle(m_packs[pack].hash, m_packs[pack].format,
m_packs[pack].w, m_packs[pack].h, m_packs[pack].x, m_packs[pack].y,
m_packs[pack].rowpixels, m_packs[pack].palette, m_packs[pack].base));
- if (m_packs[pack].children[0] != -1)
- {
- add_pack_to_array(m_packs[pack].children[0], array);
- }
+ if (m_packs[pack].children[0] != -1)
+ {
+ add_pack_to_array(m_packs[pack].children[0], array);
+ }
- if (m_packs[pack].children[1] != -1)
- {
- add_pack_to_array(m_packs[pack].children[1], array);
- }
- }
+ if (m_packs[pack].children[1] != -1)
+ {
+ add_pack_to_array(m_packs[pack].children[1], array);
+ }
+ }
}