summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2017-11-30 10:35:36 +0000
committerTavmjong Bah <tavmjong@free.fr>2017-11-30 10:35:36 +0000
commit542441374b6d6129b69470da18e5230dd421bc21 (patch)
tree12caf1d88b563f5c10614e1624445f2f9aaba96c /src
parentStore device-scale and propogate value where necessary. (diff)
downloadinkscape-542441374b6d6129b69470da18e5230dd421bc21.tar.gz
inkscape-542441374b6d6129b69470da18e5230dd421bc21.zip
Support device scale in filters.
Diffstat (limited to 'src')
-rw-r--r--src/display/nr-filter-diffuselighting.cpp23
-rw-r--r--src/display/nr-filter-displacement-map.cpp11
-rw-r--r--src/display/nr-filter-gaussian.cpp14
-rw-r--r--src/display/nr-filter-image.cpp23
-rw-r--r--src/display/nr-filter-morphology.cpp5
-rw-r--r--src/display/nr-filter-slot.cpp8
-rw-r--r--src/display/nr-filter-slot.h7
-rw-r--r--src/display/nr-filter-specularlighting.cpp20
-rw-r--r--src/display/nr-filter-turbulence.cpp23
-rw-r--r--src/display/nr-filter.cpp5
-rw-r--r--src/display/nr-light.cpp22
-rw-r--r--src/display/nr-light.h6
12 files changed, 127 insertions, 40 deletions
diff --git a/src/display/nr-filter-diffuselighting.cpp b/src/display/nr-filter-diffuselighting.cpp
index c6724e3ba..ed5afa82a 100644
--- a/src/display/nr-filter-diffuselighting.cpp
+++ b/src/display/nr-filter-diffuselighting.cpp
@@ -83,9 +83,10 @@ private:
struct DiffusePointLight : public DiffuseLight {
DiffusePointLight(cairo_surface_t *bumpmap, SPFePointLight *light, guint32 color,
- Geom::Affine const &trans, double scale, double diffuse_constant, double x0, double y0)
+ Geom::Affine const &trans, double scale, double diffuse_constant,
+ double x0, double y0, int device_scale)
: DiffuseLight(bumpmap, scale, diffuse_constant)
- , _light(light, color, trans)
+ , _light(light, color, trans, device_scale)
, _x0(x0)
, _y0(y0)
{
@@ -105,9 +106,10 @@ private:
struct DiffuseSpotLight : public DiffuseLight {
DiffuseSpotLight(cairo_surface_t *bumpmap, SPFeSpotLight *light, guint32 color,
- Geom::Affine const &trans, double scale, double diffuse_constant, double x0, double y0)
+ Geom::Affine const &trans, double scale, double diffuse_constant,
+ double x0, double y0, int device_scale)
: DiffuseLight(bumpmap, scale, diffuse_constant)
- , _light(light, color, trans)
+ , _light(light, color, trans, device_scale)
, _x0(x0)
, _y0(y0)
{}
@@ -160,11 +162,18 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot)
set_cairo_surface_ci(out, ci_fp );
guint32 color = SP_RGBA32_F_COMPOSE( r, g, b, 1.0 );
+ int device_scale = slot.get_device_scale();
+
Geom::Rect slot_area = slot.get_slot_area();
Geom::Point p = slot_area.min();
+
+ // trans has inverse y... so we can't just scale by device_scale! We must instead explicitly
+ // scale the point and spot light coordinates (as well as "scale").
+
Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb();
+
double x0 = p[Geom::X], y0 = p[Geom::Y];
- double scale = surfaceScale * trans.descrim();
+ double scale = surfaceScale * trans.descrim() * device_scale;
switch (light_type) {
case DISTANT_LIGHT:
@@ -173,11 +182,11 @@ void FilterDiffuseLighting::render_cairo(FilterSlot &slot)
break;
case POINT_LIGHT:
ink_cairo_surface_synthesize(out,
- DiffusePointLight(input, light.point, color, trans, scale, diffuseConstant, x0, y0));
+ DiffusePointLight(input, light.point, color, trans, scale, diffuseConstant, x0, y0, device_scale));
break;
case SPOT_LIGHT:
ink_cairo_surface_synthesize(out,
- DiffuseSpotLight(input, light.spot, color, trans, scale, diffuseConstant, x0, y0));
+ DiffuseSpotLight(input, light.spot, color, trans, scale, diffuseConstant, x0, y0, device_scale));
break;
default: {
cairo_t *ct = cairo_create(out);
diff --git a/src/display/nr-filter-displacement-map.cpp b/src/display/nr-filter-displacement-map.cpp
index c0d1ae411..fb2f3a0f0 100644
--- a/src/display/nr-filter-displacement-map.cpp
+++ b/src/display/nr-filter-displacement-map.cpp
@@ -71,12 +71,17 @@ private:
void FilterDisplacementMap::render_cairo(FilterSlot &slot)
{
+ std::cout << "FilterDisplacementMap:" << std::endl;
cairo_surface_t *texture = slot.getcairo(_input);
cairo_surface_t *map = slot.getcairo(_input2);
cairo_surface_t *out = ink_cairo_surface_create_identical(texture);
// color_interpolation_filters for out same as texture. See spec.
copy_cairo_surface_ci( texture, out );
+ std::cout << " texture: " << cairo_image_surface_get_width(texture) << std::endl;
+ std::cout << " map: " << cairo_image_surface_get_width(map) << std::endl;
+ std::cout << " out: " << cairo_image_surface_get_width(out) << std::endl;
+
// We may need to transform map surface to correct color interpolation space. The map surface
// might be used as input to another primitive but it is likely that all the primitives in a given
// filter use the same color interpolation space so we don't copy the map before converting.
@@ -87,8 +92,10 @@ void FilterDisplacementMap::render_cairo(FilterSlot &slot)
set_cairo_surface_ci( map, ci_fp );
Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb();
- double scalex = scale * trans.expansionX();
- double scaley = scale * trans.expansionY();
+
+ int device_scale = slot.get_device_scale();
+ double scalex = scale * trans.expansionX() * device_scale;
+ double scaley = scale * trans.expansionY() * device_scale;
ink_cairo_surface_synthesize(out, Displace(texture, map, Xchannel, Ychannel, scalex, scaley));
diff --git a/src/display/nr-filter-gaussian.cpp b/src/display/nr-filter-gaussian.cpp
index cdd01e75e..2227edfef 100644
--- a/src/display/nr-filter-gaussian.cpp
+++ b/src/display/nr-filter-gaussian.cpp
@@ -583,6 +583,12 @@ void FilterGaussian::render_cairo(FilterSlot &slot)
double deviation_x_orig = dx * trans.expansionX();
double deviation_y_orig = dy * trans.expansionY();
+
+ int device_scale = slot.get_device_scale();
+
+ deviation_x_orig *= device_scale;
+ deviation_y_orig *= device_scale;
+
cairo_format_t fmt = cairo_image_surface_get_format(in);
int bytes_per_pixel = 0;
switch (fmt) {
@@ -604,7 +610,7 @@ void FilterGaussian::render_cairo(FilterSlot &slot)
int x_step = 1 << _effect_subsample_step_log2(deviation_x_orig, quality);
int y_step = 1 << _effect_subsample_step_log2(deviation_y_orig, quality);
bool resampling = x_step > 1 || y_step > 1;
- int w_orig = ink_cairo_surface_get_width(in);
+ int w_orig = ink_cairo_surface_get_width(in); // Pixels
int h_orig = ink_cairo_surface_get_height(in);
int w_downsampled = resampling ? static_cast<int>(ceil(static_cast<double>(w_orig)/x_step))+1 : w_orig;
int h_downsampled = resampling ? static_cast<int>(ceil(static_cast<double>(h_orig)/y_step))+1 : h_orig;
@@ -633,8 +639,10 @@ void FilterGaussian::render_cairo(FilterSlot &slot)
cairo_surface_t *downsampled = NULL;
if (resampling) {
+ // Divide by device scale as w_downsampled is in pixels while
+ // cairo_surface_create_similar() uses device units.
downsampled = cairo_surface_create_similar(in, cairo_surface_get_content(in),
- w_downsampled, h_downsampled);
+ w_downsampled/device_scale, h_downsampled/device_scale);
cairo_t *ct = cairo_create(downsampled);
cairo_scale(ct, static_cast<double>(w_downsampled)/w_orig, static_cast<double>(h_downsampled)/h_orig);
cairo_set_source_surface(ct, in, 0, 0);
@@ -671,7 +679,7 @@ void FilterGaussian::render_cairo(FilterSlot &slot)
cairo_surface_mark_dirty(downsampled);
if (resampling) {
cairo_surface_t *upsampled = cairo_surface_create_similar(downsampled, cairo_surface_get_content(downsampled),
- w_orig, h_orig);
+ w_orig/device_scale, h_orig/device_scale);
cairo_t *ct = cairo_create(upsampled);
cairo_scale(ct, static_cast<double>(w_orig)/w_downsampled, static_cast<double>(h_orig)/h_downsampled);
cairo_set_source_surface(ct, downsampled, 0, 0);
diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp
index 7e859314a..86ebb49cb 100644
--- a/src/display/nr-filter-image.cpp
+++ b/src/display/nr-filter-image.cpp
@@ -47,6 +47,7 @@ FilterImage::~FilterImage()
void FilterImage::render_cairo(FilterSlot &slot)
{
+ std::cout << "FilterImage::render_cairo: Entrance" << std::endl;
if (!feImageHref)
return;
@@ -78,8 +79,11 @@ void FilterImage::render_cairo(FilterSlot &slot)
if( feImageWidth == 0 ) feImageWidth = bbox_width;
if( feImageHeight == 0 ) feImageHeight = bbox_height;
+ int device_scale = slot.get_device_scale();
+
// Internal image, like <use>
if (from_element) {
+ std::cout << " Internal image" << std::endl;
if (!SVGElem) return;
// TODO: do not recreate the rendering tree every time
@@ -108,8 +112,12 @@ void FilterImage::render_cairo(FilterSlot &slot)
*/
Geom::Rect sa = slot.get_slot_area();
- cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
- sa.width(), sa.height());
+ cairo_surface_t *out =
+ cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ sa.width() * device_scale,
+ sa.height() * device_scale);
+ cairo_surface_set_device_scale(out, device_scale, device_scale);
+
Inkscape::DrawingContext dc(out, sa.min());
dc.transform(user2pb); // we are now in primitive units
dc.translate(feImageX, feImageY);
@@ -128,11 +136,14 @@ void FilterImage::render_cairo(FilterSlot &slot)
slot.set(_output, out);
cairo_surface_destroy(out);
+ std::cout << " feImage: out: " << cairo_image_surface_get_width( out) << std::endl;
+ std::cout << "FilterImage::render_cairo: Exit 2" << std::endl;
return;
}
// External image, like <image>
if (!image && !broken_ref) {
+ std::cout << " External image" << std::endl;
broken_ref = true;
/* TODO: If feImageHref is absolute, then use that (preferably handling the
@@ -170,10 +181,12 @@ void FilterImage::render_cairo(FilterSlot &slot)
}
cairo_surface_t *image_surface = image->getSurfaceRaw();
-
+ std::cout << " image: " << cairo_image_surface_get_width(image_surface) << std::endl;
Geom::Rect sa = slot.get_slot_area();
cairo_surface_t *out = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
- sa.width(), sa.height());
+ sa.width() * device_scale, sa.height() * device_scale);
+ cairo_surface_set_device_scale( out, device_scale, device_scale );
+ std::cout << " out: " << cairo_image_surface_get_width(out) << std::endl;
// For the moment, we'll assume that any image is in sRGB color space
// set_cairo_surface_ci(out, SP_CSS_COLOR_INTERPOLATION_SRGB);
@@ -278,8 +291,8 @@ void FilterImage::render_cairo(FilterSlot &slot)
cairo_set_source_surface(ct, image_surface, 0, 0);
cairo_paint(ct);
cairo_destroy(ct);
-
slot.set(_output, out);
+ std::cout << "FilterImage::render_cairo: Exit 2" << std::endl;
}
bool FilterImage::can_handle_affine(Geom::Affine const &)
diff --git a/src/display/nr-filter-morphology.cpp b/src/display/nr-filter-morphology.cpp
index b6e5052e1..a06033e80 100644
--- a/src/display/nr-filter-morphology.cpp
+++ b/src/display/nr-filter-morphology.cpp
@@ -171,9 +171,10 @@ void FilterMorphology::render_cairo(FilterSlot &slot)
return;
}
+ int device_scale = slot.get_device_scale();
Geom::Affine p2pb = slot.get_units().get_matrix_primitiveunits2pb();
- double xr = fabs(xradius * p2pb.expansionX());
- double yr = fabs(yradius * p2pb.expansionY());
+ double xr = fabs(xradius * p2pb.expansionX()) * device_scale;
+ double yr = fabs(yradius * p2pb.expansionY()) * device_scale;
int bpp = cairo_image_surface_get_format(input) == CAIRO_FORMAT_A8 ? 1 : 4;
cairo_surface_t *interm = ink_cairo_surface_create_identical(input);
diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp
index a6e0c5c4e..9d76462c0 100644
--- a/src/display/nr-filter-slot.cpp
+++ b/src/display/nr-filter-slot.cpp
@@ -270,6 +270,14 @@ int FilterSlot::get_blurquality(void) {
return blurquality;
}
+void FilterSlot::set_device_scale(int const s) {
+ device_scale = s;
+}
+
+int FilterSlot::get_device_scale() {
+ return device_scale;
+}
+
Geom::Rect FilterSlot::get_slot_area() const {
Geom::Point p(_slot_x, _slot_y);
Geom::Point dim(_slot_w, _slot_h);
diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h
index 166b2e718..d73e9d91c 100644
--- a/src/display/nr-filter-slot.h
+++ b/src/display/nr-filter-slot.h
@@ -72,6 +72,12 @@ public:
/** Gets the gaussian filtering quality. Affects used interpolation methods */
int get_blurquality(void);
+ /** Sets the device scale; for high DPI monitors. */
+ void set_device_scale(int const s);
+
+ /** Gets the device scale; for high DPI monitors. */
+ int get_device_scale();
+
FilterUnits const &get_units() const { return _units; }
Geom::Rect get_slot_area() const;
@@ -98,6 +104,7 @@ private:
int _last_out;
FilterQuality filterquality;
int blurquality;
+ int device_scale;
cairo_surface_t *_get_transformed_source_graphic();
cairo_surface_t *_get_transformed_background();
diff --git a/src/display/nr-filter-specularlighting.cpp b/src/display/nr-filter-specularlighting.cpp
index 2ce02adee..e8d03d42e 100644
--- a/src/display/nr-filter-specularlighting.cpp
+++ b/src/display/nr-filter-specularlighting.cpp
@@ -93,9 +93,9 @@ private:
struct SpecularPointLight : public SpecularLight {
SpecularPointLight(cairo_surface_t *bumpmap, SPFePointLight *light, guint32 color,
Geom::Affine const &trans, double scale, double specular_constant,
- double specular_exponent, double x0, double y0)
+ double specular_exponent, double x0, double y0, int device_scale)
: SpecularLight(bumpmap, scale, specular_constant, specular_exponent)
- , _light(light, color, trans)
+ , _light(light, color, trans, device_scale)
, _x0(x0)
, _y0(y0)
{
@@ -117,9 +117,9 @@ private:
struct SpecularSpotLight : public SpecularLight {
SpecularSpotLight(cairo_surface_t *bumpmap, SPFeSpotLight *light, guint32 color,
Geom::Affine const &trans, double scale, double specular_constant,
- double specular_exponent, double x0, double y0)
+ double specular_exponent, double x0, double y0, int device_scale)
: SpecularLight(bumpmap, scale, specular_constant, specular_exponent)
- , _light(light, color, trans)
+ , _light(light, color, trans, device_scale)
, _x0(x0)
, _y0(y0)
{}
@@ -173,11 +173,17 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot)
set_cairo_surface_ci(out, ci_fp );
guint32 color = SP_RGBA32_F_COMPOSE( r, g, b, 1.0 );
+ int device_scale = slot.get_device_scale();
+
+ // trans has inverse y... so we can't just scale by device_scale! We must instead explicitly
+ // scale the point and spot light coordinates (as well as "scale").
+
Geom::Affine trans = slot.get_units().get_matrix_primitiveunits2pb();
+
Geom::Point p = slot.get_slot_area().min();
double x0 = p[Geom::X];
double y0 = p[Geom::Y];
- double scale = surfaceScale * trans.descrim();
+ double scale = surfaceScale * trans.descrim() * device_scale;
double ks = specularConstant;
double se = specularExponent;
@@ -188,11 +194,11 @@ void FilterSpecularLighting::render_cairo(FilterSlot &slot)
break;
case POINT_LIGHT:
ink_cairo_surface_synthesize(out,
- SpecularPointLight(input, light.point, color, trans, scale, ks, se, x0, y0));
+ SpecularPointLight(input, light.point, color, trans, scale, ks, se, x0, y0, device_scale));
break;
case SPOT_LIGHT:
ink_cairo_surface_synthesize(out,
- SpecularSpotLight(input, light.spot, color, trans, scale, ks, se, x0, y0));
+ SpecularSpotLight(input, light.spot, color, trans, scale, ks, se, x0, y0, device_scale));
break;
default: {
cairo_t *ct = cairo_create(out);
diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp
index 1397c0f34..349bcc242 100644
--- a/src/display/nr-filter-turbulence.cpp
+++ b/src/display/nr-filter-turbulence.cpp
@@ -378,6 +378,19 @@ void FilterTurbulence::render_cairo(FilterSlot &slot)
cairo_surface_t *input = slot.getcairo(_input);
cairo_surface_t *out = ink_cairo_surface_create_same_size(input, CAIRO_CONTENT_COLOR_ALPHA);
+ // It is probably possible to render at a device scale greater than one
+ // but for the moment rendering at a device scale of one is the easiest.
+ // cairo_image_surface_get_width() returns width in pixels but
+ // cairo_surface_create_similar() requires width in device units so divide by device scale.
+ // We are rendering at a device scale of 1... so divide by device scale again!
+ double x_scale = 0;
+ double y_scale = 0;
+ cairo_surface_get_device_scale(input, &x_scale, &y_scale);
+ int width = ceil(cairo_image_surface_get_width( input)/x_scale/x_scale);
+ int height = ceil(cairo_image_surface_get_height(input)/y_scale/y_scale);
+ cairo_surface_t *temp = cairo_surface_create_similar (input, CAIRO_CONTENT_COLOR_ALPHA, width, height);
+ cairo_surface_set_device_scale( temp, 1, 1 );
+
// color_interpolation_filter is determined by CSS value (see spec. Turbulence).
if( _style ) {
set_cairo_surface_ci(out, (SPColorInterpolation)_style->color_interpolation_filters.computed );
@@ -395,8 +408,16 @@ void FilterTurbulence::render_cairo(FilterSlot &slot)
Geom::Rect slot_area = slot.get_slot_area();
double x0 = slot_area.min()[Geom::X];
double y0 = slot_area.min()[Geom::Y];
+ ink_cairo_surface_synthesize(temp, Turbulence(*gen, unit_trans, x0, y0));
+
+ // cairo_surface_write_to_png( temp, "turbulence0.png" );
+
+ cairo_t *ct = cairo_create(out);
+ cairo_set_source_surface(ct, temp, 0, 0);
+ cairo_paint(ct);
+ cairo_destroy(ct);
- ink_cairo_surface_synthesize(out, Turbulence(*gen, unit_trans, x0, y0));
+ cairo_surface_destroy(temp);
cairo_surface_mark_dirty(out);
diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp
index d430553d4..a1bea4fce 100644
--- a/src/display/nr-filter.cpp
+++ b/src/display/nr-filter.cpp
@@ -42,6 +42,7 @@
#include "display/drawing.h"
#include "display/drawing-item.h"
#include "display/drawing-context.h"
+#include "display/drawing-surface.h"
#include <2geom/affine.h>
#include <2geom/rect.h>
#include "svg/svg-length.h"
@@ -95,6 +96,9 @@ Filter::~Filter()
int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, DrawingContext *bgdc)
{
+ // std::cout << "Filter::render() for: " << const_cast<Inkscape::DrawingItem *>(item)->name() << std::endl;
+ // std::cout << " graphic drawing_scale: " << graphic.surface()->device_scale() << std::endl;
+
if (_primitive.empty()) {
// when no primitives are defined, clear source graphic
graphic.setSource(0,0,0,0);
@@ -150,6 +154,7 @@ int Filter::render(Inkscape::DrawingItem const *item, DrawingContext &graphic, D
FilterSlot slot(const_cast<Inkscape::DrawingItem*>(item), bgdc, graphic, units);
slot.set_quality(filterquality);
slot.set_blurquality(blurquality);
+ slot.set_device_scale(graphic.surface()->device_scale());
for (unsigned i = 0 ; i < _primitive.size() ; i++) {
_primitive[i]->render_cairo(slot);
diff --git a/src/display/nr-light.cpp b/src/display/nr-light.cpp
index 0e9a55a9f..791ae53da 100644
--- a/src/display/nr-light.cpp
+++ b/src/display/nr-light.cpp
@@ -41,11 +41,11 @@ void DistantLight::light_components(NR::Fvector &lc) {
lc[LIGHT_BLUE] = SP_RGBA32_B_U(color);
}
-PointLight::PointLight(SPFePointLight *light, guint32 lighting_color, const Geom::Affine &trans) {
+PointLight::PointLight(SPFePointLight *light, guint32 lighting_color, const Geom::Affine &trans, int device_scale) {
color = lighting_color;
- l_x = light->x;
- l_y = light->y;
- l_z = light->z;
+ l_x = light->x * device_scale;
+ l_y = light->y * device_scale;
+ l_z = light->z * device_scale;
NR::convert_coord(l_x, l_y, l_z, trans);
}
@@ -64,15 +64,15 @@ void PointLight::light_components(NR::Fvector &lc) {
lc[LIGHT_BLUE] = SP_RGBA32_B_U(color);
}
-SpotLight::SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::Affine &trans) {
+SpotLight::SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::Affine &trans, int device_scale) {
double p_x, p_y, p_z;
color = lighting_color;
- l_x = light->x;
- l_y = light->y;
- l_z = light->z;
- p_x = light->pointsAtX;
- p_y = light->pointsAtY;
- p_z = light->pointsAtZ;
+ l_x = light->x * device_scale;
+ l_y = light->y * device_scale;
+ l_z = light->z * device_scale;
+ p_x = light->pointsAtX * device_scale;
+ p_y = light->pointsAtY * device_scale;
+ p_z = light->pointsAtZ * device_scale;
cos_lca = std::cos(M_PI / 180 * light->limitingConeAngle);
speExp = light->specularExponent;
NR::convert_coord(l_x, l_y, l_z, trans);
diff --git a/src/display/nr-light.h b/src/display/nr-light.h
index 57c421f4a..2eacdc92b 100644
--- a/src/display/nr-light.h
+++ b/src/display/nr-light.h
@@ -69,8 +69,9 @@ class PointLight {
* \param trans the transformation between absolute coordinate (those
* employed in the sp light object) and current coordinate (those
* employed in the rendering)
+ * \param device_scale for high DPI monitors.
*/
- PointLight(SPFePointLight *light, guint32 lighting_color, const Geom::Affine &trans);
+ PointLight(SPFePointLight *light, guint32 lighting_color, const Geom::Affine &trans, int device_scale = 1);
virtual ~PointLight();
/**
* Computes the light vector of the distant light at point (x,y,z).
@@ -109,8 +110,9 @@ class SpotLight {
* \param trans the transformation between absolute coordinate (those
* employed in the sp light object) and current coordinate (those
* employed in the rendering)
+ * \param device_scale for high DPI monitors.
*/
- SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::Affine &trans);
+ SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::Affine &trans, int device_scale = 1);
virtual ~SpotLight();
/**