mirror of
https://github.com/tfussell/xlnt.git
synced 2024-03-22 13:11:17 +08:00
begin trying to garbage collect cell formats
This commit is contained in:
parent
f9e349ce8d
commit
1474c8ab82
|
@ -32,6 +32,7 @@ namespace xlnt {
|
|||
|
||||
class alignment;
|
||||
class border;
|
||||
class cell;
|
||||
class fill;
|
||||
class font;
|
||||
class number_format;
|
||||
|
|
|
@ -781,7 +781,7 @@ void cell::set_font(const font &font_)
|
|||
{
|
||||
auto &format = duplicate_format();
|
||||
format.font(font_, true);
|
||||
d_->format_id_ = format.id();
|
||||
d_->format_id_ = format.id();
|
||||
}
|
||||
|
||||
void cell::set_number_format(const number_format &number_format_)
|
||||
|
|
|
@ -18,6 +18,18 @@ public:
|
|||
wb_guess_types.set_guess_types(true);
|
||||
}
|
||||
|
||||
void test_temp()
|
||||
{
|
||||
xlnt::workbook wb;
|
||||
auto ws = wb.get_active_sheet();
|
||||
auto cell = ws.get_cell("A1");
|
||||
cell.set_value(3.141592);
|
||||
cell.set_font(xlnt::font().bold(true));
|
||||
cell.set_font(xlnt::font().size(20));
|
||||
wb.save("a.xlsx");
|
||||
wb.load("a.xlsx");
|
||||
}
|
||||
|
||||
void test_infer_numeric()
|
||||
{
|
||||
auto ws = wb_guess_types.create_sheet();
|
||||
|
|
|
@ -29,9 +29,13 @@
|
|||
|
||||
#include <detail/format_impl.hpp>
|
||||
#include <detail/style_impl.hpp>
|
||||
#include <xlnt/cell/cell.hpp>
|
||||
#include <xlnt/styles/format.hpp>
|
||||
#include <xlnt/styles/style.hpp>
|
||||
#include <xlnt/utils/exceptions.hpp>
|
||||
#include <xlnt/worksheet/worksheet.hpp>
|
||||
#include <xlnt/workbook/workbook.hpp>
|
||||
#include <xlnt/workbook/worksheet_iterator.hpp>
|
||||
|
||||
namespace xlnt {
|
||||
namespace detail {
|
||||
|
@ -46,41 +50,17 @@ struct stylesheet
|
|||
{
|
||||
format_impls.push_back(format_impl());
|
||||
auto &impl = format_impls.back();
|
||||
|
||||
impl.parent = this;
|
||||
impl.id = format_impls.size() - 1;
|
||||
impl.border_id = 0;
|
||||
impl.fill_id = 0;
|
||||
impl.font_id = 0;
|
||||
impl.number_format_id = 0;
|
||||
|
||||
formats.push_back(format(&impl));
|
||||
auto &format = formats.back();
|
||||
|
||||
if (!alignments.empty())
|
||||
{
|
||||
format.alignment(alignments.front(), false);
|
||||
}
|
||||
|
||||
if (!borders.empty())
|
||||
{
|
||||
format.border(borders.front(), false);
|
||||
}
|
||||
|
||||
if (!fills.empty())
|
||||
{
|
||||
format.fill(fills.front(), false);
|
||||
}
|
||||
|
||||
if (!fonts.empty())
|
||||
{
|
||||
format.font(fonts.front(), false);
|
||||
}
|
||||
|
||||
if (!number_formats.empty())
|
||||
{
|
||||
format.number_format(number_formats.front(), false);
|
||||
}
|
||||
|
||||
if (!protections.empty())
|
||||
{
|
||||
format.protection(protections.front(), false);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
|
@ -214,6 +194,58 @@ struct stylesheet
|
|||
colors.clear();
|
||||
}
|
||||
|
||||
format_impl *deduplicate(format_impl *f)
|
||||
{
|
||||
std::unordered_map<format_impl *, std::size_t> reference_counts;
|
||||
|
||||
for (auto ws : *parent)
|
||||
{
|
||||
auto dimension = ws.calculate_dimension();
|
||||
|
||||
for (auto row = dimension.get_top_left().get_row(); row <= dimension.get_bottom_right().get_row(); row++)
|
||||
{
|
||||
for (auto column = dimension.get_top_left().get_column(); column <= dimension.get_bottom_right().get_column(); column++)
|
||||
{
|
||||
if (ws.has_cell(cell_reference(column, row)))
|
||||
{
|
||||
auto cell = ws.get_cell(cell_reference(column, row));
|
||||
|
||||
if (cell.has_format())
|
||||
{
|
||||
reference_counts[formats.at(cell.get_format().id()).d_]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto result = f;
|
||||
|
||||
for (auto &impl : format_impls)
|
||||
{
|
||||
if (reference_counts[&impl] == 0 && &impl != f)
|
||||
{
|
||||
result = &impl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (result != f)
|
||||
{
|
||||
auto impl_iter = std::find_if(format_impls.begin(), format_impls.end(),
|
||||
[=](const format_impl &impl) { return &impl == f; });
|
||||
auto index = std::distance(format_impls.begin(), impl_iter);
|
||||
formats.erase(formats.begin() + index);
|
||||
format_impls.erase(impl_iter);
|
||||
}
|
||||
*/
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
workbook *parent;
|
||||
|
||||
std::list<format_impl> format_impls;
|
||||
std::vector<format> formats;
|
||||
|
||||
|
|
|
@ -123,6 +123,7 @@ void format::font(const xlnt::font &new_font, bool applied)
|
|||
{
|
||||
font_id(d_->parent->add_font(new_font));
|
||||
base_format::font(new_font, applied);
|
||||
d_ = d_->parent->deduplicate(d_);
|
||||
}
|
||||
|
||||
xlnt::number_format &format::number_format()
|
||||
|
|
|
@ -343,6 +343,10 @@ workbook::workbook()
|
|||
|
||||
workbook::workbook(detail::workbook_impl *impl) : d_(impl)
|
||||
{
|
||||
if (impl != nullptr)
|
||||
{
|
||||
d_->stylesheet_.parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void workbook::register_app_properties_in_manifest()
|
||||
|
@ -913,6 +917,8 @@ void swap(workbook &left, workbook &right)
|
|||
{
|
||||
ws.set_parent(left);
|
||||
}
|
||||
|
||||
left.d_->stylesheet_.parent = &left;
|
||||
}
|
||||
|
||||
if (right.d_ != nullptr)
|
||||
|
@ -921,12 +927,15 @@ void swap(workbook &left, workbook &right)
|
|||
{
|
||||
ws.set_parent(right);
|
||||
}
|
||||
|
||||
right.d_->stylesheet_.parent = &right;
|
||||
}
|
||||
}
|
||||
|
||||
workbook &workbook::operator=(workbook other)
|
||||
{
|
||||
swap(*this, other);
|
||||
d_->stylesheet_.parent = this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -943,6 +952,8 @@ workbook::workbook(const workbook &other) : workbook()
|
|||
{
|
||||
ws.set_parent(*this);
|
||||
}
|
||||
|
||||
d_->stylesheet_.parent = this;
|
||||
}
|
||||
|
||||
workbook::~workbook()
|
||||
|
|
Loading…
Reference in New Issue
Block a user