Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hi,

Here are some patches to improve SVG export filter.

0001: Make filter export Gradients and Hatches as SVG <pattern>s.
This tend not to change a visual look but improve semantic structure of a file.
# Actually,hatches go outside of a shape sometimes without this patch.

0003: Make filter export linear and axial gradients as SVG <linearGradient>s.
Use SVG's native gradient instead of polygon fallback.
With this patch, gradient steps of linear and axial gradient are ignored.
In other words, linear and axial gradients are always exported as
"smooth" gradients.
However, as far as I know, the manual steps function is for printing.
So I suppose ignoring gradient steps is safe.

To support native gradients, I need to calculate a bounding box of a gradient.
Currently it is done in OutputDevice::ImplDrawLinearGradient and
OutputDevice::ImplDrawComplexGradient.
So I moved that to Gradient class (0002 patch) to use it in filter code.


0004: Make filter export transparencies as SVG <mask>s.
SVG export filter supports only solid transparency of solid fill (i.e.
color) until now.
The patch extends support to support solid and gradient transparency
of all fill styles.
# Some SVG viewers including WebKit don't support <mask> yet :-(.


The patches are under the LGPLv3+ / MPL.

Cheers,
--
KUROSAWA Takeshi <taken.spc@gmail.com>
From 6254c025823c829e56fe6b5775c91c014eb2b87c Mon Sep 17 00:00:00 2001
From: Takeshi Kurosawa <taken.spc@gmail.com>
Date: Wed, 2 Feb 2011 14:31:59 +0900
Subject: [PATCH 1/3] Export hatches and gradients as SVG <pattern>s

This tend not to change a visual look, but improve semantic structure of a file.
---
 filter/source/svg/svgwriter.cxx |   85 +++++++++++++++++++++++++++------------
 filter/source/svg/svgwriter.hxx |    3 +
 2 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 7765ea5..1599cc6 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -39,6 +39,7 @@
 static const char      aXMLElemG[] = "g";
 static const char      aXMLElemDefs[] = "defs";
 static const char      aXMLElemClipPath[] = "clipPath";
+static const char      aXMLElemPattern[] = "pattern";
 static const char      aXMLElemLine[] = "line";
 static const char      aXMLElemRect[] = "rect";
 static const char      aXMLElemEllipse[] = "ellipse";
@@ -66,6 +67,7 @@ static const char     aXMLAttrRY[] = "ry";
 static const char      aXMLAttrWidth[] = "width";
 static const char      aXMLAttrHeight[] = "height";
 static const char      aXMLAttrPoints[] = "points";
+static const char      aXMLAttrPatternUnits[] = "patternUnits";
 static const char      aXMLAttrXLinkHRef[] = "xlink:href";
 
 static const sal_Unicode pBase64[] = 
@@ -483,7 +485,8 @@ SVGActionWriter::SVGActionWriter( SvXMLExport& rExport, SVGFontExport& rFontExpo
     mrFontExport( rFontExport ),
     mpContext( NULL ),
     mbClipAttrChanged( sal_False ),
-    mnCurClipId( 1 )
+    mnCurClipId( 1 ),
+    mnCurPatternId( 1 )
 {
     mpVDev = new VirtualDevice;
     mpVDev->EnableOutput( sal_False );
@@ -763,48 +766,81 @@ void SVGActionWriter::ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, 
sal_Bo
 
 // -----------------------------------------------------------------------------
 
-void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient,
-                                           const NMSP_RTL::OUString* pStyle, sal_uInt32 
nWriteFlags )
+void SVGActionWriter::ImplWritePattern( const PolyPolygon& rPolyPoly,
+                                        const Hatch* pHatch,
+                                        const Gradient* pGradient,
+                                        const NMSP_RTL::OUString* pStyle,
+                                        sal_uInt32 nWriteFlags )
 {
     if( rPolyPoly.Count() )
     {
-        SvXMLElementExport     aElemG( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
-        FastString                     aClipId;
-        FastString                     aClipStyle;
+        SvXMLElementExport aElemG( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
 
-        aClipId += B2UCONST( "clip" );
-        aClipId += NMSP_RTL::OUString::valueOf( ImplGetNextClipId() );
+        FastString aPatternId;
+        aPatternId += B2UCONST( "pattern" );
+        aPatternId += GetValueString( ImplGetNextPatternId() );
 
         {
             SvXMLElementExport aElemDefs( mrExport, XML_NAMESPACE_NONE, aXMLElemDefs, TRUE, TRUE );
 
-            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aClipId.GetString() );
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aPatternId.GetString() );
+
+            Rectangle aRect( ImplMap( rPolyPoly.GetBoundRect() ) );
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX, GetValueString( aRect.Left() ) );
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY, GetValueString( aRect.Top() ) );
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrWidth, GetValueString( 
aRect.GetWidth() ) );
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrHeight, GetValueString( 
aRect.GetHeight() ) );
+
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrPatternUnits, NMSP_RTL::OUString( 
RTL_CONSTASCII_USTRINGPARAM( "userSpaceOnUse") ) );
 
             {
-                SvXMLElementExport aElemClipPath( mrExport, XML_NAMESPACE_NONE, aXMLElemClipPath, 
TRUE, TRUE );
-                ImplWritePolyPolygon( rPolyPoly, sal_False );
+                SvXMLElementExport aElemPattern( mrExport, XML_NAMESPACE_NONE, aXMLElemPattern, 
TRUE, TRUE );
+
+                // The origion of a pattern is positioned at (aRect.Left(), aRect.Top())
+                // We need to translate a pattern to (aRect.Left(), aRect.Top())
+                FastString aTransform;
+                aTransform += B2UCONST( "translate" );
+                aTransform += B2UCONST( "(" );
+                aTransform += GetValueString( -aRect.Left() );
+                aTransform += B2UCONST( "," );
+                aTransform += GetValueString( -aRect.Top() );
+                aTransform += B2UCONST( ")" );
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrTransform, 
aTransform.GetString() );
+
+                {
+                    SvXMLElementExport aElemG2( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, 
TRUE );
+
+                    GDIMetaFile aTmpMtf;
+                    if( pHatch )
+                        mpVDev->AddHatchActions( rPolyPoly, *pHatch, aTmpMtf );
+                    else if ( pGradient )
+                        mpVDev->AddGradientActions( rPolyPoly.GetBoundRect(), *pGradient, aTmpMtf 
);
+                    ImplWriteActions( aTmpMtf, pStyle, nWriteFlags );
+                }
             }
         }
 
-        // create new context with clippath set
-        aClipStyle += B2UCONST( "clip-path:URL(#" );
-        aClipStyle += aClipId.GetString();
-        aClipStyle += B2UCONST( ")" );
-
-        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aClipStyle.GetString() );
+        FastString aPatternStyle;
+        aPatternStyle += B2UCONST( "fill:url(#" );
+        aPatternStyle += aPatternId.GetString();
+        aPatternStyle += B2UCONST( ")" );
 
         {
-            GDIMetaFile                        aTmpMtf;
-            SvXMLElementExport aElemG2( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
-
-            mpVDev->AddGradientActions( rPolyPoly.GetBoundRect(), rGradient, aTmpMtf );
-            ImplWriteActions( aTmpMtf, pStyle, nWriteFlags );
+            ImplWritePolyPolygon( rPolyPoly, sal_False, &aPatternStyle.GetString() );
         }
     }
 }
 
 // -----------------------------------------------------------------------------
 
+void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient,
+                                           const NMSP_RTL::OUString* pStyle, sal_uInt32 
nWriteFlags )
+{
+    ImplWritePattern( rPolyPoly, NULL, &rGradient, pStyle, nWriteFlags );
+}
+
+// -----------------------------------------------------------------------------
+
 void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, 
                                      const sal_Int32* pDXArray, long nWidth,
                                      const NMSP_RTL::OUString* pStyle )
@@ -1409,10 +1445,7 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 if( nWriteFlags & SVGWRITER_WRITE_FILL )
                 {
                     const MetaHatchAction*     pA = (const MetaHatchAction*) pAction;
-                    GDIMetaFile                                aTmpMtf;
-
-                    mpVDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
-                    ImplWriteActions( aTmpMtf, pStyle, nWriteFlags );
+                    ImplWritePattern( pA->GetPolyPolygon(), &pA->GetHatch(), NULL, pStyle, 
nWriteFlags );
                 }
             }
             break;
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index e1467c3..65bb067 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -165,6 +165,7 @@ private:
     SVGAttributeWriter*                mpContext;
     sal_Bool                           mbClipAttrChanged;
     sal_Int32                          mnCurClipId;
+    sal_Int32                          mnCurPatternId;
     Stack                                      maContextStack;
     VirtualDevice*                     mpVDev;
     MapMode                                    maTargetMapMode;
@@ -185,6 +186,7 @@ private:
     void                                       ImplWriteRect( const Rectangle& rRect, long nRadX = 
0, long nRadY = 0, const ::rtl::OUString* pStyle = NULL );
     void                                       ImplWriteEllipse( const Point& rCenter, long nRadX, 
long nRadY, const ::rtl::OUString* pStyle = NULL );
     void                                       ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, 
sal_Bool bLineOnly, const ::rtl::OUString* pStyle = NULL );
+    void                                       ImplWritePattern( const PolyPolygon& rPolyPoly, 
const Hatch* pHatch, const Gradient* pGradient, const ::rtl::OUString* pStyle, sal_uInt32 
nWriteFlags );
     void                                       ImplWriteGradientEx( const PolyPolygon& rPolyPoly, 
const Gradient& rGradient, const ::rtl::OUString* pStyle, sal_uInt32 nWriteFlags );
     void                                       ImplWriteText( const Point& rPos, const String& 
rText, const sal_Int32* pDXArray, long nWidth, const ::rtl::OUString* pStyle = NULL );
     void                ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* 
pDXArray, long nWidth, const ::rtl::OUString* pStyle, Color aTextColor );
@@ -195,6 +197,7 @@ private:
     
     void                                       ImplWriteActions( const GDIMetaFile& rMtf, const 
::rtl::OUString* pStyle, sal_uInt32 nWriteFlags );
     sal_Int32                          ImplGetNextClipId() { return mnCurClipId++; }
+    sal_Int32                          ImplGetNextPatternId() { return mnCurPatternId++; }
 
 public:
 
-- 
1.7.1

From b3ea2556903c07658e748d2bcb80cfd082b9ad7c Mon Sep 17 00:00:00 2001
From: Takeshi Kurosawa <taken.spc@gmail.com>
Date: Tue, 1 Feb 2011 14:40:58 +0900
Subject: [PATCH] Encapsulate calculation of gradient bounding box to Gradient::GetBoundRect

Export filters need to get gradient bounding box.
---
 vcl/inc/vcl/gradient.hxx    |    3 +
 vcl/source/gdi/gradient.cxx |   93 +++++++++++++++++++++++++++++++++++++++++++
 vcl/source/gdi/outdev4.cxx  |   91 +++++-------------------------------------
 3 files changed, 107 insertions(+), 80 deletions(-)

diff --git a/vcl/inc/vcl/gradient.hxx b/vcl/inc/vcl/gradient.hxx
index 46abd8d..f24ec95 100644
--- a/vcl/inc/vcl/gradient.hxx
+++ b/vcl/inc/vcl/gradient.hxx
@@ -31,6 +31,7 @@
 
 #include <vcl/dllapi.h>
 #include <tools/color.hxx>
+#include <tools/gen.hxx>
 
 #include <vcl/vclenum.hxx>
 
@@ -119,6 +120,8 @@ public:
     void            SetSteps( USHORT nSteps );
     USHORT          GetSteps() const { return mpImplGradient->mnStepCount; }
 
+    void            GetBoundRect( const Rectangle& rRect, Rectangle &rBoundRect, Point& rCenter ) 
const;
+
     Gradient&       operator=( const Gradient& rGradient );
     BOOL            operator==( const Gradient& rGradient ) const;
     BOOL            operator!=( const Gradient& rGradient ) const
diff --git a/vcl/source/gdi/gradient.cxx b/vcl/source/gdi/gradient.cxx
index d11d62e..297f30d 100644
--- a/vcl/source/gdi/gradient.cxx
+++ b/vcl/source/gdi/gradient.cxx
@@ -245,6 +245,99 @@ void Gradient::SetSteps( USHORT nSteps )
 
 // -----------------------------------------------------------------------
 
+void Gradient::GetBoundRect( const Rectangle& rRect, Rectangle& rBoundRect, Point& rCenter ) const
+{
+    Rectangle aRect( rRect );
+    USHORT nAngle = GetAngle() % 3600;
+
+    if( GetStyle() == GRADIENT_LINEAR || GetStyle() == GRADIENT_AXIAL )
+    {
+        aRect.Left()--;
+        aRect.Top()--;
+        aRect.Right()++;
+        aRect.Bottom()++;
+
+        const double    fAngle = nAngle * F_PI1800;
+        const double    fWidth = aRect.GetWidth();
+        const double    fHeight = aRect.GetHeight();
+        double          fDX = fWidth  * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) );
+        double          fDY = fHeight * fabs( cos( fAngle ) ) + fWidth  * fabs( sin( fAngle ) );
+
+        fDX = ( fDX - fWidth  ) * 0.5 + 0.5;
+        fDY = ( fDY - fHeight ) * 0.5 + 0.5;
+
+        aRect.Left()   -= (long) fDX;
+        aRect.Right()  += (long) fDX;
+        aRect.Top()    -= (long) fDY;
+        aRect.Bottom() += (long) fDY;
+
+        rBoundRect = aRect;
+        rCenter = rRect.Center();
+    }
+    else
+    {
+
+        if( GetStyle() == GRADIENT_SQUARE || GetStyle() == GRADIENT_RECT )
+        {
+            const double    fAngle = nAngle * F_PI1800;
+            const double    fWidth = aRect.GetWidth();
+            const double    fHeight = aRect.GetHeight();
+            double          fDX = fWidth  * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) 
);
+            double          fDY = fHeight * fabs( cos( fAngle ) ) + fWidth  * fabs( sin( fAngle ) 
);
+
+            fDX = ( fDX - fWidth  ) * 0.5 + 0.5;
+            fDY = ( fDY - fHeight ) * 0.5 + 0.5;
+
+            aRect.Left()   -= (long) fDX;
+            aRect.Right()  += (long) fDX;
+            aRect.Top()    -= (long) fDY;
+            aRect.Bottom() += (long) fDY;
+        }
+
+        Size aSize( aRect.GetSize() );
+
+        if( GetStyle() == GRADIENT_RADIAL )
+        {
+            // Radien-Berechnung fuer Kreis
+            aSize.Width() = (long)(0.5 + sqrt((double)aSize.Width()*(double)aSize.Width() + 
(double)aSize.Height()*(double)aSize.Height()));
+            aSize.Height() = aSize.Width();
+        }
+        else if( GetStyle() == GRADIENT_ELLIPTICAL )
+        {
+            // Radien-Berechnung fuer Ellipse
+            aSize.Width() = (long)( 0.5 + (double) aSize.Width()  * 1.4142 );
+            aSize.Height() = (long)( 0.5 + (double) aSize.Height() * 1.4142 );
+        }
+        else if( GetStyle() == GRADIENT_SQUARE )
+        {
+            if ( aSize.Width() > aSize.Height() )
+                aSize.Height() = aSize.Width();
+            else
+                aSize.Width() = aSize.Height();
+        }
+
+        // neue Mittelpunkte berechnen
+        long    nZWidth = aRect.GetWidth() * (long) GetOfsX() / 100;
+        long    nZHeight = aRect.GetHeight() * (long) GetOfsY() / 100;
+        long    nBorderX = (long) GetBorder() * aSize.Width()  / 100;
+        long    nBorderY = (long) GetBorder() * aSize.Height() / 100;
+        rCenter = Point( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
+
+        // Rand beruecksichtigen
+        aSize.Width() -= nBorderX;
+        aSize.Height() -= nBorderY;
+
+        // Ausgaberechteck neu setzen
+        aRect.Left() = rCenter.X() - ( aSize.Width() >> 1 );
+        aRect.Top() = rCenter.Y() - ( aSize.Height() >> 1 );
+
+        aRect.SetSize( aSize );
+        rBoundRect = rRect;
+    }
+}
+
+// -----------------------------------------------------------------------
+
 Gradient& Gradient::operator=( const Gradient& rGradient )
 {
     DBG_CHKTHIS( Gradient, NULL );
diff --git a/vcl/source/gdi/outdev4.cxx b/vcl/source/gdi/outdev4.cxx
index e550225..cc6facf 100644
--- a/vcl/source/gdi/outdev4.cxx
+++ b/vcl/source/gdi/outdev4.cxx
@@ -175,42 +175,25 @@ void OutputDevice::ImplDrawLinearGradient( const Rectangle& rRect,
                                            BOOL bMtf, const PolyPolygon* pClipPolyPoly )
 {
     // rotiertes BoundRect ausrechnen
-    Rectangle aRect = rRect;
-    aRect.Left()--;
-    aRect.Top()--;
-    aRect.Right()++;
-    aRect.Bottom()++;
-    USHORT     nAngle = rGradient.GetAngle() % 3600;
-    double     fAngle  = nAngle * F_PI1800;
-    double     fWidth  = aRect.GetWidth();
-    double     fHeight = aRect.GetHeight();
-    double     fDX     = fWidth  * fabs( cos( fAngle ) ) +
-                      fHeight * fabs( sin( fAngle ) );
-    double     fDY     = fHeight * fabs( cos( fAngle ) ) +
-                      fWidth  * fabs( sin( fAngle ) );
-            fDX        = (fDX - fWidth)  * 0.5 + 0.5;
-            fDY        = (fDY - fHeight) * 0.5 + 0.5;
-    aRect.Left()   -= (long)fDX;
-    aRect.Right()  += (long)fDX;
-    aRect.Top()    -= (long)fDY;
-    aRect.Bottom() += (long)fDY;
+    Rectangle aRect;
+    Point     aCenter;
+    USHORT    nAngle = rGradient.GetAngle() % 3600;
+
+    rGradient.GetBoundRect( rRect, aRect, aCenter );
 
     // Rand berechnen und Rechteck neu setzen
-    Point              aCenter = rRect.Center();
     Rectangle  aFullRect = aRect;
     long               nBorder = (long)rGradient.GetBorder() * aRect.GetHeight() / 100;
-    BOOL               bLinear;
 
     // Rand berechnen und Rechteck neu setzen fuer linearen Farbverlauf
-    if ( rGradient.GetStyle() == GRADIENT_LINEAR )
+    bool bLinear = (rGradient.GetStyle() == GRADIENT_LINEAR);
+    if ( bLinear )
     {
-        bLinear = TRUE;
         aRect.Top() += nBorder;
     }
     // Rand berechnen und Rechteck neu setzen fuer axiale Farbverlauf
     else
     {
-        bLinear = FALSE;
         nBorder >>= 1;
 
         aRect.Top()    += nBorder;
@@ -430,7 +413,8 @@ void OutputDevice::ImplDrawComplexGradient( const Rectangle& rRect,
     // Virtuelle Device werden auch ausgeklammert, da einige Treiber
     // ansonsten zu langsam sind
     PolyPolygon*    pPolyPoly;
-    Rectangle      aRect( rRect );
+    Rectangle       aRect;
+    Point           aCenter;
     Color                      aStartCol( rGradient.GetStartColor() );
     Color                      aEndCol( rGradient.GetEndColor() );
     long                       nStartRed = ( (long) aStartCol.GetRed() * 
rGradient.GetStartIntensity() ) / 100;
@@ -444,67 +428,14 @@ void OutputDevice::ImplDrawComplexGradient( const Rectangle& rRect,
     long                       nBlueSteps = nEndBlue   - nStartBlue;
     long            nStepCount = rGradient.GetSteps();
     USHORT             nAngle = rGradient.GetAngle() % 3600;
+
+    rGradient.GetBoundRect( rRect, aRect, aCenter );
     
     if( (meRasterOp != ROP_OVERPAINT) || (meOutDevType != OUTDEV_WINDOW) || bMtf )
         pPolyPoly = new PolyPolygon( 2 );
     else
         pPolyPoly = NULL;
 
-    if( rGradient.GetStyle() == GRADIENT_SQUARE || rGradient.GetStyle() == GRADIENT_RECT )
-    {
-        const double    fAngle = nAngle * F_PI1800;
-        const double    fWidth = aRect.GetWidth();
-        const double    fHeight = aRect.GetHeight();
-        double          fDX = fWidth  * fabs( cos( fAngle ) ) + fHeight * fabs( sin( fAngle ) ); 
-        double          fDY = fHeight * fabs( cos( fAngle ) ) + fWidth  * fabs( sin( fAngle ) ); 
-
-        fDX = ( fDX - fWidth ) * 0.5 + 0.5;
-        fDY = ( fDY - fHeight ) * 0.5 + 0.5;
-    
-        aRect.Left() -= (long) fDX;
-        aRect.Right() += (long) fDX;
-        aRect.Top() -= (long) fDY;
-        aRect.Bottom() += (long) fDY;
-    }
-    
-    Size aSize( aRect.GetSize() );
-    
-    if( rGradient.GetStyle() == GRADIENT_RADIAL )
-    {
-        // Radien-Berechnung fuer Kreis
-        aSize.Width() = (long)(0.5 + sqrt((double)aSize.Width()*(double)aSize.Width() + 
(double)aSize.Height()*(double)aSize.Height()));
-        aSize.Height() = aSize.Width();
-    }
-    else if( rGradient.GetStyle() == GRADIENT_ELLIPTICAL )
-    {
-        // Radien-Berechnung fuer Ellipse
-        aSize.Width() = (long)( 0.5 + (double) aSize.Width()  * 1.4142 );
-        aSize.Height() = (long)( 0.5 + (double) aSize.Height() * 1.4142 );
-    }
-    else if( rGradient.GetStyle() == GRADIENT_SQUARE )
-    {
-        if ( aSize.Width() > aSize.Height() )
-            aSize.Height() = aSize.Width();
-        else
-            aSize.Width() = aSize.Height();
-    }
-
-    // neue Mittelpunkte berechnen
-    long       nZWidth = aRect.GetWidth()      * (long) rGradient.GetOfsX() / 100;
-    long       nZHeight = aRect.GetHeight() * (long) rGradient.GetOfsY() / 100;
-    long       nBorderX = (long) rGradient.GetBorder() * aSize.Width()  / 100;
-    long       nBorderY = (long) rGradient.GetBorder() * aSize.Height() / 100;
-    Point      aCenter( aRect.Left() + nZWidth, aRect.Top() + nZHeight );
-
-    // Rand beruecksichtigen
-    aSize.Width() -= nBorderX;
-    aSize.Height() -= nBorderY;
-
-    // Ausgaberechteck neu setzen
-    aRect.Left() = aCenter.X() - ( aSize.Width() >> 1 );
-    aRect.Top() = aCenter.Y() - ( aSize.Height() >> 1 );
-    
-    aRect.SetSize( aSize );
     long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
 
     // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
-- 
1.7.1

From 9ef0b3c56099a6c58a1347574115d803c2071ee6 Mon Sep 17 00:00:00 2001
From: Takeshi Kurosawa <taken.spc@gmail.com>
Date: Wed, 2 Feb 2011 14:35:20 +0900
Subject: [PATCH 2/3] Export linear and axial gradient as SVG <linearGradient>

With this patch, gradient steps of linear and axial are ignored.
In other words, theose gradients are always exported as "smooth" gradients.
---
 filter/source/svg/svgwriter.cxx |  141 ++++++++++++++++++++++++++++++++++-----
 filter/source/svg/svgwriter.hxx |    5 ++
 2 files changed, 130 insertions(+), 16 deletions(-)

diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index 1599cc6..ab5bd3b 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -40,6 +40,8 @@ static const char     aXMLElemG[] = "g";
 static const char      aXMLElemDefs[] = "defs";
 static const char      aXMLElemClipPath[] = "clipPath";
 static const char      aXMLElemPattern[] = "pattern";
+static const char      aXMLElemLinearGradient[] = "linearGradient";
+static const char      aXMLElemStop[] = "stop";
 static const char      aXMLElemLine[] = "line";
 static const char      aXMLElemRect[] = "rect";
 static const char      aXMLElemEllipse[] = "ellipse";
@@ -68,6 +70,8 @@ static const char     aXMLAttrWidth[] = "width";
 static const char      aXMLAttrHeight[] = "height";
 static const char      aXMLAttrPoints[] = "points";
 static const char      aXMLAttrPatternUnits[] = "patternUnits";
+static const char      aXMLAttrGradientUnits[] = "gradientUnits";
+static const char      aXMLAttrOffset[] = "offset";
 static const char      aXMLAttrXLinkHRef[] = "xlink:href";
 
 static const sal_Unicode pBase64[] = 
@@ -331,6 +335,22 @@ NMSP_RTL::OUString SVGAttributeWriter::GetFontStyle( const Font& rFont )
 
 // -----------------------------------------------------------------------------
 
+NMSP_RTL::OUString SVGAttributeWriter::GetColorStyle( const Color& rColor,
+                                                      USHORT nIntensity )
+{
+    FastString aStyle;
+    aStyle += B2UCONST( "rgb(" );
+    aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rColor.GetRed() * nIntensity / 100L );
+    aStyle += B2UCONST( "," );
+    aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rColor.GetGreen() * nIntensity / 100L );
+    aStyle += B2UCONST( "," );
+    aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rColor.GetBlue()  * nIntensity / 100L );
+    aStyle += B2UCONST( ")" );
+    return aStyle.GetString();
+}
+
+// -----------------------------------------------------------------------------
+
 NMSP_RTL::OUString SVGAttributeWriter::GetPaintStyle( const Color& rLineColor, const Color& 
rFillColor, const LineInfo* pLineInfo )
 {
     FastString aStyle;
@@ -343,13 +363,7 @@ NMSP_RTL::OUString SVGAttributeWriter::GetPaintStyle( const Color& rLineColor, 
c
     else
     {
         // line color value in rgb
-        aStyle += B2UCONST( "rgb(" );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetRed() );
-        aStyle += B2UCONST( "," );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetGreen() );
-        aStyle += B2UCONST( "," );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rLineColor.GetBlue() );
-        aStyle += B2UCONST( ")" );
+        aStyle += GetColorStyle( rLineColor );
 
         // line color opacity in percent if neccessary
         if( rLineColor.GetTransparency() )
@@ -431,13 +445,7 @@ NMSP_RTL::OUString SVGAttributeWriter::GetPaintStyle( const Color& rLineColor, 
c
     else
     {
         // fill color value in rgb
-        aStyle += B2UCONST( "rgb(" );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetRed() );
-        aStyle += B2UCONST( "," );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetGreen() );
-        aStyle += B2UCONST( "," );
-        aStyle += NMSP_RTL::OUString::valueOf( (sal_Int32) rFillColor.GetBlue() );
-        aStyle += B2UCONST( ")" );
+        aStyle += GetColorStyle( rFillColor );
 
         // fill color opacity in percent if neccessary
         if( rFillColor.GetTransparency() )
@@ -486,7 +494,8 @@ SVGActionWriter::SVGActionWriter( SvXMLExport& rExport, SVGFontExport& rFontExpo
     mpContext( NULL ),
     mbClipAttrChanged( sal_False ),
     mnCurClipId( 1 ),
-    mnCurPatternId( 1 )
+    mnCurPatternId( 1 ),
+    mnCurGradientId( 1 )
 {
     mpVDev = new VirtualDevice;
     mpVDev->EnableOutput( sal_False );
@@ -836,7 +845,107 @@ void SVGActionWriter::ImplWritePattern( const PolyPolygon& rPolyPoly,
 void SVGActionWriter::ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient,
                                            const NMSP_RTL::OUString* pStyle, sal_uInt32 
nWriteFlags )
 {
-    ImplWritePattern( rPolyPoly, NULL, &rGradient, pStyle, nWriteFlags );
+    if ( rGradient.GetStyle() == GRADIENT_LINEAR ||
+         rGradient.GetStyle() == GRADIENT_AXIAL )
+    {
+        ImplWriteGradientLinear( rPolyPoly, rGradient );
+    }
+    else
+    {
+        ImplWritePattern( rPolyPoly, NULL, &rGradient, pStyle, nWriteFlags );
+    }
+}
+
+void SVGActionWriter::ImplWriteGradientLinear( const PolyPolygon& rPolyPoly,
+                                               const Gradient& rGradient )
+{
+    if( rPolyPoly.Count() )
+    {
+        SvXMLElementExport aElemG( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+
+        FastString aGradientId;
+        aGradientId += B2UCONST( "gradient" );
+        aGradientId += GetValueString( ImplGetNextGradientId() );
+
+        {
+            SvXMLElementExport aElemDefs( mrExport, XML_NAMESPACE_NONE, aXMLElemDefs, TRUE, TRUE );
+
+            mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aGradientId.GetString() );
+            {
+                Rectangle aTmpRect;
+                Point aTmpCenter;
+                rGradient.GetBoundRect( rPolyPoly.GetBoundRect(), aTmpRect, aTmpCenter );
+                const Rectangle aRect( ImplMap( aTmpRect) );
+                const Point aCenter( ImplMap( aTmpCenter) );
+                const USHORT nAngle = rGradient.GetAngle() % 3600;
+
+                Polygon aPoly( 2 );
+                aPoly[ 0 ].X() = aPoly[ 1 ].X() = aRect.Left();
+                aPoly[ 0 ].Y() = aRect.Top();
+                aPoly[ 1 ].Y() = aRect.Bottom();
+                aPoly.Rotate( aCenter, nAngle );
+
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX1, GetValueString( aPoly[ 0 
].X() ) );
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY1, GetValueString( aPoly[ 0 
].Y() ) );
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrX2, GetValueString( aPoly[ 1 
].X() ) );
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrY2, GetValueString( aPoly[ 1 
].Y() ) );
+
+                mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrGradientUnits, 
NMSP_RTL::OUString( RTL_CONSTASCII_USTRINGPARAM( "userSpaceOnUse" ) ) );
+            }
+
+            {
+                SvXMLElementExport aElemLinearGradient( mrExport, XML_NAMESPACE_NONE, 
aXMLElemLinearGradient, TRUE, TRUE );
+
+                if( rGradient.GetStyle() == GRADIENT_LINEAR )
+                {
+                    ImplWriteGradientStop( rGradient.GetStartColor(),
+                                           rGradient.GetStartIntensity(),
+                                           rGradient.GetBorder() / 100.0 );
+                    ImplWriteGradientStop( rGradient.GetEndColor(),
+                                           rGradient.GetEndIntensity(),
+                                           1.0 );
+                }
+                else
+                {
+                    ImplWriteGradientStop( rGradient.GetEndColor(),
+                                           rGradient.GetEndIntensity(),
+                                           rGradient.GetBorder() / 200.0 );
+                    ImplWriteGradientStop( rGradient.GetStartColor(),
+                                           rGradient.GetStartIntensity(),
+                                           0.5 );
+                    ImplWriteGradientStop( rGradient.GetEndColor(),
+                                           rGradient.GetEndIntensity(),
+                                           1.0 - rGradient.GetBorder() / 200.0 );
+                }
+            }
+        }
+
+        FastString aGradientStyle;
+        aGradientStyle += B2UCONST( "fill:" );
+        aGradientStyle += B2UCONST( "url(#" );
+        aGradientStyle += aGradientId.GetString();
+        aGradientStyle += B2UCONST( ")" );
+
+        {
+            ImplWritePolyPolygon( rPolyPoly, sal_False, &aGradientStyle.GetString() );
+        }
+    }
+}
+
+void SVGActionWriter::ImplWriteGradientStop( const Color& rColor,
+                                             USHORT nIntensity,
+                                             double fOffset )
+{
+    mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrOffset, NMSP_RTL::OUString::valueOf( 
fOffset ) );
+
+    FastString aStyle;
+    aStyle += B2UCONST( "stop-color:" );
+    aStyle += mpContext->GetColorStyle ( rColor, nIntensity );
+
+    mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aStyle.GetString() );
+    {
+        SvXMLElementExport aElemStartStop( mrExport, XML_NAMESPACE_NONE, aXMLElemStop, TRUE, TRUE 
);
+    }
 }
 
 // -----------------------------------------------------------------------------
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index 65bb067..103bdee 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -142,6 +142,7 @@ public:
     virtual                                    ~SVGAttributeWriter();
 
     ::rtl::OUString                    GetFontStyle( const Font& rFont );
+    ::rtl::OUString                    GetColorStyle( const Color& rColor, USHORT nItensity = 100 
);
     ::rtl::OUString                    GetPaintStyle( const Color& rLineColor, const Color& 
rFillColor, const LineInfo* pLineInfo );
 
     void                                       SetFontAttr( const Font& rFont );
@@ -166,6 +167,7 @@ private:
     sal_Bool                           mbClipAttrChanged;
     sal_Int32                          mnCurClipId;
     sal_Int32                          mnCurPatternId;
+    sal_Int32                          mnCurGradientId;
     Stack                                      maContextStack;
     VirtualDevice*                     mpVDev;
     MapMode                                    maTargetMapMode;
@@ -188,6 +190,8 @@ private:
     void                                       ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, 
sal_Bool bLineOnly, const ::rtl::OUString* pStyle = NULL );
     void                                       ImplWritePattern( const PolyPolygon& rPolyPoly, 
const Hatch* pHatch, const Gradient* pGradient, const ::rtl::OUString* pStyle, sal_uInt32 
nWriteFlags );
     void                                       ImplWriteGradientEx( const PolyPolygon& rPolyPoly, 
const Gradient& rGradient, const ::rtl::OUString* pStyle, sal_uInt32 nWriteFlags );
+    void                                       ImplWriteGradientLinear( const PolyPolygon& 
rPolyPoly, const Gradient& rGradient );
+    void                                       ImplWriteGradientStop( const Color& rColor, USHORT 
nIntensity, double fOffset );
     void                                       ImplWriteText( const Point& rPos, const String& 
rText, const sal_Int32* pDXArray, long nWidth, const ::rtl::OUString* pStyle = NULL );
     void                ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* 
pDXArray, long nWidth, const ::rtl::OUString* pStyle, Color aTextColor );
     void                                       ImplWriteBmp( const BitmapEx& rBmpEx, const Point& 
rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const ::rtl::OUString* pStyle = NULL 
);
@@ -198,6 +202,7 @@ private:
     void                                       ImplWriteActions( const GDIMetaFile& rMtf, const 
::rtl::OUString* pStyle, sal_uInt32 nWriteFlags );
     sal_Int32                          ImplGetNextClipId() { return mnCurClipId++; }
     sal_Int32                          ImplGetNextPatternId() { return mnCurPatternId++; }
+    sal_Int32                          ImplGetNextGradientId() { return mnCurGradientId++; }
 
 public:
 
-- 
1.7.1

From 84ae44fd034700fb9c55000bf85ca893c06edd67 Mon Sep 17 00:00:00 2001
From: Takeshi Kurosawa <taken.spc@gmail.com>
Date: Wed, 2 Feb 2011 14:38:31 +0900
Subject: [PATCH 3/3] Export transparencies as SVg <mask>s

SVG export filter supports only solid transparency of solid fill (i.e. color) until now.
This patch extends support to solid and gradient transparency of all fill styles.
---
 filter/source/svg/svgwriter.cxx |   94 +++++++++++++++++++++++++++++---------
 filter/source/svg/svgwriter.hxx |    3 +
 2 files changed, 74 insertions(+), 23 deletions(-)

diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx
index ab5bd3b..f88c36c 100644
--- a/filter/source/svg/svgwriter.cxx
+++ b/filter/source/svg/svgwriter.cxx
@@ -39,6 +39,7 @@
 static const char      aXMLElemG[] = "g";
 static const char      aXMLElemDefs[] = "defs";
 static const char      aXMLElemClipPath[] = "clipPath";
+static const char      aXMLElemMask[] = "mask";
 static const char      aXMLElemPattern[] = "pattern";
 static const char      aXMLElemLinearGradient[] = "linearGradient";
 static const char      aXMLElemStop[] = "stop";
@@ -495,7 +496,8 @@ SVGActionWriter::SVGActionWriter( SvXMLExport& rExport, SVGFontExport& rFontExpo
     mbClipAttrChanged( sal_False ),
     mnCurClipId( 1 ),
     mnCurPatternId( 1 ),
-    mnCurGradientId( 1 )
+    mnCurGradientId( 1 ),
+    mnCurMaskId( 1 )
 {
     mpVDev = new VirtualDevice;
     mpVDev->EnableOutput( sal_False );
@@ -949,6 +951,72 @@ void SVGActionWriter::ImplWriteGradientStop( const Color& rColor,
 }
 
 // -----------------------------------------------------------------------------
+void SVGActionWriter::ImplWriteMask( GDIMetaFile& rMtf,
+                                     const Point& rDestPt,
+                                     const Size& rDestSize,
+                                     const Gradient& rGradient,
+                                     const NMSP_RTL::OUString* pStyle,
+                                     sal_uInt32 nWriteFlags )
+{
+    Point          aSrcPt( rMtf.GetPrefMapMode().GetOrigin() );
+    const Size     aSrcSize( rMtf.GetPrefSize() );
+    const double   fScaleX = aSrcSize.Width() ? (double) rDestSize.Width() / aSrcSize.Width() : 
1.0;
+    const double   fScaleY = aSrcSize.Height() ? (double) rDestSize.Height() / aSrcSize.Height() : 
1.0;
+    long           nMoveX, nMoveY;
+
+    if( fScaleX != 1.0 || fScaleY != 1.0 )
+    {
+        rMtf.Scale( fScaleX, fScaleY );
+        aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+    }
+
+    nMoveX = rDestPt.X() - aSrcPt.X(), nMoveY = rDestPt.Y() - aSrcPt.Y();
+
+    if( nMoveX || nMoveY )
+        rMtf.Move( nMoveX, nMoveY );
+
+    FastString aMaskId;
+    aMaskId += B2UCONST( "mask" );
+    aMaskId += GetValueString( ImplGetNextMaskId() );
+
+    {
+        SvXMLElementExport aElemDefs( mrExport, XML_NAMESPACE_NONE, aXMLElemDefs, TRUE, TRUE );
+
+        mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrId, aMaskId.GetString() );
+        {
+            SvXMLElementExport aElemMask( mrExport, XML_NAMESPACE_NONE, aXMLElemMask, TRUE, TRUE );
+
+            PolyPolygon aPolyPolygon( PolyPolygon( Rectangle( rDestPt, rDestSize ) ) );
+            Gradient aGradient( rGradient );
+
+            // swap gradient stops to adopt SVG mask
+            Color tmpColor( aGradient.GetStartColor() );
+            USHORT tmpIntensity( aGradient.GetStartIntensity() );
+            aGradient.SetStartColor( aGradient.GetEndColor() );
+            aGradient.SetStartIntensity( aGradient.GetEndIntensity()) ;
+            aGradient.SetEndColor( tmpColor );
+            aGradient.SetEndIntensity( tmpIntensity );
+
+            ImplWriteGradientEx( aPolyPolygon, aGradient, pStyle, nWriteFlags );
+        }
+    }
+
+    FastString aMaskStyle;
+    aMaskStyle += B2UCONST( "mask:url(#" );
+    aMaskStyle += aMaskId.GetString();
+    aMaskStyle += B2UCONST( ")" );
+    mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrStyle, aMaskStyle.GetString() );
+
+    {
+        SvXMLElementExport aElemG( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE );
+
+        mpVDev->Push();
+        ImplWriteActions( rMtf, pStyle, nWriteFlags );
+        mpVDev->Pop();
+    }
+}
+
+// -----------------------------------------------------------------------------
 
 void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, 
                                      const sal_Int32* pDXArray, long nWidth,
@@ -1588,28 +1656,8 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf,
                 {
                     const MetaFloatTransparentAction*  pA = (const MetaFloatTransparentAction*) 
pAction;
                     GDIMetaFile                                                        aTmpMtf( 
pA->GetGDIMetaFile() );
-                    Point                                                              aSrcPt( 
aTmpMtf.GetPrefMapMode().GetOrigin() );
-                    const Size                                                 aSrcSize( 
aTmpMtf.GetPrefSize() );
-                    const Point                                                        aDestPt( 
pA->GetPoint() );
-                    const Size                                                 aDestSize( 
pA->GetSize() );
-                    const double                                               fScaleX = 
aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
-                    const double                                               fScaleY = 
aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
-                    long                                                               nMoveX, 
nMoveY;
-
-                    if( fScaleX != 1.0 || fScaleY != 1.0 )
-                    {
-                        aTmpMtf.Scale( fScaleX, fScaleY );
-                        aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( 
aSrcPt.Y() * fScaleY );
-                    }
-
-                    nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
-
-                    if( nMoveX || nMoveY )
-                        aTmpMtf.Move( nMoveX, nMoveY );
-
-                    mpVDev->Push();
-                    ImplWriteActions( aTmpMtf, pStyle, nWriteFlags );
-                    mpVDev->Pop();
+                    ImplWriteMask( aTmpMtf, pA->GetPoint(), pA->GetSize(),
+                                   pA->GetGradient(), pStyle, nWriteFlags  );
                 }
             }
             break;
diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx
index 103bdee..90fae3d 100644
--- a/filter/source/svg/svgwriter.hxx
+++ b/filter/source/svg/svgwriter.hxx
@@ -168,6 +168,7 @@ private:
     sal_Int32                          mnCurClipId;
     sal_Int32                          mnCurPatternId;
     sal_Int32                          mnCurGradientId;
+    sal_Int32                          mnCurMaskId;
     Stack                                      maContextStack;
     VirtualDevice*                     mpVDev;
     MapMode                                    maTargetMapMode;
@@ -192,6 +193,7 @@ private:
     void                                       ImplWriteGradientEx( const PolyPolygon& rPolyPoly, 
const Gradient& rGradient, const ::rtl::OUString* pStyle, sal_uInt32 nWriteFlags );
     void                                       ImplWriteGradientLinear( const PolyPolygon& 
rPolyPoly, const Gradient& rGradient );
     void                                       ImplWriteGradientStop( const Color& rColor, USHORT 
nIntensity, double fOffset );
+    void                                       ImplWriteMask( GDIMetaFile& rMtf, const Point& 
rDestPt, const Size& rDestSize, const Gradient& rGradient, const ::rtl::OUString* pStyle, 
sal_uInt32 nWriteFlags );
     void                                       ImplWriteText( const Point& rPos, const String& 
rText, const sal_Int32* pDXArray, long nWidth, const ::rtl::OUString* pStyle = NULL );
     void                ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* 
pDXArray, long nWidth, const ::rtl::OUString* pStyle, Color aTextColor );
     void                                       ImplWriteBmp( const BitmapEx& rBmpEx, const Point& 
rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const ::rtl::OUString* pStyle = NULL 
);
@@ -203,6 +205,7 @@ private:
     sal_Int32                          ImplGetNextClipId() { return mnCurClipId++; }
     sal_Int32                          ImplGetNextPatternId() { return mnCurPatternId++; }
     sal_Int32                          ImplGetNextGradientId() { return mnCurGradientId++; }
+    sal_Int32                          ImplGetNextMaskId() { return mnCurMaskId++; }
 
 public:
 
-- 
1.7.1


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.