Skip to content

Commit

Permalink
Add new font properties and text rendering options to FCL files
Browse files Browse the repository at this point in the history
This adds reading and writing of new DirectWrite-related font properties and text rendering options to FCL files.
  • Loading branch information
reupen committed Dec 19, 2024
1 parent 330edeb commit f6ca36e
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 12 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
[#981](https://github.com/reupen/columns_ui/pull/989),
[#1030](https://github.com/reupen/columns_ui/pull/1030),
[#1031](https://github.com/reupen/columns_ui/pull/1031),
[#1037](https://github.com/reupen/columns_ui/pull/1037)]
[#1037](https://github.com/reupen/columns_ui/pull/1037),
[#1039](https://github.com/reupen/columns_ui/pull/1039)]

This includes colour font support on Windows 8.1 and newer (allowing the use
of, for example, colour emojis).
Expand Down
42 changes: 31 additions & 11 deletions foo_ui_columns/fcl_fonts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class FontsDataSet : public fcl::dataset {
identifier_global_items,
identifier_global_labels,
identifier_client_entries,
identifier_rendering_mode,
identifier_force_greyscale_antialiasing,

identifier_client_entry = 0,
};
void get_data(stream_writer* p_writer, uint32_t type, fcl::t_export_feedback& feedback,
Expand Down Expand Up @@ -55,6 +58,8 @@ class FontsDataSet : public fcl::dataset {
out.write_item(
identifier_client_entries, mem.m_data.get_ptr(), gsl::narrow<uint32_t>(mem.m_data.get_size()));
}
out.write_item(identifier_rendering_mode, fonts::rendering_mode);
out.write_item(identifier_force_greyscale_antialiasing, fonts::force_greyscale_antialiasing);
}
void set_data(stream_reader* p_reader, size_t stream_size, uint32_t type, fcl::t_import_feedback& feedback,
abort_callback& p_abort) override
Expand All @@ -67,21 +72,29 @@ class FontsDataSet : public fcl::dataset {
reader.read_item(element_id);
reader.read_item(element_size);

pfc::array_t<uint8_t> data;
data.set_size(element_size);
reader.read(data.get_ptr(), data.get_size());

stream_reader_memblock_ref data_reader(data);
const auto get_data = [&] {
std::vector<uint8_t> data(element_size);
reader.read(data.data(), data.size());
return data;
};

switch (element_id) {
case identifier_global_items:
g_font_manager_data.m_common_items_entry->import(&data_reader, data.get_size(), type, p_abort);
case identifier_global_items: {
const auto data = get_data();
stream_reader_memblock_ref data_reader(data.data(), data.size());
g_font_manager_data.m_common_items_entry->import(&data_reader, data.size(), type, p_abort);
break;
case identifier_global_labels:
g_font_manager_data.m_common_labels_entry->import(&data_reader, data.get_size(), type, p_abort);
}
case identifier_global_labels: {
const auto data = get_data();
stream_reader_memblock_ref data_reader(data.data(), data.size());
g_font_manager_data.m_common_labels_entry->import(&data_reader, data.size(), type, p_abort);
break;
}
case identifier_client_entries: {
fbh::fcl::Reader reader2(&data_reader, data.get_size(), p_abort);
const auto data = get_data();
stream_reader_memblock_ref data_reader(data.data(), data.size());
fbh::fcl::Reader reader2(&data_reader, data.size(), p_abort);

const auto count = reader2.read_item<uint32_t>();

Expand All @@ -103,7 +116,14 @@ class FontsDataSet : public fcl::dataset {
} else
reader2.skip(element_size2);
}
} break;
break;
}
case identifier_rendering_mode:
reader.read_item(fonts::rendering_mode);
break;
case identifier_force_greyscale_antialiasing:
reader.read_item(fonts::force_greyscale_antialiasing);
break;
default:
reader.skip(element_size);
break;
Expand Down
69 changes: 69 additions & 0 deletions foo_ui_columns/font_manager_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,45 @@ void FontManagerData::Entry::import(stream_reader* p_reader, size_t stream_size,
case identifier_point_size_tenths:
reader.read_item(font_description.point_size_tenths);
break;
case identifier_dip_size:
reader.read_item(font_description.dip_size);
break;
case identifier_typographic_font_family: {
pfc::string8 value;
reader.read_item(value, element_size);
font_description.typographic_family_name = mmh::to_utf16(value.c_str());
break;
}
case identifier_weight_stretch_style: {
std::vector<uint8_t> wss_data(element_size);
reader.read(wss_data.data(), wss_data.size());

uih::direct_write::WeightStretchStyle wss;
stream_reader_memblock_ref wss_reader(wss_data.data(), wss_data.size());

const auto family_name = wss_reader.read_string(p_abort);
wss.family_name = mmh::to_utf16(family_name.c_str());

wss.weight = static_cast<DWRITE_FONT_WEIGHT>(wss_reader.read_lendian_t<int32_t>(p_abort));
wss.stretch = static_cast<DWRITE_FONT_STRETCH>(wss_reader.read_lendian_t<int32_t>(p_abort));
wss.style = static_cast<DWRITE_FONT_STYLE>(wss_reader.read_lendian_t<int32_t>(p_abort));

break;
}
case identifier_axis_values: {
std::vector<uint8_t> axis_values_data(element_size);
reader.read(axis_values_data.data(), axis_values_data.size());

stream_reader_memblock_ref axis_values_reader(axis_values_data.data(), axis_values_data.size());
const auto axis_count = axis_values_reader.read_lendian_t<uint32_t>(p_abort);

for (auto _ : std::ranges::views::iota(0u, axis_count)) {
const auto tag = axis_values_reader.read_lendian_t<uint32_t>(p_abort);
const auto value = axis_values_reader.read_lendian_t<float>(p_abort);
font_description.axis_values.insert_or_assign(tag, value);
}
break;
}
default:
reader.skip(element_size);
break;
Expand All @@ -233,8 +272,38 @@ void FontManagerData::Entry::_export(stream_writer* p_stream, abort_callback& p_
out.write_item(identifier_mode, (uint32_t)font_mode);
if (font_mode == cui::fonts::font_mode_custom) {
out.write_item(identifier_font, font_description.log_font);

if (font_description.wss) {
const auto& wss = *font_description.wss;

stream_writer_buffer_simple wss_writer;
wss_writer.write_string(mmh::to_utf8(wss.family_name).c_str(), p_abort);
wss_writer.write_lendian_t(gsl::narrow<int32_t>(wss.weight), p_abort);
wss_writer.write_lendian_t(gsl::narrow<int32_t>(wss.stretch), p_abort);
wss_writer.write_lendian_t(gsl::narrow<int32_t>(wss.style), p_abort);

out.write_item(identifier_weight_stretch_style, wss_writer.m_buffer.get_ptr(),
gsl::narrow<uint32_t>(wss_writer.m_buffer.size()));
}
}
out.write_item(identifier_point_size_tenths, font_description.point_size_tenths);
out.write_item(identifier_dip_size, font_description.dip_size);
out.write_item(identifier_typographic_font_family, mmh::to_utf8(font_description.typographic_family_name).c_str());

if (!font_description.axis_values.empty()) {
const auto& axis_values = font_description.axis_values;

stream_writer_buffer_simple axis_values_writer;
axis_values_writer.write_lendian_t(gsl::narrow<uint32_t>(axis_values.size()), p_abort);

for (auto [tag, value] : axis_values) {
axis_values_writer.write_lendian_t(tag, p_abort);
axis_values_writer.write_lendian_t(value, p_abort);
}

out.write_item(identifier_axis_values, axis_values_writer.m_buffer.get_ptr(),
gsl::narrow<uint32_t>(axis_values_writer.m_buffer.size()));
}
}

void FontManagerData::Entry::read(uint32_t version, stream_reader* p_stream, abort_callback& p_abort)
Expand Down
4 changes: 4 additions & 0 deletions foo_ui_columns/font_manager_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ class FontManagerData : public cfg_var {
identifier_mode,
identifier_font,
identifier_point_size_tenths,
identifier_weight_stretch_style,
identifier_dip_size,
identifier_typographic_font_family,
identifier_axis_values,
};
GUID guid{};
cui::fonts::FontDescription font_description{};
Expand Down

0 comments on commit f6ca36e

Please sign in to comment.