[Git][debian-gis-team/mapnik][upstream] New upstream version 4.0.6+ds
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Sun Mar 2 15:25:15 GMT 2025
Bas Couwenberg pushed to branch upstream at Debian GIS Project / mapnik
Commits:
5b976712 by Bas Couwenberg at 2025-03-02T16:11:59+01:00
New upstream version 4.0.6+ds
- - - - -
16 changed files:
- .github/actions/run_tests/action.yml
- .gitmodules
- CHANGELOG.md
- INSTALL.md
- docs/cmake-usage.md
- docs/design.md
- include/mapnik/cairo/cairo_context.hpp
- include/mapnik/text/harfbuzz_shaper.hpp
- include/mapnik/text/text_layout.hpp
- include/mapnik/text/text_properties.hpp
- include/mapnik/version.hpp
- src/cairo/cairo_context.cpp
- src/text/renderer.cpp
- src/text/text_layout.cpp
- src/text/text_properties.cpp
- test/unit/text/shaping.cpp
Changes:
=====================================
.github/actions/run_tests/action.yml
=====================================
@@ -43,12 +43,14 @@ runs:
- name: Pack visual test results
working-directory: build/out
+ if: runner.os != 'macOS'
shell: bash
run: |
tar -vzcf visual-test-results.tar.gz visual-test-result
- name: Upload visual test results
uses: actions/upload-artifact at v4
+ if: runner.os != 'macOS'
with:
name: ${{ inputs.cmake-preset }}-visual-tests-${{ github.sha }}
path: build/out/visual-test-results.tar.gz
=====================================
.gitmodules
=====================================
@@ -1,23 +1,23 @@
[submodule "test/data"]
- path = test/data
- url = https://github.com/mapnik/test-data.git
- branch = master
+ path = test/data
+ url = https://github.com/mapnik/test-data.git
+ branch = master
[submodule "test/data-visual"]
- path = test/data-visual
- url = https://github.com/mapnik/test-data-visual.git
- branch = master
+ path = test/data-visual
+ url = https://github.com/mapnik/test-data-visual.git
+ branch = master
[submodule "deps/mapbox/variant"]
- path = deps/mapbox/variant
- url = https://github.com/mapbox/variant.git
+ path = deps/mapbox/variant
+ url = https://github.com/mapbox/variant.git
branch = master
[submodule "deps/mapbox/geometry"]
- path = deps/mapbox/geometry
- url = https://github.com/mapbox/geometry.hpp.git
+ path = deps/mapbox/geometry
+ url = https://github.com/mapbox/geometry.hpp.git
branch = master
[submodule "deps/mapbox/protozero"]
- path = deps/mapbox/protozero
- url = https://github.com/mapbox/protozero.git
+ path = deps/mapbox/protozero
+ url = https://github.com/mapbox/protozero.git
branch = master
[submodule "deps/mapbox/polylabel"]
- path = deps/mapbox/polylabel
- url = https://github.com/mapbox/polylabel.git
+ path = deps/mapbox/polylabel
+ url = https://github.com/mapbox/polylabel.git
=====================================
CHANGELOG.md
=====================================
@@ -6,11 +6,29 @@ Developers: Please commit along with changes.
For a complete change history, see the git log.
+## Mapnik 4.0.6
+
+Released March 2nd, 2025
+
+(Packaged from [eb86d9513](https://github.com/mapnik/mapnik/commit/eb86d9513))
+
+- Add 'lang' parameter to TextSymbolizer
+ PR https://github.com/mapnik/mapnik/pull/4492
+ PR https://github.com/mapnik/mapnik/pull/4493
+ https://github.com/mapnik/mapnik/issues/4494
+
+- AGG text - add missing `halo` renderer (rasterizer="full")
+
+- Attempt to disable 'cairo' glyph caching
+ PR https://github.com/mapnik/mapnik/pull/4498
+ https://github.com/mapnik/mapnik/issues/4497
+
+
## Mapnik 4.0.5
Released January 31st, 2025
-(Packaged from [11414a561](https://github.com/mapnik/mapnik/commit/11414a561)
+(Packaged from [11414a561](https://github.com/mapnik/mapnik/commit/11414a561))
- Fix compilation warnings using `clang` and `gcc` (WIP)
- Default to -std=c++20
@@ -21,7 +39,7 @@ Released January 31st, 2025
Released December 4th, 2024
-(Packaged from [51a8a59f1](https://github.com/mapnik/mapnik/commit/51a8a59f1)
+(Packaged from [51a8a59f1](https://github.com/mapnik/mapnik/commit/51a8a59f1))
- Explicit conversions operators in Expressions bool(expr), int(expr), float(expr), str(expr)
- value::to_bool() - sync logic with Python bool() operator e.g `if 0 -> false : else -> true`
=====================================
INSTALL.md
=====================================
@@ -85,10 +85,10 @@ Mapnik Core depends on:
- system
- regex (optionally built with icu regex support)
- program_options (optionally for mapnik command line programs)
+ - property_tree (for RapidXml parser, optionally libxml2 can be used)
* libicuuc >= 4.0 (ideally >= 4.2) - International Components for Unicode
* libz - Zlib compression
* libfreetype - Freetype2 for font support (Install requires freetype-config)
- * libxml2 - XML parsing (Install requires xml2-config)
* libharfbuzz - an OpenType text shaping engine (>=0.9.34 needed for CSS font-feature-settings support)
Mapnik Core optionally depends on:
@@ -108,6 +108,7 @@ Additional optional dependencies:
- pg_config - PostgreSQL installation capabilities
* libgdal - GDAL/OGR input (For gdal and ogr plugin support) (>= GDAL 2.0.2 for thread safety - https://github.com/mapnik/mapnik/issues/3339)
* libsqlite3 - SQLite input (needs RTree support builtin) (sqlite plugin support)
+ * libxml2 - Alternative XML parser (with entity support as used by the former OpenStreetMap 'standard' style)
Instructions for installing many of these dependencies on
various platforms can be found at the Mapnik Wiki:
=====================================
docs/cmake-usage.md
=====================================
@@ -34,7 +34,7 @@ All targets:
* `mapnik::wkt`: wkt support for libmapnik.
All mapnik executables and targets are exported within `mapnikTargets.cmake`.
-The font path is is available in the variable `MAPNIK_FONTS_DIR`.
+The font path is available in the variable `MAPNIK_FONTS_DIR`.
The install location of the plugins might be configuration dependent.
For each configuration there exists a variable `MAPNIK_PLUGINS_DIR_<CONFIGURATION>` where `<CONFIGURATION>` is one of `CMAKE_BUILD_TYPE` as upper case.
=====================================
docs/design.md
=====================================
@@ -2,7 +2,7 @@
Above all Mapnik is about making beautiful maps. This aim drives us to be constantly forward looking. Progress in technology and design are reshaping the art of the possible for maps. Mapnik joins the best ideas in high quality graphics with robust patterns and algorithms for spatial data access. The goal should be no less than enabling a new generation of map makers and gorgeous maps.
-Mapnik is a library. It is not a server - rather it's for writing servers. Or for writing desktop graphics engines to display maps. Or for visualizing new galaxies - its up to you. If you have an inclination for scripting and something to render in real world or celestial coordinates, Mapnik is for you. Mapnik is not a full solution, or even half a solution. At its best, Mapnik is a drawing api that provides the right tools for the developer to make sense of, and art from, geodata.
+Mapnik is a library. It is not a server - rather it's for writing servers. Or for writing desktop graphics engines to display maps. Or for visualizing new galaxies - it's up to you. If you have an inclination for scripting and something to render in real world or celestial coordinates, Mapnik is for you. Mapnik is not a full solution, or even half a solution. At its best, Mapnik is a drawing api that provides the right tools for the developer to make sense of, and art from, geodata.
But Mapnik is not just about drawing on a canvas. Beautiful maps can also be interactive maps and Mapnik aims to provide very flexible, custom access to geo features both in its C++ api and in binding languages. MetaWriters and the Grid renderer are two recent advances that enable highly interactive feature display in mapping applications using JSON serialized features, but more will come.
=====================================
include/mapnik/cairo/cairo_context.hpp
=====================================
@@ -47,6 +47,7 @@ MAPNIK_DISABLE_WARNING_POP
#include <memory>
#include <map>
#include <stdexcept>
+#include <random>
#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
@@ -403,9 +404,16 @@ class cairo_context : private util::noncopyable
}
}
}
+ inline double generate_offset()
+ {
+ std::mt19937 gen(rd_());
+ std::uniform_real_distribution<> dis{0.0, 1e-6};
+ return dis(gen);
+ }
private:
cairo_ptr cairo_;
+ std::random_device rd_;
};
template<typename Context>
=====================================
include/mapnik/text/harfbuzz_shaper.hpp
=====================================
@@ -225,7 +225,8 @@ struct harfbuzz_shaper
text_itemizer& itemizer,
std::map<unsigned, double>& width_map,
face_manager_freetype& font_manager,
- double scale_factor)
+ double scale_factor,
+ std::optional<std::string> lang = std::optional<std::string>(std::nullopt))
{
unsigned start = line.first_char();
unsigned end = line.last_char();
@@ -281,15 +282,23 @@ struct harfbuzz_shaper
hb_font_t* font(hb_ft_font_create(face->get_face(), nullptr));
auto script = detail::_icu_script_to_script(text_item.script);
- auto language = detail::script_to_language(script);
- MAPNIK_LOG_DEBUG(harfbuzz_shaper)
- << "RUN:[" << text_item.start << "," << text_item.end << "]"
- << " LANGUAGE:" << ((language != nullptr) ? hb_language_to_string(language) : "unknown")
- << " SCRIPT:" << script << "(" << text_item.script << ") " << uscript_getShortName(text_item.script)
- << " FONT:" << face->family_name();
- if (language != HB_LANGUAGE_INVALID)
+ hb_language_t hb_lang;
+ if (lang)
{
- hb_buffer_set_language(buffer.get(), language); // set most common language for the run based script
+ hb_lang = hb_language_from_string(lang->c_str(), -1);
+ }
+ else
+ {
+ hb_lang = detail::script_to_language(script);
+ MAPNIK_LOG_DEBUG(harfbuzz_shaper)
+ << "RUN:[" << text_item.start << "," << text_item.end << "]"
+ << " LANGUAGE:" << ((hb_lang != nullptr) ? hb_language_to_string(hb_lang) : "unknown")
+ << " SCRIPT:" << script << "(" << text_item.script << ") "
+ << uscript_getShortName(text_item.script) << " FONT:" << face->family_name();
+ }
+ if (hb_lang != HB_LANGUAGE_INVALID)
+ {
+ hb_buffer_set_language(buffer.get(), hb_lang); // set most common language for the run based script
}
hb_buffer_set_script(buffer.get(), script);
=====================================
include/mapnik/text/text_layout.hpp
=====================================
@@ -167,6 +167,7 @@ class text_layout
// Precalculated values for maximum performance
rotation orientation_ = {0, 1.0};
char wrap_char_ = ' ';
+ std::optional<std::string> lang_;
double wrap_width_ = 0.0;
bool wrap_before_ = false;
bool repeat_wrap_char_ = false;
=====================================
include/mapnik/text/text_properties.hpp
=====================================
@@ -155,6 +155,7 @@ struct MAPNIK_DECL text_layout_properties
symbolizer_base::value_type jalign;
symbolizer_base::value_type valign;
directions_e dir = EXACT_POSITION;
+ std::optional<std::string> lang;
};
struct text_properties_expressions
=====================================
include/mapnik/version.hpp
=====================================
@@ -27,7 +27,7 @@
#define MAPNIK_MAJOR_VERSION 4
#define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 5
+#define MAPNIK_PATCH_VERSION 6
#define MAPNIK_VERSION MAPNIK_VERSION_ENCODE(MAPNIK_MAJOR_VERSION, MAPNIK_MINOR_VERSION, MAPNIK_PATCH_VERSION)
=====================================
src/cairo/cairo_context.cpp
=====================================
@@ -426,7 +426,6 @@ void cairo_context::show_glyph(unsigned long index, pixel_position const& pos)
glyph.index = index;
glyph.x = pos.x;
glyph.y = pos.y;
-
cairo_show_glyphs(cairo_.get(), &glyph, 1);
check_object_status_and_throw_exception(*this);
}
@@ -448,27 +447,22 @@ void cairo_context::add_text(glyph_positions const& pos,
composite_mode_e halo_comp_op,
double scale_factor)
{
+ auto off = generate_offset();
pixel_position const& base_point = pos.get_base_point();
const double sx = base_point.x;
const double sy = base_point.y;
-
- for (auto const& glyph_pos : pos)
- {
- glyph_info const& glyph = glyph_pos.glyph;
- glyph.face->set_character_sizes(glyph.format->text_size * scale_factor);
- }
-
// render halo
double halo_radius = 0;
set_operator(halo_comp_op);
for (auto const& glyph_pos : pos)
{
glyph_info const& glyph = glyph_pos.glyph;
+ glyph.face->set_character_sizes(glyph.format->text_size * scale_factor);
halo_radius = glyph.format->halo_radius * scale_factor;
// make sure we've got reasonable values.
if (halo_radius <= 0.0 || halo_radius > 1024.0)
continue;
- double text_size = glyph.format->text_size * scale_factor;
+ double text_size = glyph.format->text_size * scale_factor + off;
cairo_matrix_t matrix;
matrix.xx = text_size * glyph_pos.rot.cos;
matrix.xy = text_size * glyph_pos.rot.sin;
@@ -489,19 +483,19 @@ void cairo_context::add_text(glyph_positions const& pos,
for (auto const& glyph_pos : pos)
{
glyph_info const& glyph = glyph_pos.glyph;
- double text_size = glyph.format->text_size * scale_factor;
+ double text_size = glyph.format->text_size * scale_factor + off;
cairo_matrix_t matrix;
matrix.xx = text_size * glyph_pos.rot.cos;
matrix.xy = text_size * glyph_pos.rot.sin;
matrix.yx = text_size * -glyph_pos.rot.sin;
matrix.yy = text_size * glyph_pos.rot.cos;
- matrix.x0 = 0;
- matrix.y0 = 0;
+ pixel_position new_pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot);
+ matrix.x0 = new_pos.x;
+ matrix.y0 = -new_pos.y;
set_font_matrix(matrix);
set_font_face(manager, glyph.face);
- pixel_position new_pos = glyph_pos.pos + glyph.offset.rotate(glyph_pos.rot);
set_color(glyph.format->fill, glyph.format->text_opacity);
- show_glyph(glyph.glyph_index, pixel_position(sx + new_pos.x, sy - new_pos.y));
+ show_glyph(glyph.glyph_index, pixel_position(sx, sy));
}
}
=====================================
src/text/renderer.cpp
=====================================
@@ -217,7 +217,22 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
if (!error)
{
FT_BitmapGlyph bit = reinterpret_cast<FT_BitmapGlyph>(g);
- if (bit->bitmap.pixel_mode != FT_PIXEL_MODE_BGRA)
+ if (bit->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
+ {
+ pixel_position render_pos(base_point);
+ image_rgba8 glyph_image(render_glyph_image(glyph, bit->bitmap, transform_, render_pos));
+ const constexpr std::size_t pixel_size = sizeof(image_rgba8::pixel_type);
+ render_halo<pixel_size>(glyph_image.bytes(),
+ glyph_image.width(),
+ glyph_image.height(),
+ halo_fill,
+ render_pos.x,
+ render_pos.y,
+ halo_radius,
+ halo_opacity,
+ halo_comp_op_);
+ }
+ else
{
composite_bitmap(pixmap_,
&bit->bitmap,
=====================================
src/text/text_layout.cpp
=====================================
@@ -113,6 +113,7 @@ text_layout::text_layout(face_manager_freetype& font_manager,
util::apply_visitor(extract_value<std::string>(feature, attrs), layout_properties_.wrap_char);
if (!wrap_str.empty())
wrap_char_ = wrap_str[0];
+ lang_ = layout_properties_.lang;
wrap_width_ = util::apply_visitor(extract_value<value_double>(feature, attrs), layout_properties_.wrap_width);
double angle = util::apply_visitor(extract_value<value_double>(feature, attrs), layout_properties_.orientation);
orientation_.init(util::radians(angle));
@@ -456,7 +457,7 @@ void text_layout::clear()
void text_layout::shape_text(text_line& line)
{
- harfbuzz_shaper::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_);
+ harfbuzz_shaper::shape_text(line, itemizer_, width_map_, font_manager_, scale_factor_, lang_);
}
void text_layout::init_auto_alignment()
=====================================
src/text/text_properties.cpp
=====================================
@@ -270,6 +270,7 @@ void text_layout_properties::from_xml(xml_node const& node, fontset_map const& f
set_property_from_xml<vertical_alignment_e>(valign, "vertical-alignment", node);
set_property_from_xml<horizontal_alignment_e>(halign, "horizontal-alignment", node);
set_property_from_xml<justify_alignment_e>(jalign, "justify-alignment", node);
+ lang = node.get_opt_attr<std::string>("lang");
}
void text_layout_properties::to_xml(boost::property_tree::ptree& node,
@@ -300,6 +301,8 @@ void text_layout_properties::to_xml(boost::property_tree::ptree& node,
serialize_property("rotate-displacement", rotate_displacement, node);
if (!(orientation == dfl.orientation) || explicit_defaults)
serialize_property("orientation", orientation, node);
+ if (lang)
+ set_attr(node, "lang", *lang);
}
void text_layout_properties::add_expressions(expression_set& output) const
=====================================
test/unit/text/shaping.cpp
=====================================
@@ -28,7 +28,7 @@ void test_shaping(mapnik::font_set const& fontset,
itemizer.add_text(ustr, props);
mapnik::text_line line(0, length);
- mapnik::harfbuzz_shaper::shape_text(line, itemizer, width_map, fm, scale_factor);
+ mapnik::harfbuzz_shaper::shape_text(line, itemizer, width_map, fm, scale_factor, "");
std::size_t index = 0;
for (auto const& g : line)
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapnik/-/commit/5b9767128f7de59bbaedf9ddd7fecc7b68ddc190
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/mapnik/-/commit/5b9767128f7de59bbaedf9ddd7fecc7b68ddc190
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250302/b8d2230b/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list