We already did some improvements, but I wanted to clean
this up somewhat. Reason for the needed corrections was
in principle the sqrt()-based general calculation of
the HoldTime in the default implementation of
calculateCombinedHoldCyclesInSeconds. The original idea
was to hold huge data shorter due to memory constraints.
To solve that we added an adapted version to
CairoPixelProcessor2D.
With lessons learned I decided to remove that and
provide a revised general implementation based on linear
scaling of the HoldTime. Based on assuming the seen
huge Bitmap and estimating 20min for it, just create a
factor and multiply with SizeInBytes.
I checked that and it works as intended. It will spare
us from this problem re-occurring with future SDPRs.
NOTE: This still keeps the CairoSDPR-specific avoiding
of buffering of small Bitmaps when these are available
from Bitmap directly. This stays useful and is
Cairo-specific.
Signed-off-by: Armin Le Grand (collabora) <Armin.LeGrand@collabora.com>
Change-Id: I30c7361c6fbfaf0be90be353091cbaf831db5cd2
Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/2005
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit a3d3ae5e931a04ff5718382ccffe9f16de336a42)
(cherry picked from commit 7550c6ea0bb82f7574e4b974f8d24bd1662a878b)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205991
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Tested-by: Jenkins
If we have a really 'big' pixel-based graphic the cost for creating
the mip-map entries is high. If that is the case, force keeping this
entry alive and not getting flushed by using a large number of
seconds. In that case the local MipMap is more important than the
memory kept allocated for fast repaints.
To detect 'big' graphics, compare to an assumed ScreenSize (may also
be fetched from real screen if needed). To react, create a buffer
residing time of one hour (increase if needed).
NOTE: This will increase MemoryFootPrint if isCairoCompatible
is false by holding the local cairo_surface_t in CairoSurfaceHelper
longer than before.
Change-Id: I1cf726f00d459bc0cb19bb1d202e64e010061426
Reviewed-on: https://gerrit.collaboraoffice.com/c/core/+/1134
Tested-by: Jenkins CPCI <releng@collaboraoffice.com>
Reviewed-by: Tomaž Vajngerl <tomaz.vajngerl@collabora.com>
(cherry picked from commit 2e1b0a51a745e615ed7e2f22666cc4aa4e005451)
(cherry picked from commit c2c58c177ae822906fe2c558546851643fe54247)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/205988
Tested-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Fixes warnings like this one seen in a clang-cl (21.1.8)
build on Windows:
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\basegfx/utils/systemdependentdata.hxx(45,16): warning: 'dllimport' attribute only applies to functions, variables, classes, and Objective-C
interfaces [-Wignored-attributes]
45 | enum class BASEGFX_DLLPUBLIC SDD_Type : sal_uInt16 {
| ^
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\basegfx/basegfxdllapi.h(33,27):: note: expanded from macro 'BASEGFX_DLLPUBLIC'
33 | #define BASEGFX_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
| ^
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\sal/types.h(210,47): note: expanded from macro 'SAL_DLLPUBLIC_IMPORT'
210 | # define SAL_DLLPUBLIC_IMPORT __declspec(dllimport)
| ^
and
In file included from C:/Users/mwegh/development/git/libreoffice-WORKTREE/oox/source/drawingml/diagram/datamodelcontext.cxx:20:
In file included from C:/Users/mwegh/development/git/libreoffice-WORKTREE/oox/source/drawingml/diagram\datamodelcontext.hxx:24:
In file included from C:/Users/mwegh/development/git/libreoffice-WORKTREE/oox/source/drawingml/diagram\datamodel_oox.hxx:29:
In file included from C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\svx/diagram/datamodel_svx.hxx:30:
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\svx/diagram/DomMapFlag.hxx(28,12): warning: 'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces
[-Wignored-attributes]
28 | enum class SVXCORE_DLLPUBLIC DomMapFlag : sal_uInt16
| ^
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\svx/svxdllapi.h(35,27): note: expanded from macro 'SVXCORE_DLLPUBLIC'
35 | #define SVXCORE_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
| ^
C:/Users/mwegh/development/git/libreoffice-WORKTREE/include\sal/types.h(210,47): note: expanded from macro 'SAL_DLLPUBLIC_IMPORT'
210 | # define SAL_DLLPUB[build CXX] oox/source/drawingml/diagram/layoutatomvisitorbase.cxx
LIC_IMPORT __declspec(dllimport)
|
Change-Id: Id472eea3ccb9270e87cfce4e5e6761c566fdbdc0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/202144
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
All the changes should go through BColorStops interface and not
directly.
Change-Id: I4c6dd42f8d6b6c43cdcf9d53557ccb12f8d0507c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195386
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Jenkins
After recent commit 851fb75779
recheck these directories in include/ again
to test drive the new --headersfwd mode of bin/find-unneeded-includes
Change-Id: I0ede437c4f9958cd98210ed1760a5b98ea8bd1ad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192377
Tested-by: Jenkins
Reviewed-by: Gabor Kelemen <gabor.kelemen@collabora.com>
Detect where created when a RGBA gradient could be
used directly and create a primitive representing
that, a PolyPolygonRGBAGradientPrimitive2D.
That primitive decomposes to what was created before,
so no primitive renderer has to be touched, all will
work as before.
NOTE: That helper primitive just holds references to
what would be created anyways, so one depth step
added but not really any additional data.
This is the 1st step for direct support, the 2nd is
to then detect and use that primitive in SDPR
implementations directly.
Change-Id: I4f247636ce58a8a1fd1e0df32dabed0d6cc10d0e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170527
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Up to now that genereal buffering mechanism used
typeid.*hash_code to identify the class. As we
have learned this is not safe. Thus I changed it
to use enum'ed SystemDependentDataType definitions
Change-Id: I803912ec419290db1d40bae0bc41364fad64cbfd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170385
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Added and corrected quite some stuff to this basic
construct provided by Caolan (thanks again!). No
detailed descriptions here, but it's getting more
complete and faster.
May contain errors and is primitive-complete in the
sense that all gets rendered, but some basic stuff
that should be directly supported is still missing,
e.g. text rendering.
Adding this to allow people to check it out (speed)
also since it's not yet used as default in master,
so it's safe and also safes the changes publically.
To test it, use TEST_SYSTEM_PRIMITIVE_RENDERER as
set EnvVar in linux systems.
Change-Id: I25f795c9ea4ad4f3b99591304f8803dffa499436
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168911
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
create a plugin that finds methods we can mark as final because they are
not override in subclasses.
Which is useful both as documentation (telling you that you don't need
to worry about subclasses changing the implementation under you),
and for performance, letting the compiler elide virtual calls in many
cases.
Apply the results to a subset of stuff in /include
Change-Id: I7b5cc893ec2f343bc356bfc338e4cf531ffba1e0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165054
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
As part of the efforts in #157664 to remove redundant definitions of
operator!=, to upgrade the codebase to C++20, this commit removes the
remaining definitions in the basegfx module.
Change-Id: I19f2b9ddf42185435313445c8395a851030e2149
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165199
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Jenkins
This is needed because the module dependencies are an issues if
the conversion is done in basegfx. The bigger issue will come when
the ComplexColor conversion will be done as basegfx can't depend on
docmodel because of circular dependencies.
The BGradient is also more suitable for docmodel anyway as the
previously it was part of the model and is not a basic (gfx)
type - however this doesn't move the whole BGradient into docmodel
yet.
Change-Id: Id91ce52232f89f00e09b451c13da36e2854ae14b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155674
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Unfortunately SVG export is based on metafiles and thus there
is (in principle) no way to get the BGradient/ColorStop/MCGR
data transfered as needed. For that, using UNO API to read the
model or using B2DPrimitives would help - as is better for the
export respectively.
Since there is not the time to re-design SVG export I added
this 'compromize' as a fix. It gets the needed data transported
over the metafile (that part is the compromize). It then
exports the MCGR data to SVG (at least - as was already there -
if it's a linear/axial gradient). This happens now with all
Gradient Stops when there is a MCGR gradient. That part is/will
hopefully be re-usable if SVG export gets redesigned.
I also added a handling for StepCount feature, so when used (in
LO, others do not have that) 'hard' color stops get generated
to make the gradient look identical for SVG export.
Had to make adding of that extra-information in metafiles
dependent on exporting really to SVG. There are 51 cases which
use 'MetaActionType::COMMENT' which would potentially have
to be adapted.
Also added code to solve the problem for TransparencePrimitive2D
at VclMetafileProcessor2D::processTransparencePrimitive2D. This
will now - also only for SVG export - directly create the needed
MetaFloatTransparentAction and add additional MCGR information.
This will be used on SVG export to write a 'Mask' as was done
before. This is now capable of creating fill MCGR-Masks in
the sense that any number of TransparencyStops will be supported.
Change-Id: Ic6d022714eae96b8fbc09e60652851ac5799b757
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152623
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
When exporting a shape with an axial gradient fill to OOXML, it is
converted to a linear gradient with multiple color stops. Versions
before MCGR had recreated it as axial gradient on import from OOXML.
But now LO is able to handle multiple color stops and so the linear
gradient from OOXML is imported as linear gradient in LO.
When such file is then written as ODF, the multiple color stops are
in elements in extended namespace and versions before MCGR do not
understand them. They show only the first and last color (which are
equal) and the gradient is lost.
With this patch LO converts the linear gradient back to an axial gradient
on export to ODF. The exported axial gradient is rendered in a version
with MCGR same as the linear gradient when opening the OOXML file. The
difference is, that versions without MCGR now render an axial gradient
with two colors.
Change-Id: I2b416b4cdca75d8327107a4f259d63c2e6e97ac3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152574
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
For better compatibility with LO versions before MCGR, try
to re-create a 'border' value based on the existing GradientSteps.
With MCGR we do not need 'border' anymore in quite some cases since
no Start/EndColor at 0.0 resp. 1.0 is explicitely needed. Since we
(unfortunately need to) internally continue to support border
anyways it does no harm to fallback to use the border value - if
there is an equivalent representation as this helper checks for.
For exports that do not support 'border' this will be adapted as
needed (see tryToApplyBorder())
Change-Id: If98c64039ff97143d4b5c92ac2a950e70f5bb70a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152395
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Due to tdf#155362 I added code to be able in case we
would need it to convert a BGradient using added
tooling from having offsets in the GradientSteps
and no border to adapted GradientSteps and border.
This is preferrable due to our GradientStyle_RECT
(and GradientStyle_ELLIPTICAL too) use that 'non-
linear' paint aka move-two-pixels-inside, someone
else called it 'frame-paint'. This does not bode
well with the border being applied 'linear' at the
same time (argh). Thus - while in principle all is
correct when re-importing a GradientStyle_RECT
with a border after export to pptx, it looks
slightly better ('correcter') wen doing so. That is
because when being able to and restoring a border
at least that border part *is* applied linearly.
I took the chance to further apply tooling, move
it to classes involved and instead of awt::Gradient2
use more basegfx::BGradient since it can and does
host tooling. This is also a preparation to be
able to adapt (restore) border in case of turn-
around in ODF where the importing instance is before
MCGR existance and has to handle Start/EndColor.
Needed to take more care with using BGradient instead
of awt::Gradient2 for initialization, also better
dividing/organization of tooling, already preparation
to use for other purposes.
Change-Id: I2d3a4240a5ac6fff9211b46642ee80366dc09e3d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152194
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Added code to make WriteGradientFill directly use the
available BGradient implementation. The goal is to
never directly work on awt::Gradient2, but use
BGradient & it's tooling methods.
Added constructors and tooling to BGradient and
BColorStops to make that easier (single line
conversions between uno::Any, basesgfx classes
and awt:: incarnations). Directly handle uno::Any
and awt:: classes, changed stuff to make use of
this.
Change-Id: I083a323b9efee8ca4f3becb2966aac0a294b9a60
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151842
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Adapted handling of 'border' argument from our gradients
for oox export, so that it looks the same.
Also added quite some cases to peserve in-between
GradientStops for current UI implementations to be
able to edit the gradients as usual without losing
the in-between GradientStops.
While we will not be able to modify these, we are
at least able to modify all the other gradient
attributes, including start/endColor.
Done this for TransparencyGradients, too.
Also moved more stuff to the gradient tooling in
basegfx.
Change-Id: I6e94011bbf3715baa1401ab97e5b59811298342f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150577
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This is a 1st version and might need more fine-tuning,
so it is still 'hidden' behind the MCGR_TEST env var
being set (as the import is, too).
Still, when used, it can now import a MCGR with
transparence and export it again. I will now do extended
testing/experimenting, fine-tuning where needed and
prepare final change/drive forward.
The current state in master should not be changed as
long as the mentioned env var is not set, but this
will need to be checked, too, due to changes to the
export api in oox.
Corrected an error in GetAlphaFromTransparenceGradient
method(s), css::rendering::RGBColor is [0.0 .. 1.0]
Corercted an error in WriteSolidFill where transparence
gradient gets checked. This should really check if
TrGr is used, but only checks for 'empty/unused'
color instead (assuming COL_BLACK is 'unused').
All usages of GetAlphaFromTransparenceGradient should
be checked and adapted.
Change-Id: If59d7a06b9207e2efe9e71f3f8ddeca4476408f3
Change-Id: If97f8abdd0e1597aa1fd865b7e884e06a22b71f5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150391
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Moved the Gradient intensity handling to tooling since
it is also needed for TransparencyGradients. Added
missing use of GradientStepCount for transparency.
Change-Id: I63ae6683fa0131be7faadc8572e19f5c43bf27e3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149957
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
This change provides 1st changes to get Gradients with
muti color stops imported from MSO in the oox import
filter. It supports currently multiple ColorStops and
transparency. Also 'border'(s) should work, but
-remember- this is work in progress.
Since it is work in progress it is currently and
temporaily secured by ENV VAR "MCGR_TEST=0", so when
not using this the master version will not be touched
at all.
The number defines various ColorStop tests, 0 for none,
but some changes are active, e.g. MSO import. You may
try 1 or 16 to see all your Gradients hard replaced by
something using that feature.
I will take care fo cleaning this up again when the
feature progresses/gets complete.
Change-Id: I92e10d8cd5150733741a6def20a542abf97bd903
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149682
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
The biggest change here is to allow multiple ColorStops
with the same Offset. That allows to define gradients
with 'hard' color changes at any place using two
ColorStops with the same Offset and different Colors.
This required quite some adaptions, but works well.
Also removed in this context checking for all Colors
being the same to not mix up things. Also works well.
Also changed the need for having Start/EndColors AKA
ColorStops for 0.0 and 1.0 in place, instead 'imply'
the 1st ColorStop to also define the StartColor and
the last one the EndColor. This allows e.g. Gradient
definitions with two GradientStops at the same
Offset e.g. 0.5 with different colors to already
define a full Gradient.
Also added a tooling method to reverse ColorSteps,
which changes the order and mirrors the Offsets
(what even keeps an existing sort valid).
This is useful e.g. for GradientAxial which is the
only one where for decomposition the Gradient had
to be interpreted 'reverse' since it's defined
from center to edge, but for creating correct filled
polygons to represent this the inverse order had to
be used, creating polygons from edge to center.
This led to 'wild' code for this one of six cases
and prevented unifications with the other cases
(also made your brain flip).
Thus I adapted this now to use the reversed
ColorSteps consequently, and the same principle
loops than the other implementations to make things
easier for the future and to use common tooling.
Change-Id: If2943348d17d5b9cd165f4d78f22638a1dff5237
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149208
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Added tooling replaceStart/EndColor to allow simple
transition for code that does not immediately adapt
to multi color gradients. Also added
createColorStepsFromStartEndColor for the same
purpose.
Adapted XGradient to no longer have Start/EndColor
at all, but only use ColorSteps.
Adapted all usages of XGradient to no longer use
Get/Set/Start/EndColor, but access the ColorSteps
instead.
Replaced quite some XGradient constructors that
used XGradient() as Start/EndColor since this is
already the default.
Adapted ColorBlending to black AKA Start/EndIntens
in XGradient to work now on all ColorSteps in the
required linearly-scaled manner.
UNO API changes:
Added com::sun::star::awt::ColorStep as basic data
element that holds a pair of Offset and Color.
Added com::sun::star::awt::ColorStepSequence to
handle an array of sorted entries.
Added com::sun::star::awt::Gradient2 derived from
com::sun::star::awt::Gradient, extended by the
needed com::sun::star::awt::ColorStepSequence.
Added MID_GRADIENT_COLORSTEPSEQUENCE to UNO API
to provide access to ColorSteps directly.
Adapted XFillGradientItem::QueryValue/PutValue to
make use of new UNO API data structures. To do so,
added tooling methods for data transition:
- fillColorStepSequenceFromColorSteps
- fillGradient2FromXGradient
- fillColorStepsFromAny
- fillXGradientFromAny
and adapted
- case '0' (all data)
- MID_FILLGRADIENT
- MID_GRADIENT_COLORSTEPSEQUENCE
- MID_GRADIENT_START/ENDCOLOR
to make use of these.
Tested usage of these in the office.
Renamed from GradientStep to GradientStop after
discussions with members on the list to make this
closer related to other norms/definitions.
Also renamed classes and class members to better
reflect to GradientStop, so grepping/finding will
be easier (e.g. 'Color' just exists pretty often,
but 'StopColor' is more precise).
Changed the used UNO API class for reprsenting the
Color to better reflect to ranges [0.0 .. 1.0] and
usage of RGB.
Change-Id: I1eeb3e97e81d6785967615d1ff256551fc3b882d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148849
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Due to the fact that handling of a vector GradientSteps
will get used more often with ongoing changes I moved
some handling to tooling, see sortAndCorrectColorSteps.
That method sorts and corrects a vector of ColorSteps
so that only valid entreis remain in a sorted order,
for details please refer to the docu at function
definition. I took the occasion to rearrange that to
work on the single provided vector which is better for
speed & ressources.
Also changed the ColorStep constructor to not
automatically correct constructed entries: While that
is formally correct, it moves an invalid entry to 0.0
or 1.0, thus creating additional wrong Start/EndColor
entries. Those may then 'overlay' the correct entry
when corrections are applied to the vector of entries
which leads to getting the wanted Start/EndColor to be
factically deleted, what is an error.
Also rearranged FillGradientAttribute to now work
initially with ColorSteps, no longer requires the
Start/EndColor, also adapted all usages. This securely
allows start/end and in-between single-color sections
in gradients.
Also needed to re-formulate GradientRect &
GradientElliptical ::appendTransformationsAndColors
method for correct 2D mapping(s) - always incrementing
from the start to end conflicts with the adaption of
the start value for the inner loop mainly because
increment is at start of inner loop (pre-increment).
Corrected errors from clang plugin, but also some
wrong initialiations for basegfx::ColorSteps.
Change-Id: I292592ed9abcfa591f68a680479f4fcdda46cbeb
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148196
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Added to make GradientLinear work using the MCGR
as 1st of six types. Had to do quite some tickeling
to get it all work, but looks good.
Five more to go, already started to put some things
to tooling to make re-usable for the other types.
Besides adapting this the main change is that the
adaption of defined step-count (versus automatic)
has to be done in modifyBColor now instead of the
back-mapping methods (e.g. getLinearGradientAlpha).
It is still 100% backward-compatible, so as long
as there is no source using this it will stay
invisible - by purpose.
I started to do quite some tests (and fixes/
adaptions in consequence), see the static variable
nUseGradientSteps. If you want to play with this,
you might set it to '1' instead of '0' and use a
linear gradient on an object.
Change-Id: I9d61934defb0674456247f2879f0a89b6a5e50f7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147413
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Move GradientSteps data to GeoTexSvxGradient and adapt
interfaces. Also move tooling to more isolated place
in gradienttools in basegfx.
Keep everything still compatible, the work will be now
to adapt all six different derivations of
GeoTexSvxGradient to make use of the evtl. given
GradientSteps.
Change-Id: Iaa212763c603d46de0a94b1b203b979bb7ce359d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147050
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>