/*
7 * Krzysztof KosiĆski <tweenk.pl@gmail.com>
9 * Copyright (C) 2011 Authors
10 * Released under GNU GPL v2+, read the file
'COPYING' for more information.
41 mutable std::optional<DrawingCache>
surface;
69 , _context_style(nullptr)
70 , _contains_unisolated_blend(false)
71 , style_vector_effect_size(false)
72 , style_vector_effect_rotate(false)
73 , style_vector_effect_fixed(false)
77 , _fill_pattern(nullptr)
78 , _stroke_pattern(nullptr)
83 , _background_accumulate(0)
86 , _cached_persistent(0)
87 , _has_cache_iterator(0)
100 if (itemdrawing->get_active() ==
this) {
101 itemdrawing->set_active(
nullptr);
115 _children.clear_and_dispose([] (
auto c) {
delete c; });
125 for (
auto c =
item->_parent;
c;
c =
c->_parent) {
126 if (
c ==
this)
return true;
146 item->_parent =
this;
166 item->_parent =
this;
182 _children.clear_and_dispose([] (
auto c) {
delete c; });
190 auto constexpr EPS = 1e-18;
258 static bool const cache_env = getenv(
"_INKSCAPE_DISABLE_CACHE");
269 if (cached == (
bool)
_cache) {
274 _cache = std::make_unique<CacheData>();
298 bool background_new =
false;
299 bool vector_effect_size =
false;
300 bool vector_effect_rotate =
false;
301 bool vector_effect_fixed =
false;
337 i.setChildrenStyle(context_style);
345 item->_parent =
this;
361 item->_parent =
this;
430 defer([=,
this, filter = std::move(filter)] ()
mutable {
468 bool const forcecache =
_filter && filters;
476 if ((~
_state & flags) == 0)
return;
485 unsigned to_update =
_state ^ flags;
507 child_ctx.
ctm[0] /= value;
508 child_ctx.
ctm[1] /= value;
509 child_ctx.
ctm[2] /= value;
510 child_ctx.
ctm[3] /= value;
516 child_ctx.
ctm[0] = value;
517 child_ctx.
ctm[1] = 0.0;
518 child_ctx.
ctm[2] = 0.0;
519 child_ctx.
ctm[3] = value;
524 bool affine_changed =
false;
527 affine_changed =
true;
532 if (totally_invalidated) {
536 _cache->surface->markDirty();
543 if (totally_invalidate) {
554 add_complexity_if(
_clip);
555 add_complexity_if(
_mask);
581 _drawbox = enlarged->roundOutwards();
652 _cache->surface->scheduleTransform(*cl, ctm_change);
671 if (!totally_invalidated) {
672 if (!is<DrawingGroup>(
this) || (
_filter && filters) || totally_invalidate) {
679struct MaskLuminanceToAlpha
683 guint r = 0, g = 0, b = 0;
688 guint32 ao = r*109 + g*366 + b*37;
689 return ((ao + 256) << 15) & 0xff000000;
707 bool const forcecache =
_filter && render_filters;
711 if (
this == stop_at) {
741 _filter->area_enlarge(*iarea,
this);
754 std::unique_lock<std::mutex> lock;
758 lock = std::unique_lock(
_cache->mutables);
761 if (
_cache->surface->device_scale() != device_scale) {
762 _cache->surface->markDirty();
764 _cache->surface->prepare();
766 _cache->surface->paintFromCache(dc, carea, forcecache);
778 _cache->surface.emplace(*cl, device_scale);
791 bool const needs_intermediate_rendering =
801 auto antialias =
rc.antialiasing_override.value_or(
_antialias);
828 cairo_set_antialias(ict.
raw(), cairo_get_antialias(dc.
raw()));
875 render_result =
_renderItem(ict,
rc, *carea, flags, stop_at);
878 if (
_filter && render_filters) {
879 bool rendered =
false;
882 for (; bg_root; bg_root = bg_root->_parent) {
883 if (bg_root->_background_new || bg_root->_filter)
break;
920 cachect.rectangle(*carea);
921 cachect.setOperator(CAIRO_OPERATOR_SOURCE);
922 cachect.setSource(&intermediate);
924 _cache->surface->markClean(*carea);
938 return render_result;
966 auto saved_rgba =
rc.outline_color;
977 rc.outline_color = saved_rgba;
1065 auto dglyps = cast<DrawingGlyphs>(
this);
1067 expanded = dglyps->getPickBox();
1083 return "No object id";
1085 return "No associated object";
1093 std::cout <<
"Display Item Tree" << std::endl;
1095 std::cout <<
"DI: ";
1096 for (
int i = 0; i < level; i++) {
1099 std::cout <<
name() << std::endl;
1101 i.recursivePrintTree(level + 1);
1120 for (
auto i =
this; i; i = i->_parent) {
1121 if (i !=
this && i->_filter) {
1122 i->
_filter->area_enlarge(*dirty, i);
1124 if (i->_cache && i->_cache->surface) {
1125 i->_cache->surface->markDirty(*dirty);
1127 i->_dropPatternCache();
1128 if (i->_background_accumulate) {
1137 if (
auto canvasitem =
drawing().getCanvasItemDrawing()) {
1138 canvasitem->get_canvas()->redraw_area(*dirty);
1147 _cache->surface->markDirty(area);
1151 i._invalidateFilterBackground(area);
1177 unsigned oldstate =
_state;
1187 if (
drawing().getCanvasItemDrawing()) {
1205 if (!cache_rect)
return -1.0;
1208 double score = cache_rect->
area();
1215 _filter->area_enlarge(test_area,
this);
1217 score *= (double)(test_area & limit_area)->area() / ref_area.
area();
1238 switch (antialias) {
1240 cairo_set_antialias(dc.
raw(), CAIRO_ANTIALIAS_NONE);
1243 cairo_set_antialias(dc.
raw(), CAIRO_ANTIALIAS_FAST);
1246 cairo_set_antialias(dc.
raw(), CAIRO_ANTIALIAS_GOOD);
1249 cairo_set_antialias(dc.
raw(), CAIRO_ANTIALIAS_BEST);
1252 g_assert_not_reached();
1258 switch (shape_rendering) {
1272 g_assert_not_reached();
Cairo software blending templates.
void ink_cairo_surface_filter(cairo_surface_t *in, cairo_surface_t *out, Filter &&filter)
cairo_operator_t ink_css_blend_to_cairo_operator(SPBlendMode css_blend)
Cairo integration helpers.
Cairo::RefPtr< Cairo::ImageSurface > surface
3x3 matrix representing an affine transformation.
void setTranslation(Point const &loc)
Sets the translation imparted by the Affine.
Coord descrim() const
Calculate the descriminant.
bool isSingular(Coord eps=EPSILON) const
Check whether this matrix is singular.
bool isIdentity(Coord eps=EPSILON) const
Check whether this matrix is an identity matrix.
Affine inverse() const
Compute the inverse matrix.
Axis-aligned generic rectangle that can be empty.
C area() const
Compute the rectangle's area.
void unionWith(CRect const &b)
Enlarge the rectangle to contain the argument.
bool intersects(CRect const &r) const
Check whether the rectangles have any common points.
void intersectWith(CRect const &b)
Leave only the area overlapping with the argument.
Axis aligned, non-empty, generic rectangle.
static CRect from_xywh(C x, C y, C w, C h)
Create rectangle from origin and dimensions.
C area() const
Compute the rectangle's area.
bool contains(GenericRect< C > const &r) const
Check whether the rectangle includes all points in the given rectangle.
bool intersects(GenericRect< C > const &r) const
Check whether the rectangles have any common points.
void expandBy(C amount)
Expand the rectangle in both directions by the specified amount.
Axis-aligned rectangle that can be empty.
Two-dimensional point that doubles as a vector.
Axis aligned, non-empty rectangle.
Minimal wrapper over Cairo.
void setSource(cairo_pattern_t *source)
cairo_surface_t * rawTarget()
DrawingSurface * surface()
void paint(double alpha=1.0)
void rectangle(Geom::Rect const &r)
void setOperator(cairo_operator_t op)
SVG drawing item for display.
virtual void _clipItem(DrawingContext &dc, RenderContext &rc, Geom::IntRect const &area) const
unsigned _cached_persistent
If set, will always be cached regardless of score.
unsigned _background_accumulate
Whether this element accumulates background (has any ancestor with enable-background: new)
void clip(DrawingContext &dc, RenderContext &rc, Geom::IntRect const &area) const
Rasterize the clipping path.
DrawingPattern * _fill_pattern
SPItem * _item
Used to associate DrawingItems with SPItems that created them.
@ RENDER_FILTER_BACKGROUND
void appendChild(DrawingItem *item)
void _setCached(bool cached, bool persistent=false)
Enable / disable storing the rendering in memory.
Geom::OptIntRect _cacheRect() const
Antialiasing _antialias
antialiasing level (default is Good)
CacheList::iterator _cache_iterator
unsigned render(DrawingContext &dc, RenderContext &rc, Geom::IntRect const &area, unsigned flags=0, DrawingItem const *stop_at=nullptr) const
Rasterize items.
std::unique_ptr< CacheData > _cache
bool style_vector_effect_size
Geom::Affine const & ctm() const
DrawingItem * pick(Geom::Point const &p, double delta, unsigned flags=0)
Get the item under the specified point.
Geom::OptIntRect _drawbox
Full visual bounding box - enlarged by filters, shrunk by clips and masks.
void setBlendMode(SPBlendMode blend_mode)
void setSensitive(bool sensitive)
Geom::OptIntRect _bbox
Bounding box in display (pixel) coords including stroke.
Drawing & drawing() const
virtual void _dropPatternCache()
void setOpacity(float opacity)
virtual void setStyle(SPStyle const *style, SPStyle const *context_style=nullptr)
Process information related to the new style.
unsigned _sensitive
Whether this item responds to events.
unsigned _has_cache_iterator
If set, _cache_iterator is valid.
std::unique_ptr< Inkscape::Filters::Filter > _filter
unsigned _propagate_state
double _cacheScore()
Compute the caching score.
bool unisolatedBlend() const
virtual unsigned _renderItem(DrawingContext &dc, RenderContext &rc, Geom::IntRect const &area, unsigned flags, DrawingItem const *stop_at) const
Geom::OptRect _item_bbox
Geometric bounding box in item's user space.
void setVisible(bool visible)
void setZOrder(unsigned zorder)
Move this item to the given place in the Z order of siblings. Does nothing if the item is not a norma...
virtual DrawingItem * _pickItem(Geom::Point const &p, double delta, unsigned flags)
void setAntialiasing(Antialiasing antialias)
bool style_vector_effect_fixed
virtual void setChildrenStyle(SPStyle const *context_style)
Recursively update children style.
std::unique_ptr< Geom::Affine > _transform
Incremental transform from parent to this item's coords.
void _markForUpdate(unsigned state, bool propagate)
Marks the item as needing a recomputation of internal data.
DrawingPattern * _stroke_pattern
void setFilterRenderer(std::unique_ptr< Filters::Filter > renderer)
Glib::ustring name() const
virtual bool _canClip() const
void setTransform(Geom::Affine const &trans)
void _renderOutline(DrawingContext &dc, RenderContext &rc, Geom::IntRect const &area, unsigned flags) const
DrawingItem(Drawing &drawing)
unsigned _background_new
Whether enable-background: new is set for this element.
bool _contains_unisolated_blend
void setStrokePattern(DrawingPattern *pattern)
void update(Geom::IntRect const &area=Geom::IntRect::infinite(), UpdateContext const &ctx=UpdateContext(), unsigned flags=STATE_ALL, unsigned reset=0)
Update derived data before operations.
bool isAncestorOf(DrawingItem const *item) const
Returns true if item is among the descendants. Will return false if item == this.
void prependChild(DrawingItem *item)
SPStyle const * _context_style
Geom::Affine _ctm
Total transform from item coords to display coords.
void setIsolation(bool isolation)
virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset)
void setFillPattern(DrawingPattern *pattern)
void _invalidateFilterBackground(Geom::IntRect const &area)
void _markForRendering()
Marks the current visual bounding box of the item for redrawing.
bool style_vector_effect_rotate
Geom::Affine transform() const
void setMask(DrawingItem *item)
void setItemBounds(Geom::OptRect const &bounds)
void setClip(DrawingItem *item)
void recursivePrintTree(unsigned level=0) const
Drawing tree node used for rendering paints.
Drawing surface that remembers its origin.
uint32_t maskOutlineColor() const
CacheList _candidate_items
Geom::OptIntRect const & cacheLimit() const
ColorMode colorMode() const
CanvasItemDrawing * getCanvasItemDrawing()
uint32_t clipOutlineColor() const
RenderMode renderMode() const
bool outlineOverlay() const
auto & grayscaleMatrix() const
std::optional< Antialiasing > _antialiasing_override
std::set< DrawingItem * > _cached_items
char const * getId() const
Returns the objects current ID string.
T< SPAttr::ENABLE_BACKGROUND, SPIEnum< SPEnableBackground > > enable_background
enable-background, used for defining where filter effects get their background image
T< SPAttr::VECTOR_EFFECT, SPIVectorEffect > vector_effect
vector effect
static char const *const current
Cairo drawing context with Inkscape extensions.
Group belonging to an SVG drawing element.
static constexpr auto CACHE_SCORE_THRESHOLD
Do not consider objects for caching below this score.
Canvas item belonging to an SVG drawing element.
Canvas belonging to SVG pattern.
Cairo surface that remembers its origin.
struct _cairo_surface cairo_surface_t
Group belonging to an SVG drawing element.
GenericOptRect< IntCoord > OptIntRect
Affine identity()
Create an identity matrix.
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
std::vector< Point > intersect(const xAx &C1, const xAx &C2)
void ExtractRGB32(guint32 px, guint32 &r, guint32 &g, guint &b)
Helper class to stream background task notifications as a series of messages.
Geom::PathVector outline(Geom::Path const &input, double width, double miter, LineJoinType join, LineCapType butt, double tolerance)
Strokes the path given by input.
void propagate_antialias(SPShapeRendering shape_rendering, DrawingItem &item)
Propagate element's shape rendering attribute into internal anti-aliasing setting of DrawingItem.
void apply_antialias(DrawingContext &dc, Antialiasing antialias)
Apply antialias setting to Cairo.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
std::uint32_t outline_color
@ SP_CSS_SHAPE_RENDERING_AUTO
@ SP_CSS_SHAPE_RENDERING_GEOMETRICPRECISION
@ SP_CSS_SHAPE_RENDERING_CRISPEDGES
@ SP_CSS_SHAPE_RENDERING_OPTIMIZESPEED
@ SP_CSS_ISOLATION_ISOLATE
SPStyle - a style object for SPItem objects.