Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
8454c5ef
Kaydet (Commit)
8454c5ef
authored
Eki 15, 2009
tarafından
thb
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
#i105939# Adds special box clipping support to basegfx
üst
44dfc8de
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
2379 additions
and
562 deletions
+2379
-562
b2dpolygon.hxx
basegfx/inc/basegfx/polygon/b2dpolygon.hxx
+8
-2
b2dpolypolygon.hxx
basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
+6
-0
b2dpolyrange.hxx
basegfx/inc/basegfx/range/b2dpolyrange.hxx
+64
-42
b2drangeclipper.hxx
basegfx/inc/basegfx/range/b2drangeclipper.hxx
+53
-0
mkpolygons.pl
basegfx/qa/mkpolygons.pl
+344
-0
b2dpolygon.cxx
basegfx/source/polygon/b2dpolygon.cxx
+73
-25
b2dpolypolygon.cxx
basegfx/source/polygon/b2dpolypolygon.cxx
+40
-0
b2dmultirange.cxx
basegfx/source/range/b2dmultirange.cxx
+0
-282
b2dpolyrange.cxx
basegfx/source/range/b2dpolyrange.cxx
+371
-0
b2drangeclipper.cxx
basegfx/source/range/b2drangeclipper.cxx
+950
-0
makefile.mk
basegfx/source/range/makefile.mk
+2
-1
basegfx2d.cxx
basegfx/test/basegfx2d.cxx
+38
-210
boxclipper.cxx
basegfx/test/boxclipper.cxx
+426
-0
makefile.mk
basegfx/test/makefile.mk
+4
-0
No files found.
basegfx/inc/basegfx/polygon/b2dpolygon.hxx
Dosyayı görüntüle @
8454c5ef
...
@@ -83,7 +83,7 @@ namespace basegfx
...
@@ -83,7 +83,7 @@ namespace basegfx
sal_uInt32
count
()
const
;
sal_uInt32
count
()
const
;
/// Coordinate interface
/// Coordinate interface
basegfx
::
B2DPoint
getB2DPoint
(
sal_uInt32
nIndex
)
const
;
const
basegfx
::
B2DPoint
&
getB2DPoint
(
sal_uInt32
nIndex
)
const
;
void
setB2DPoint
(
sal_uInt32
nIndex
,
const
basegfx
::
B2DPoint
&
rValue
);
void
setB2DPoint
(
sal_uInt32
nIndex
,
const
basegfx
::
B2DPoint
&
rValue
);
/// Coordinate insert/append
/// Coordinate insert/append
...
@@ -201,7 +201,7 @@ namespace basegfx
...
@@ -201,7 +201,7 @@ namespace basegfx
@return
@return
The outer range of the bezier curve/polygon
The outer range of the bezier curve/polygon
*/
*/
B2DRange
getB2DRange
()
const
;
const
B2DRange
&
getB2DRange
()
const
;
/** insert other 2D polygons
/** insert other 2D polygons
...
@@ -261,6 +261,12 @@ namespace basegfx
...
@@ -261,6 +261,12 @@ namespace basegfx
/// apply transformation given in matrix form
/// apply transformation given in matrix form
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
);
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
);
// point iterators
const
B2DPoint
*
begin
()
const
;
const
B2DPoint
*
end
()
const
;
B2DPoint
*
begin
();
B2DPoint
*
end
();
};
};
}
// end of namespace basegfx
}
// end of namespace basegfx
...
...
basegfx/inc/basegfx/polygon/b2dpolypolygon.hxx
Dosyayı görüntüle @
8454c5ef
...
@@ -128,6 +128,12 @@ namespace basegfx
...
@@ -128,6 +128,12 @@ namespace basegfx
// apply transformation given in matrix form to the polygon
// apply transformation given in matrix form to the polygon
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
);
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
);
// polygon iterators
const
B2DPolygon
*
begin
()
const
;
const
B2DPolygon
*
end
()
const
;
B2DPolygon
*
begin
();
B2DPolygon
*
end
();
};
};
}
// end of namespace basegfx
}
// end of namespace basegfx
...
...
basegfx/inc/basegfx/range/b2d
multi
range.hxx
→
basegfx/inc/basegfx/range/b2d
poly
range.hxx
Dosyayı görüntüle @
8454c5ef
...
@@ -28,19 +28,19 @@
...
@@ -28,19 +28,19 @@
*
*
************************************************************************/
************************************************************************/
#ifndef _BGFX_RANGE_B2D
MULTI
RANGE_HXX
#ifndef _BGFX_RANGE_B2D
POLY
RANGE_HXX
#define _BGFX_RANGE_B2D
MULTI
RANGE_HXX
#define _BGFX_RANGE_B2D
POLY
RANGE_HXX
#include <o3tl/cow_wrapper.hxx>
#include <o3tl/cow_wrapper.hxx>
#include <
memory
>
#include <
boost/tuple/tuple.hpp
>
#include <basegfx/vector/b2enums.hxx>
namespace
basegfx
namespace
basegfx
{
{
class
B2DTuple
;
class
B2DTuple
;
class
B2DRange
;
class
B2DRange
;
class
B2DPolyPolygon
;
class
B2DPolyPolygon
;
class
ImplB2D
Multi
Range
;
class
ImplB2D
Poly
Range
;
/** Multiple ranges in one object.
/** Multiple ranges in one object.
...
@@ -51,67 +51,89 @@ namespace basegfx
...
@@ -51,67 +51,89 @@ namespace basegfx
rectangular objects. Add each modified object to a
rectangular objects. Add each modified object to a
B2DMultiRange, then test each viewable object against
B2DMultiRange, then test each viewable object against
intersection with the multi range.
intersection with the multi range.
Similar in spirit to the poly-polygon vs. polygon relationship.
Note that comparable to polygons, a poly-range can also
contain 'holes' - this is encoded via polygon orientation at
the poly-polygon, and via explicit flags for the poly-range.
*/
*/
class
B2D
Multi
Range
class
B2D
Poly
Range
{
{
public
:
public
:
B2DMultiRange
();
typedef
boost
::
tuple
<
B2DRange
,
B2VectorOrientation
>
ElementType
;
~
B2DMultiRange
();
B2DPolyRange
();
~
B2DPolyRange
();
/** Create a multi range with exactly one containing range
/** Create a multi range with exactly one containing range
*/
*/
explicit
B2DMultiRange
(
const
B2DRange
&
rRange
);
explicit
B2DPolyRange
(
const
ElementType
&
rElement
);
B2DPolyRange
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
);
B2DPolyRange
(
const
B2DPolyRange
&
);
B2DPolyRange
&
operator
=
(
const
B2DPolyRange
&
);
B2DMultiRange
(
const
B2DMultiRange
&
);
/// unshare this poly-range with all internally shared instances
B2DMultiRange
&
operator
=
(
const
B2DMultiRange
&
);
void
makeUnique
(
);
/** Check whether range is empty.
bool
operator
==
(
const
B2DPolyRange
&
)
const
;
bool
operator
!=
(
const
B2DPolyRange
&
)
const
;
@return true, if this object either contains no ranges at
/// Number of included ranges
all, or all contained ranges are empty.
sal_uInt32
count
()
const
;
*/
bool
isEmpty
()
const
;
/** Reset to empty.
ElementType
getElement
(
sal_uInt32
nIndex
)
const
;
void
setElement
(
sal_uInt32
nIndex
,
const
ElementType
&
rElement
);
void
setElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
);
After this call, the object will not contain any ranges,
// insert/append a single range
and isEmpty() will return true.
void
insertElement
(
sal_uInt32
nIndex
,
const
ElementType
&
rElement
,
sal_uInt32
nCount
=
1
);
*/
void
insertElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
=
1
);
void
reset
();
void
appendElement
(
const
ElementType
&
rElement
,
sal_uInt32
nCount
=
1
);
void
appendElement
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
=
1
);
// insert/append multiple ranges
void
insertPolyRange
(
sal_uInt32
nIndex
,
const
B2DPolyRange
&
);
void
appendPolyRange
(
const
B2DPolyRange
&
);
void
remove
(
sal_uInt32
nIndex
,
sal_uInt32
nCount
=
1
);
void
clear
();
// flip range orientations - converts holes to solids, and vice versa
void
flip
();
/** Get overall range
@return
The union range of all contained ranges
*/
B2DRange
getBounds
()
const
;
/** Test whether given tuple is inside one or more of the
/** Test whether given tuple is inside one or more of the
included ranges.
included ranges. Does *not* use overall range, but checks
individually.
*/
*/
bool
isInside
(
const
B2DTuple
&
rTuple
)
const
;
bool
isInside
(
const
B2DTuple
&
rTuple
)
const
;
/** Test whether given range is inside one or more of the
/** Test whether given range is inside one or more of the
included ranges.
included ranges. Does *not* use overall range, but checks
individually.
*/
*/
bool
isInside
(
const
B2DRange
&
rRange
)
const
;
bool
isInside
(
const
B2DRange
&
rRange
)
const
;
/** Test whether given range overlaps one or more of the
/** Test whether given range overlaps one or more of the
included ranges.
included ranges. Does *not* use overall range, but checks
*/
individually.
bool
overlaps
(
const
B2DRange
&
rRange
)
const
;
/** Add given range to the number of contained ranges.
*/
void
addRange
(
const
B2DRange
&
rRange
);
/** Get overall bound rect for all included ranges.
*/
*/
B2DRange
getBounds
()
const
;
bool
overlaps
(
const
B2DRange
&
rRange
)
const
;
/** Request poly-polygon representing the added ranges.
This method creates a poly-polygon, consisting exactly out
/** Request a poly-polygon with solved cross-overs
of the contained ranges.
*/
*/
B2DPolyPolygon
getPolyPolygon
()
const
;
B2DPolyPolygon
solveCrossovers
()
const
;
private
:
private
:
o3tl
::
cow_wrapper
<
ImplB2D
Multi
Range
>
mpImpl
;
o3tl
::
cow_wrapper
<
ImplB2D
Poly
Range
>
mpImpl
;
};
};
}
}
#endif
/* _BGFX_RANGE_B2D
MULTI
RANGE_HXX */
#endif
/* _BGFX_RANGE_B2D
POLY
RANGE_HXX */
basegfx/inc/basegfx/range/b2drangeclipper.hxx
0 → 100644
Dosyayı görüntüle @
8454c5ef
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.hxx,v $
* $Revision: 1.6 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
#ifndef _BGFX_RANGE_B2DRANGECLIPPER_HXX
#define _BGFX_RANGE_B2DRANGECLIPPER_HXX
#include <basegfx/range/b2dpolyrange.hxx>
#include <vector>
namespace
basegfx
{
namespace
tools
{
/** Extract poly-polygon w/o self-intersections from poly-range
Similar to the solveCrossovers(const B2DPolyPolygon&)
method, this one calculates a self-intersection-free
poly-polygon with the same topology, and encoding
inside/outsidedness via polygon orientation and layering.
*/
B2DPolyPolygon
solveCrossovers
(
const
std
::
vector
<
B2DRange
>&
rRanges
,
const
std
::
vector
<
B2VectorOrientation
>&
rOrientations
);
}
}
#endif
/* _BGFX_RANGE_B2DRANGECLIPPER_HXX */
basegfx/qa/mkpolygons.pl
0 → 100644
Dosyayı görüntüle @
8454c5ef
:
eval
'exec perl -wS $0 ${1+"$@"}'
if
0
;
#
# 2009 Copyright Novell, Inc. & Sun Microsystems, Inc.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
use
IO::
File
;
use
Cwd
;
use
File::
Spec
;
use
File::Spec::
Functions
;
use
File::
Temp
;
use
File::
Path
;
$TempDir
=
""
;
# all the XML package generation is a blatant rip from AF's
# write-calc-doc.pl
###############################################################################
# Open a file with the given name.
# First it is checked if the temporary directory, in which all files for
# the document are gathered, is already present and create it if it is not.
# Then create the path to the file inside the temporary directory.
# Finally open the file and return a file handle to it.
#
sub
open_file
{
my
$filename
=
pop
@_
;
# Create base directory of temporary directory tree if not alreay
# present.
if
(
$TempDir
eq
""
)
{
$TempDir
=
File::Temp::
tempdir
(
CLEANUP
=>
1
);
}
# Create the path to the file.
my
$fullname
=
File::
Spec
->
catfile
(
$TempDir
,
$filename
);
my
(
$volume
,
$directories
,
$file
)
=
File::
Spec
->
splitpath
(
$fullname
);
mkpath
(
File::
Spec
->
catpath
(
$volume
,
$directories
,
""
));
# Open the file and return a file handle to it.
return
new
IO::
File
(
$fullname
,
"w"
);
}
###############################################################################
# Zip the files in the directory tree into the given file.
#
sub
zip_dirtree
{
my
$filename
=
pop
@_
;
my
$cwd
=
getcwd
;
my
$zip_name
=
$filename
;
# We are about to change the directory.
# Therefore create an absolute pathname for the zip archive.
# First transfer the drive from $cwd to $zip_name. This is a
# workaround for a bug in file_name_is_absolute which thinks
# the the path \bla is an absolute path under DOS.
my
(
$volume
,
$directories
,
$file
)
=
File::
Spec
->
splitpath
(
$zip_name
);
my
(
$volume_cwd
,
$directories_cwd
,
$file_cwd
)
=
File::
Spec
->
splitpath
(
$cwd
);
$volume
=
$volume_cwd
if
(
$volume
eq
""
);
$zip_name
=
File::
Spec
->
catpath
(
$volume
,
$directories
,
$file
);
# Add the current working directory to a relative path.
if
(
!
file_name_is_absolute
(
$zip_name
))
{
$zip_name
=
File::
Spec
->
catfile
(
$cwd
,
$zip_name
);
# Try everything to clean up the name.
$zip_name
=
File::
Spec
->
rel2abs
(
$filename
);
$zip_name
=
File::
Spec
->
canonpath
(
$zip_name
);
# Remove .. directories from the middle of the path.
while
(
$zip_name
=~
/\/[^\/][^\.\/][^\/]*\/\.\.\//
)
{
$zip_name
=
$`
.
"/"
.
$'
;
}
}
# Just in case the zip program gets confused by an existing file with the
# same name as the one to be written that file is removed first.
if
(
-
e
$filename
)
{
if
(
unlink
(
$filename
)
==
0
)
{
print
"Existing file $filename could not be deleted.\n"
;
print
"Please close the application that uses it, then try again.\n"
;
return
;
}
}
# Finally create the zip file. First change into the temporary directory
# so that the resulting zip file contains only paths relative to it.
print
"zipping [$ZipCmd $ZipFlags $zip_name *]\n"
;
chdir
(
$TempDir
);
system
(
"$ZipCmd $ZipFlags $zip_name *"
);
chdir
(
$cwd
);
}
sub
writeHeader
{
print
$OUT
qq~<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:smil="urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" xmlns:anim="urn:oasis:names:tc:opendocument:xmlns:animation:1.0" office:version="1.0">
<office:scripts/>
<office:automatic-styles>
<style:style style:name="dp1" style:family="drawing-page">
<style:drawing-page-properties presentation:background-visible="true" presentation:background-objects-visible="true" presentation:display-footer="true" presentation:display-page-number="false" presentation:display-date-time="true"/>
</style:style>
<style:style style:name="gr1" style:family="graphic" style:parent-style-name="standard">
<style:graphic-properties draw:textarea-horizontal-align="center" draw:fill="none" draw:stroke="none" draw:textarea-vertical-align="middle"/>
</style:style>
<style:style style:name="gr2" style:family="graphic" style:parent-style-name="standard">
<style:graphic-properties draw:textarea-horizontal-align="center" draw:textarea-vertical-align="middle"/>
</style:style>
<style:style style:name="pr1" style:family="presentation" style:parent-style-name="Default-title">
<style:graphic-properties draw:fill-color="#ffffff" draw:auto-grow-height="true" fo:min-height="3.508cm"/>
</style:style>
<style:style style:name="pr2" style:family="presentation" style:parent-style-name="Default-notes">
<style:graphic-properties draw:fill-color="#ffffff" draw:auto-grow-height="true" fo:min-height="13.367cm"/>
</style:style>
<style:style style:name="P1" style:family="paragraph">
<style:paragraph-properties fo:margin-left="0cm" fo:margin-right="0cm" fo:text-indent="0cm"/>
</style:style>
<style:style style:name="P2" style:family="paragraph">
<style:paragraph-properties fo:margin-left="0.6cm" fo:margin-right="0cm" fo:text-indent="-0.6cm"/>
</style:style>
<text:list-style style:name="L1">
<text:list-level-style-bullet text:level="1" text:bullet-char="●">
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="2" text:bullet-char="●">
<style:list-level-properties text:space-before="0.6cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="3" text:bullet-char="●">
<style:list-level-properties text:space-before="1.2cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="4" text:bullet-char="●">
<style:list-level-properties text:space-before="1.8cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="5" text:bullet-char="●">
<style:list-level-properties text:space-before="2.4cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="6" text:bullet-char="●">
<style:list-level-properties text:space-before="3cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="7" text:bullet-char="●">
<style:list-level-properties text:space-before="3.6cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="8" text:bullet-char="●">
<style:list-level-properties text:space-before="4.2cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
<text:list-level-style-bullet text:level="9" text:bullet-char="●">
<style:list-level-properties text:space-before="4.8cm" text:min-label-width="0.6cm"/>
<style:text-properties fo:font-family="StarSymbol" style:use-window-font-color="true" fo:font-size="45%"/>
</text:list-level-style-bullet>
</text:list-style>
</office:automatic-styles>
<office:body>
<office:presentation>
~
;
}
sub
writeSlideHeader
{
my
$titleText
=
pop
@_
;
my
$slideNum
=
pop
@_
;
print
$OUT
" <draw:page draw:name=\"page1\" draw:style-name=\"dp1\" draw:master-page-name=\"Default\">\n"
;
print
$OUT
" <office:forms form:automatic-focus=\"false\" form:apply-design-mode=\"false\"/>\n"
;
print
$OUT
" <draw:rect draw:style-name=\"gr1\" draw:text-style-name=\"P1\" draw:id=\"id$slideNum\" draw:layer=\"layout\" svg:width=\"17.5cm\" svg:height=\"6cm\" svg:x=\"5cm\" svg:y=\"4cm\">\n"
;
print
$OUT
" <text:p text:style-name=\"P2\">Slide: $slideNum</text:p>\n"
;
print
$OUT
" <text:p text:style-name=\"P2\">Path: $titleText</text:p>\n"
;
print
$OUT
" </draw:rect>\n"
;
}
sub
writeSlideFooter
{
print
$OUT
" <presentation:notes draw:style-name=\"dp1\">\n"
;
print
$OUT
" <draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"14.851cm\" svg:height=\"11.138cm\" svg:x=\"3.068cm\" svg:y=\"2.257cm\" draw:page-number=\"1\" presentation:class=\"page\"/>\n"
;
print
$OUT
" <draw:frame presentation:style-name=\"pr3\" draw:layer=\"layout\" svg:width=\"16.79cm\" svg:height=\"13.116cm\" svg:x=\"2.098cm\" svg:y=\"14.109cm\" presentation:class=\"notes\" presentation:placeholder=\"true\">\n"
;
print
$OUT
" <draw:text-box/>\n"
;
print
$OUT
" </draw:frame>\n"
;
print
$OUT
" </presentation:notes>\n"
;
print
$OUT
" </draw:page>\n"
;
}
sub
writeFooter
{
print
$OUT
qq~ <presentation:settings presentation:full-screen="false"/>
</office:presentation>
</office:body>
</office:document-content>
~
;
}
sub
writePath
{
my
$pathAry
=
pop
@_
;
my
$path
=
$pathAry
->
[
1
];
my
$viewBox
=
$pathAry
->
[
0
];
print
$OUT
" <draw:path draw:style-name=\"gr2\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"10cm\" svg:height=\"10cm\" svg:x=\"5cm\" svg:y=\"5cm\" svg:viewBox=\""
;
print
$OUT
$viewBox
;
print
$OUT
"\" svg:d=\""
;
print
$OUT
$path
;
print
$OUT
"\">\n"
;
print
$OUT
" <text:p/>\n"
;
print
$OUT
" </draw:path>\n"
;
}
sub
writeManifest
{
my
$outFile
=
open_file
(
"META-INF/manifest.xml"
);
print
$outFile
qq~<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE manifest:manifest PUBLIC "-//OpenOffice.org//DTD Manifest 1.0//EN" "Manifest.dtd">
<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
<manifest:file-entry manifest:media-type="application/vnd.oasis.opendocument.presentation" manifest:full-path="/"/>
<manifest:file-entry manifest:media-type="text/xml" manifest:full-path="content.xml"/>
</manifest:manifest>
~
;
$outFile
->
close
;
}
###############################################################################
# Print usage information.
#
sub
usage
()
{
print
<<END_OF_USAGE;
usage: $0 <option>* [<SvgD-values>]
output-file-name defaults to polygons.odp.
-h Print this usage information.
-o output-file-name
END_OF_USAGE
}
###############################################################################
# Process the command line.
#
sub
process_command_line
{
foreach
(
@ARGV
)
{
if
(
/^-h/
)
{
usage
;
exit
0
;
}
}
$global_output_name
=
"polygons.odp"
;
my
$j
=
0
,
$noMoreOptions
=
0
;
for
(
my
$i
=
0
;
$i
<
$#ARGV
;
$i
++
)
{
if
(
!
$noMoreOptions
and
$ARGV
[
$i
]
eq
"-o"
)
{
$i
++
;
$global_output_name
=
$ARGV
[
$i
];
}
elsif
(
!
$noMoreOptions
and
$ARGV
[
$i
]
eq
"--"
)
{
$noMoreOptions
=
1
;
}
elsif
(
!
$noMoreOptions
and
$ARGV
[
$i
]
=~
/^-/
)
{
print
"Unknown option $ARGV[$i]\n"
;
usage
;
exit
1
;
}
else
{
push
(
@paths
,
[
$ARGV
[
$i
],
$ARGV
[
$i
+
1
]]);
$i
++
;
}
}
print
"output to $global_output_name\n"
;
}
###############################################################################
# Main
###############################################################################
$ZipCmd
=
$ENV
{
LOG_FILE_ZIP_CMD
};
$ZipFlags
=
$ENV
{
LOG_FILE_ZIP_FLAGS
};
# Provide default values for the zip command and it's flags.
if
(
!
defined
$ZipCmd
)
{
$ZipCmd
=
"zip"
unless
defined
$ZipCmd
;
$ZipFlags
=
"-r -q"
unless
defined
$ZipFlags
;
}
process_command_line
();
writeManifest
();
$OUT
=
open_file
(
"content.xml"
);
writeHeader
();
$pathNum
=
0
;
foreach
$path
(
@paths
)
{
writeSlideHeader
(
$pathNum
,
$path
->
[
1
]);
writePath
(
$path
);
writeSlideFooter
();
$pathNum
++
;
}
writeFooter
();
$OUT
->
close
;
zip_dirtree
(
$global_output_name
);
basegfx/source/polygon/b2dpolygon.cxx
Dosyayı görüntüle @
8454c5ef
...
@@ -44,38 +44,24 @@
...
@@ -44,38 +44,24 @@
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
class
CoordinateData2D
struct
CoordinateData2D
:
public
basegfx
::
B2DPoint
{
{
basegfx
::
B2DPoint
maPoint
;
public
:
public
:
CoordinateData2D
()
CoordinateData2D
()
{}
:
maPoint
()
{}
explicit
CoordinateData2D
(
const
basegfx
::
B2DPoint
&
rData
)
explicit
CoordinateData2D
(
const
basegfx
::
B2DPoint
&
rData
)
:
ma
Point
(
rData
)
:
B2D
Point
(
rData
)
{}
{}
const
basegfx
::
B2DPoint
&
getCoordinate
()
const
CoordinateData2D
&
operator
=
(
const
basegfx
::
B2DPoint
&
rData
)
{
return
maPoint
;
}
void
setCoordinate
(
const
basegfx
::
B2DPoint
&
rValue
)
{
if
(
rValue
!=
maPoint
)
maPoint
=
rValue
;
}
bool
operator
==
(
const
CoordinateData2D
&
rData
)
const
{
{
return
(
maPoint
==
rData
.
getCoordinate
());
B2DPoint
::
operator
=
(
rData
);
return
*
this
;
}
}
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
)
void
transform
(
const
basegfx
::
B2DHomMatrix
&
rMatrix
)
{
{
maPoint
*=
rMatrix
;
*
this
*=
rMatrix
;
}
}
};
};
...
@@ -115,12 +101,12 @@ public:
...
@@ -115,12 +101,12 @@ public:
const
basegfx
::
B2DPoint
&
getCoordinate
(
sal_uInt32
nIndex
)
const
const
basegfx
::
B2DPoint
&
getCoordinate
(
sal_uInt32
nIndex
)
const
{
{
return
maVector
[
nIndex
]
.
getCoordinate
()
;
return
maVector
[
nIndex
];
}
}
void
setCoordinate
(
sal_uInt32
nIndex
,
const
basegfx
::
B2DPoint
&
rValue
)
void
setCoordinate
(
sal_uInt32
nIndex
,
const
basegfx
::
B2DPoint
&
rValue
)
{
{
maVector
[
nIndex
]
.
setCoordinate
(
rValue
)
;
maVector
[
nIndex
]
=
rValue
;
}
}
void
insert
(
sal_uInt32
nIndex
,
const
CoordinateData2D
&
rValue
,
sal_uInt32
nCount
)
void
insert
(
sal_uInt32
nIndex
,
const
CoordinateData2D
&
rValue
,
sal_uInt32
nCount
)
...
@@ -221,6 +207,26 @@ public:
...
@@ -221,6 +207,26 @@ public:
aStart
->
transform
(
rMatrix
);
aStart
->
transform
(
rMatrix
);
}
}
}
}
const
basegfx
::
B2DPoint
*
begin
()
const
{
return
&
maVector
.
front
();
}
const
basegfx
::
B2DPoint
*
end
()
const
{
return
&
maVector
[
maVector
.
size
()];
}
basegfx
::
B2DPoint
*
begin
()
{
return
&
maVector
.
front
();
}
basegfx
::
B2DPoint
*
end
()
{
return
&
maVector
[
maVector
.
size
()];
}
};
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
...
@@ -1113,6 +1119,28 @@ public:
...
@@ -1113,6 +1119,28 @@ public:
maPoints
.
transform
(
rMatrix
);
maPoints
.
transform
(
rMatrix
);
}
}
}
}
const
basegfx
::
B2DPoint
*
begin
()
const
{
return
maPoints
.
begin
();
}
const
basegfx
::
B2DPoint
*
end
()
const
{
return
maPoints
.
end
();
}
basegfx
::
B2DPoint
*
begin
()
{
mpBufferedData
.
reset
();
return
maPoints
.
begin
();
}
basegfx
::
B2DPoint
*
end
()
{
mpBufferedData
.
reset
();
return
maPoints
.
end
();
}
};
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
...
@@ -1173,7 +1201,7 @@ namespace basegfx
...
@@ -1173,7 +1201,7 @@ namespace basegfx
return
mpPolygon
->
count
();
return
mpPolygon
->
count
();
}
}
B2DPoint
B2DPolygon
::
getB2DPoint
(
sal_uInt32
nIndex
)
const
const
B2DPoint
&
B2DPolygon
::
getB2DPoint
(
sal_uInt32
nIndex
)
const
{
{
OSL_ENSURE
(
nIndex
<
mpPolygon
->
count
(),
"B2DPolygon access outside range (!)"
);
OSL_ENSURE
(
nIndex
<
mpPolygon
->
count
(),
"B2DPolygon access outside range (!)"
);
...
@@ -1432,7 +1460,7 @@ namespace basegfx
...
@@ -1432,7 +1460,7 @@ namespace basegfx
return
mpPolygon
->
getDefaultAdaptiveSubdivision
(
*
this
);
return
mpPolygon
->
getDefaultAdaptiveSubdivision
(
*
this
);
}
}
B2DRange
B2DPolygon
::
getB2DRange
()
const
const
B2DRange
&
B2DPolygon
::
getB2DRange
()
const
{
{
return
mpPolygon
->
getB2DRange
(
*
this
);
return
mpPolygon
->
getB2DRange
(
*
this
);
}
}
...
@@ -1540,6 +1568,26 @@ namespace basegfx
...
@@ -1540,6 +1568,26 @@ namespace basegfx
mpPolygon
->
transform
(
rMatrix
);
mpPolygon
->
transform
(
rMatrix
);
}
}
}
}
const
B2DPoint
*
B2DPolygon
::
begin
()
const
{
return
mpPolygon
->
begin
();
}
const
B2DPoint
*
B2DPolygon
::
end
()
const
{
return
mpPolygon
->
end
();
}
B2DPoint
*
B2DPolygon
::
begin
()
{
return
mpPolygon
->
begin
();
}
B2DPoint
*
B2DPolygon
::
end
()
{
return
mpPolygon
->
end
();
}
}
// end of namespace basegfx
}
// end of namespace basegfx
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
...
...
basegfx/source/polygon/b2dpolypolygon.cxx
Dosyayı görüntüle @
8454c5ef
...
@@ -166,6 +166,26 @@ public:
...
@@ -166,6 +166,26 @@ public:
maPolygons
.
end
(),
maPolygons
.
end
(),
std
::
mem_fun_ref
(
&
basegfx
::
B2DPolygon
::
makeUnique
));
std
::
mem_fun_ref
(
&
basegfx
::
B2DPolygon
::
makeUnique
));
}
}
const
basegfx
::
B2DPolygon
*
begin
()
const
{
return
&
maPolygons
.
front
();
}
const
basegfx
::
B2DPolygon
*
end
()
const
{
return
&
maPolygons
[
maPolygons
.
size
()];
}
basegfx
::
B2DPolygon
*
begin
()
{
return
&
maPolygons
.
front
();
}
basegfx
::
B2DPolygon
*
end
()
{
return
&
maPolygons
[
maPolygons
.
size
()];
}
};
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
...
@@ -378,6 +398,26 @@ namespace basegfx
...
@@ -378,6 +398,26 @@ namespace basegfx
mpPolyPolygon
->
transform
(
rMatrix
);
mpPolyPolygon
->
transform
(
rMatrix
);
}
}
}
}
const
B2DPolygon
*
B2DPolyPolygon
::
begin
()
const
{
return
mpPolyPolygon
->
begin
();
}
const
B2DPolygon
*
B2DPolyPolygon
::
end
()
const
{
return
mpPolyPolygon
->
end
();
}
B2DPolygon
*
B2DPolyPolygon
::
begin
()
{
return
mpPolyPolygon
->
begin
();
}
B2DPolygon
*
B2DPolyPolygon
::
end
()
{
return
mpPolyPolygon
->
end
();
}
}
// end of namespace basegfx
}
// end of namespace basegfx
// eof
// eof
basegfx/source/range/b2dmultirange.cxx
deleted
100644 → 0
Dosyayı görüntüle @
44dfc8de
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.cxx,v $
* $Revision: 1.8 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"
#include <basegfx/range/b2drange.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2dmultirange.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <algorithm>
#include <vector>
namespace
basegfx
{
class
ImplB2DMultiRange
{
public
:
ImplB2DMultiRange
()
:
maBounds
(),
maRanges
()
{
}
explicit
ImplB2DMultiRange
(
const
B2DRange
&
rRange
)
:
maBounds
(),
maRanges
(
1
,
rRange
)
{
}
bool
isEmpty
()
const
{
// no ranges at all, or all ranges empty
return
maRanges
.
empty
()
||
::
std
::
count_if
(
maRanges
.
begin
(),
maRanges
.
end
(),
::
boost
::
mem_fn
(
&
B2DRange
::
isEmpty
)
)
==
static_cast
<
VectorOfRanges
::
difference_type
>
(
maRanges
.
size
());
}
void
reset
()
{
// swap in empty vector
VectorOfRanges
aTmp
;
maRanges
.
swap
(
aTmp
);
maBounds
.
reset
();
}
template
<
typename
ValueType
>
bool
isInside
(
const
ValueType
&
rValue
)
const
{
if
(
!
maBounds
.
isInside
(
rValue
)
)
return
false
;
// cannot use ::boost::bind here, since isInside is overloaded.
// It is currently not possible to resolve the overload
// by considering one of the other template arguments.
VectorOfRanges
::
const_iterator
aCurr
(
maRanges
.
begin
()
);
const
VectorOfRanges
::
const_iterator
aEnd
(
maRanges
.
end
()
);
while
(
aCurr
!=
aEnd
)
if
(
aCurr
->
isInside
(
rValue
)
)
return
true
;
return
false
;
}
bool
overlaps
(
const
B2DRange
&
rRange
)
const
{
if
(
!
maBounds
.
overlaps
(
rRange
)
)
return
false
;
const
VectorOfRanges
::
const_iterator
aEnd
(
maRanges
.
end
()
);
return
::
std
::
find_if
(
maRanges
.
begin
(),
aEnd
,
::
boost
::
bind
<
bool
>
(
::
boost
::
mem_fn
(
&
B2DRange
::
overlaps
),
_1
,
rRange
)
)
!=
aEnd
;
}
void
addRange
(
const
B2DRange
&
rRange
)
{
maRanges
.
push_back
(
rRange
);
maBounds
.
expand
(
rRange
);
}
B2DRange
getBounds
()
const
{
return
maBounds
;
}
B2DPolyPolygon
getPolyPolygon
()
const
{
B2DPolyPolygon
aRes
;
// Make range vector unique ( have to avoid duplicate
// rectangles. The polygon clipper will return an empty
// result in this case).
VectorOfRanges
aUniqueRanges
;
aUniqueRanges
.
reserve
(
maRanges
.
size
()
);
VectorOfRanges
::
const_iterator
aCurr
(
maRanges
.
begin
()
);
const
VectorOfRanges
::
const_iterator
aEnd
(
maRanges
.
end
()
);
while
(
aCurr
!=
aEnd
)
{
// TODO(F3): It's plain wasted resources to apply a
// general clipping algorithm to the problem at
// hand. Go for a dedicated, scan-line-based approach.
VectorOfRanges
::
const_iterator
aCurrScan
(
aCurr
+
1
);
VectorOfRanges
::
const_iterator
aFound
(
aEnd
);
while
(
aCurrScan
!=
aEnd
)
{
if
(
aCurrScan
->
equal
(
*
aCurr
)
||
aCurrScan
->
isInside
(
*
aCurr
)
)
{
// current probe is equal to aCurr, or
// completely contains aCurr. Thus, stop
// searching, because aCurr is definitely not
// a member of the unique rect list
aFound
=
aCurrScan
;
break
;
}
++
aCurrScan
;
}
if
(
aFound
==
aEnd
)
{
// check whether aCurr is fully contained in one
// of the already added rects. If yes, we can skip
// it.
bool
bUnique
(
true
);
VectorOfRanges
::
const_iterator
aCurrUnique
(
aUniqueRanges
.
begin
()
);
VectorOfRanges
::
const_iterator
aEndUnique
(
aUniqueRanges
.
end
()
);
while
(
aCurrUnique
!=
aEndUnique
)
{
if
(
aCurrUnique
->
isInside
(
*
aCurr
)
)
{
// fully contained, no need to add
bUnique
=
false
;
break
;
}
++
aCurrUnique
;
}
if
(
bUnique
)
aUniqueRanges
.
push_back
(
*
aCurr
);
}
++
aCurr
;
}
VectorOfRanges
::
const_iterator
aCurrUnique
(
aUniqueRanges
.
begin
()
);
const
VectorOfRanges
::
const_iterator
aEndUnique
(
aUniqueRanges
.
end
()
);
while
(
aCurrUnique
!=
aEndUnique
)
{
// simply merge all unique parts (OR)
aRes
.
append
(
tools
::
createPolygonFromRect
(
*
aCurrUnique
++
)
);
}
// remove redundant intersections. Note: since all added
// rectangles are positively oriented, this method cannot
// generate any holes.
aRes
=
basegfx
::
tools
::
solveCrossovers
(
aRes
);
aRes
=
basegfx
::
tools
::
stripNeutralPolygons
(
aRes
);
aRes
=
basegfx
::
tools
::
stripDispensablePolygons
(
aRes
,
false
);
return
aRes
;
}
private
:
typedef
::
std
::
vector
<
B2DRange
>
VectorOfRanges
;
B2DRange
maBounds
;
VectorOfRanges
maRanges
;
};
// ====================================================================
B2DMultiRange
::
B2DMultiRange
()
:
mpImpl
()
{
}
B2DMultiRange
::
B2DMultiRange
(
const
B2DRange
&
rRange
)
:
mpImpl
(
ImplB2DMultiRange
(
rRange
)
)
{
}
B2DMultiRange
::~
B2DMultiRange
()
{
// otherwise, ImplB2DMultiRange would be an incomplete type
}
B2DMultiRange
::
B2DMultiRange
(
const
B2DMultiRange
&
rSrc
)
:
mpImpl
(
rSrc
.
mpImpl
)
{
}
B2DMultiRange
&
B2DMultiRange
::
operator
=
(
const
B2DMultiRange
&
rSrc
)
{
mpImpl
=
rSrc
.
mpImpl
;
return
*
this
;
}
bool
B2DMultiRange
::
isEmpty
()
const
{
return
mpImpl
->
isEmpty
();
}
void
B2DMultiRange
::
reset
()
{
mpImpl
->
reset
();
}
bool
B2DMultiRange
::
isInside
(
const
B2DTuple
&
rTuple
)
const
{
return
mpImpl
->
isInside
(
rTuple
);
}
bool
B2DMultiRange
::
isInside
(
const
B2DRange
&
rRange
)
const
{
return
mpImpl
->
isInside
(
rRange
);
}
bool
B2DMultiRange
::
overlaps
(
const
B2DRange
&
rRange
)
const
{
return
mpImpl
->
overlaps
(
rRange
);
}
void
B2DMultiRange
::
addRange
(
const
B2DRange
&
rRange
)
{
mpImpl
->
addRange
(
rRange
);
}
B2DRange
B2DMultiRange
::
getBounds
()
const
{
return
mpImpl
->
getBounds
();
}
B2DPolyPolygon
B2DMultiRange
::
getPolyPolygon
()
const
{
return
mpImpl
->
getPolyPolygon
();
}
}
// end of namespace basegfx
// eof
basegfx/source/range/b2dpolyrange.cxx
0 → 100644
Dosyayı görüntüle @
8454c5ef
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.cxx,v $
* $Revision: 1.8 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/range/b2drangeclipper.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
#include <algorithm>
#include <vector>
static
basegfx
::
B2VectorOrientation
flipOrientation
(
basegfx
::
B2VectorOrientation
eOrient
)
{
return
eOrient
==
basegfx
::
ORIENTATION_POSITIVE
?
basegfx
::
ORIENTATION_NEGATIVE
:
basegfx
::
ORIENTATION_POSITIVE
;
}
namespace
basegfx
{
class
ImplB2DPolyRange
{
void
updateBounds
()
{
maBounds
.
reset
();
std
::
for_each
(
maRanges
.
begin
(),
maRanges
.
end
(),
boost
::
bind
(
(
void
(
B2DRange
::*
)(
const
B2DRange
&
))(
&
B2DRange
::
expand
),
boost
::
ref
(
maBounds
),
_1
));
}
public
:
ImplB2DPolyRange
()
:
maBounds
(),
maRanges
(),
maOrient
()
{}
explicit
ImplB2DPolyRange
(
const
B2DPolyRange
::
ElementType
&
rElem
)
:
maBounds
(
boost
::
get
<
0
>
(
rElem
)
),
maRanges
(
1
,
boost
::
get
<
0
>
(
rElem
)
),
maOrient
(
1
,
boost
::
get
<
1
>
(
rElem
)
)
{}
explicit
ImplB2DPolyRange
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
)
:
maBounds
(
rRange
),
maRanges
(
1
,
rRange
),
maOrient
(
1
,
eOrient
)
{}
bool
operator
==
(
const
ImplB2DPolyRange
&
rRHS
)
const
{
return
maRanges
==
rRHS
.
maRanges
&&
maOrient
==
rRHS
.
maOrient
;
}
sal_uInt32
count
()
const
{
return
maRanges
.
size
();
}
B2DPolyRange
::
ElementType
getElement
(
sal_uInt32
nIndex
)
const
{
return
boost
::
make_tuple
(
maRanges
[
nIndex
],
maOrient
[
nIndex
]);
}
void
setElement
(
sal_uInt32
nIndex
,
const
B2DPolyRange
::
ElementType
&
rElement
)
{
maRanges
[
nIndex
]
=
boost
::
get
<
0
>
(
rElement
);
maOrient
[
nIndex
]
=
boost
::
get
<
1
>
(
rElement
);
updateBounds
();
}
void
setElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
)
{
maRanges
[
nIndex
]
=
rRange
;
maOrient
[
nIndex
]
=
eOrient
;
updateBounds
();
}
void
insertElement
(
sal_uInt32
nIndex
,
const
B2DPolyRange
::
ElementType
&
rElement
,
sal_uInt32
nCount
)
{
maRanges
.
insert
(
maRanges
.
begin
()
+
nIndex
,
nCount
,
boost
::
get
<
0
>
(
rElement
));
maOrient
.
insert
(
maOrient
.
begin
()
+
nIndex
,
nCount
,
boost
::
get
<
1
>
(
rElement
));
maBounds
.
expand
(
boost
::
get
<
0
>
(
rElement
));
}
void
insertElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
)
{
maRanges
.
insert
(
maRanges
.
begin
()
+
nIndex
,
nCount
,
rRange
);
maOrient
.
insert
(
maOrient
.
begin
()
+
nIndex
,
nCount
,
eOrient
);
maBounds
.
expand
(
rRange
);
}
void
appendElement
(
const
B2DPolyRange
::
ElementType
&
rElement
,
sal_uInt32
nCount
)
{
maRanges
.
insert
(
maRanges
.
end
(),
nCount
,
boost
::
get
<
0
>
(
rElement
));
maOrient
.
insert
(
maOrient
.
end
(),
nCount
,
boost
::
get
<
1
>
(
rElement
));
maBounds
.
expand
(
boost
::
get
<
0
>
(
rElement
));
}
void
appendElement
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
)
{
maRanges
.
insert
(
maRanges
.
end
(),
nCount
,
rRange
);
maOrient
.
insert
(
maOrient
.
end
(),
nCount
,
eOrient
);
maBounds
.
expand
(
rRange
);
}
void
insertPolyRange
(
sal_uInt32
nIndex
,
const
ImplB2DPolyRange
&
rPolyRange
)
{
maRanges
.
insert
(
maRanges
.
begin
()
+
nIndex
,
rPolyRange
.
maRanges
.
begin
(),
rPolyRange
.
maRanges
.
end
());
maOrient
.
insert
(
maOrient
.
begin
()
+
nIndex
,
rPolyRange
.
maOrient
.
begin
(),
rPolyRange
.
maOrient
.
end
());
updateBounds
();
}
void
appendPolyRange
(
const
ImplB2DPolyRange
&
rPolyRange
)
{
maRanges
.
insert
(
maRanges
.
end
(),
rPolyRange
.
maRanges
.
begin
(),
rPolyRange
.
maRanges
.
end
());
maOrient
.
insert
(
maOrient
.
end
(),
rPolyRange
.
maOrient
.
begin
(),
rPolyRange
.
maOrient
.
end
());
updateBounds
();
}
void
remove
(
sal_uInt32
nIndex
,
sal_uInt32
nCount
)
{
maRanges
.
erase
(
maRanges
.
begin
()
+
nIndex
,
maRanges
.
begin
()
+
nIndex
+
nCount
);
maOrient
.
erase
(
maOrient
.
begin
()
+
nIndex
,
maOrient
.
begin
()
+
nIndex
+
nCount
);
updateBounds
();
}
void
clear
()
{
std
::
vector
<
B2DRange
>
aTmpRanges
;
std
::
vector
<
B2VectorOrientation
>
aTmpOrient
;
maRanges
.
swap
(
aTmpRanges
);
maOrient
.
swap
(
aTmpOrient
);
maBounds
.
reset
();
}
void
flip
()
{
std
::
for_each
(
maOrient
.
begin
(),
maOrient
.
end
(),
boost
::
bind
(
&
flipOrientation
,
_1
));
}
B2DRange
getBounds
()
const
{
return
maBounds
;
}
template
<
typename
ValueType
>
bool
isInside
(
const
ValueType
&
rValue
)
const
{
if
(
!
maBounds
.
isInside
(
rValue
)
)
return
false
;
// cannot use boost::bind here, since isInside is overloaded.
// It is currently not possible to resolve the overload
// by considering one of the other template arguments.
std
::
vector
<
B2DRange
>::
const_iterator
aCurr
(
maRanges
.
begin
()
);
const
std
::
vector
<
B2DRange
>::
const_iterator
aEnd
(
maRanges
.
end
()
);
while
(
aCurr
!=
aEnd
)
if
(
aCurr
->
isInside
(
rValue
)
)
return
true
;
return
false
;
}
bool
overlaps
(
const
B2DRange
&
rRange
)
const
{
if
(
!
maBounds
.
overlaps
(
rRange
)
)
return
false
;
const
std
::
vector
<
B2DRange
>::
const_iterator
aEnd
(
maRanges
.
end
()
);
return
std
::
find_if
(
maRanges
.
begin
(),
aEnd
,
boost
::
bind
<
bool
>
(
boost
::
mem_fn
(
&
B2DRange
::
overlaps
),
_1
,
boost
::
cref
(
rRange
)
)
)
!=
aEnd
;
}
B2DPolyPolygon
solveCrossovers
()
const
{
return
tools
::
solveCrossovers
(
maRanges
,
maOrient
);
}
private
:
B2DRange
maBounds
;
std
::
vector
<
B2DRange
>
maRanges
;
std
::
vector
<
B2VectorOrientation
>
maOrient
;
};
B2DPolyRange
::
B2DPolyRange
()
:
mpImpl
()
{}
B2DPolyRange
::~
B2DPolyRange
()
{}
B2DPolyRange
::
B2DPolyRange
(
const
ElementType
&
rElem
)
:
mpImpl
(
ImplB2DPolyRange
(
rElem
)
)
{}
B2DPolyRange
::
B2DPolyRange
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
)
:
mpImpl
(
ImplB2DPolyRange
(
rRange
,
eOrient
)
)
{}
B2DPolyRange
::
B2DPolyRange
(
const
B2DPolyRange
&
rRange
)
:
mpImpl
(
rRange
.
mpImpl
)
{}
B2DPolyRange
&
B2DPolyRange
::
operator
=
(
const
B2DPolyRange
&
rRange
)
{
mpImpl
=
rRange
.
mpImpl
;
return
*
this
;
}
void
B2DPolyRange
::
makeUnique
()
{
mpImpl
.
make_unique
();
}
bool
B2DPolyRange
::
operator
==
(
const
B2DPolyRange
&
rRange
)
const
{
if
(
mpImpl
.
same_object
(
rRange
.
mpImpl
))
return
true
;
return
((
*
mpImpl
)
==
(
*
rRange
.
mpImpl
));
}
bool
B2DPolyRange
::
operator
!=
(
const
B2DPolyRange
&
rRange
)
const
{
return
!
(
*
this
==
rRange
);
}
sal_uInt32
B2DPolyRange
::
count
()
const
{
return
mpImpl
->
count
();
}
B2DPolyRange
::
ElementType
B2DPolyRange
::
getElement
(
sal_uInt32
nIndex
)
const
{
return
mpImpl
->
getElement
(
nIndex
);
}
void
B2DPolyRange
::
setElement
(
sal_uInt32
nIndex
,
const
ElementType
&
rElement
)
{
mpImpl
->
setElement
(
nIndex
,
rElement
);
}
void
B2DPolyRange
::
setElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
)
{
mpImpl
->
setElement
(
nIndex
,
rRange
,
eOrient
);
}
void
B2DPolyRange
::
insertElement
(
sal_uInt32
nIndex
,
const
ElementType
&
rElement
,
sal_uInt32
nCount
)
{
mpImpl
->
insertElement
(
nIndex
,
rElement
,
nCount
);
}
void
B2DPolyRange
::
insertElement
(
sal_uInt32
nIndex
,
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
)
{
mpImpl
->
insertElement
(
nIndex
,
rRange
,
eOrient
,
nCount
);
}
void
B2DPolyRange
::
appendElement
(
const
ElementType
&
rElement
,
sal_uInt32
nCount
)
{
mpImpl
->
appendElement
(
rElement
,
nCount
);
}
void
B2DPolyRange
::
appendElement
(
const
B2DRange
&
rRange
,
B2VectorOrientation
eOrient
,
sal_uInt32
nCount
)
{
mpImpl
->
appendElement
(
rRange
,
eOrient
,
nCount
);
}
void
B2DPolyRange
::
insertPolyRange
(
sal_uInt32
nIndex
,
const
B2DPolyRange
&
rRange
)
{
mpImpl
->
insertPolyRange
(
nIndex
,
*
rRange
.
mpImpl
);
}
void
B2DPolyRange
::
appendPolyRange
(
const
B2DPolyRange
&
rRange
)
{
mpImpl
->
appendPolyRange
(
*
rRange
.
mpImpl
);
}
void
B2DPolyRange
::
remove
(
sal_uInt32
nIndex
,
sal_uInt32
nCount
)
{
mpImpl
->
remove
(
nIndex
,
nCount
);
}
void
B2DPolyRange
::
clear
()
{
mpImpl
->
clear
();
}
void
B2DPolyRange
::
flip
()
{
mpImpl
->
flip
();
}
B2DRange
B2DPolyRange
::
getBounds
()
const
{
return
mpImpl
->
getBounds
();
}
bool
B2DPolyRange
::
isInside
(
const
B2DTuple
&
rTuple
)
const
{
return
mpImpl
->
isInside
(
rTuple
);
}
bool
B2DPolyRange
::
isInside
(
const
B2DRange
&
rRange
)
const
{
return
mpImpl
->
isInside
(
rRange
);
}
bool
B2DPolyRange
::
overlaps
(
const
B2DRange
&
rRange
)
const
{
return
mpImpl
->
overlaps
(
rRange
);
}
B2DPolyPolygon
B2DPolyRange
::
solveCrossovers
()
const
{
return
mpImpl
->
solveCrossovers
();
}
}
// end of namespace basegfx
// eof
basegfx/source/range/b2drangeclipper.cxx
0 → 100644
Dosyayı görüntüle @
8454c5ef
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: b2dmultirange.cxx,v $
* $Revision: 1.8 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"
#include <rtl/math.hxx>
#include <basegfx/tuple/b2dtuple.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <o3tl/vector_pool.hxx>
#include <boost/bind.hpp>
#include <boost/utility.hpp>
#include <algorithm>
#include <deque>
#include <list>
namespace
basegfx
{
namespace
{
// Generating a poly-polygon from a bunch of rectangles
//
// Helper functionality for sweep-line algorithm
// ====================================================
typedef
std
::
vector
<
B2DRange
>
VectorOfRanges
;
class
ImplPolygon
;
typedef
o3tl
::
vector_pool
<
ImplPolygon
>
VectorOfPolygons
;
/** This class represents an active edge
As the sweep line traverses across the overall area,
rectangle edges parallel to it generate events, and
rectangle edges orthogonal to it generate active
edges. This class represents the latter.
*/
class
ActiveEdge
{
public
:
/** The two possible active rectangle edges differ by one
coordinate value - the upper edge has the lower, the
lower edge the higher value.
*/
enum
EdgeType
{
/// edge with lower coordinate value
UPPER
=
0
,
/// edge with higher coordinate value
LOWER
=
1
};
enum
EdgeDirection
{
/// edge proceeds to the left
PROCEED_LEFT
=
0
,
/// edge proceeds to the right
PROCEED_RIGHT
=
1
};
/** Create active edge
@param rRect
Rectangle this edge is part of
@param fInvariantCoord
The invariant ccordinate value of this edge
@param eEdgeType
Is fInvariantCoord the lower or the higher value, for
this rect?
*/
ActiveEdge
(
const
B2DRectangle
&
rRect
,
const
double
&
fInvariantCoord
,
std
::
ptrdiff_t
nPolyIdx
,
EdgeType
eEdgeType
,
EdgeDirection
eEdgeDirection
)
:
mfInvariantCoord
(
fInvariantCoord
),
mpAssociatedRect
(
&
rRect
),
mnPolygonIdx
(
nPolyIdx
),
meEdgeType
(
eEdgeType
),
meEdgeDirection
(
eEdgeDirection
)
{}
double
getInvariantCoord
()
const
{
return
mfInvariantCoord
;
}
const
B2DRectangle
&
getRect
()
const
{
return
*
mpAssociatedRect
;
}
std
::
ptrdiff_t
getTargetPolygonIndex
()
const
{
return
mnPolygonIdx
;
}
void
setTargetPolygonIndex
(
std
::
ptrdiff_t
nIdx
)
{
mnPolygonIdx
=
nIdx
;
}
EdgeType
getEdgeType
()
const
{
return
meEdgeType
;
}
EdgeDirection
getEdgeDirection
()
const
{
return
meEdgeDirection
;
}
/// For STL sort
bool
operator
<
(
const
ActiveEdge
&
rRHS
)
const
{
return
mfInvariantCoord
<
rRHS
.
mfInvariantCoord
;
}
private
:
/** The invariant coordinate value of this edge (e.g. the
common y value, for a horizontal edge)
*/
double
mfInvariantCoord
;
/** Associated rectangle
This on the one hand saves some storage space (the
vector of rectangles is persistent, anyway), and on
the other hand provides an identifier to match active
edges and x events (see below)
Ptr because class needs to be assignable
*/
const
B2DRectangle
*
mpAssociatedRect
;
/** Index of the polygon this edge is currently involved
with.
Note that this can change for some kinds of edge
intersection, as the algorithm tends to swap
associated polygons there.
-1 denotes no assigned polygon
*/
std
::
ptrdiff_t
mnPolygonIdx
;
/// 'upper' or 'lower' edge of original rectangle.
EdgeType
meEdgeType
;
/// 'left' or 'right'
EdgeDirection
meEdgeDirection
;
};
// Needs to be list - various places hold ptrs to elements
typedef
std
::
list
<
ActiveEdge
>
ListOfEdges
;
/** Element of the sweep line event list
As the sweep line traverses across the overall area,
rectangle edges parallel to it generate events, and
rectangle edges orthogonal to it generate active
edges. This class represents the former.
The class defines an element of the sweep line list. The
sweep line's position jumps in steps defined by the
coordinates of the sorted SweepLineEvent entries.
*/
class
SweepLineEvent
{
public
:
/** The two possible sweep line rectangle edges differ by
one coordinate value - the starting edge has the
lower, the finishing edge the higher value.
*/
enum
EdgeType
{
/// edge with lower coordinate value
STARTING_EDGE
=
0
,
/// edge with higher coordinate value
FINISHING_EDGE
=
1
};
/** The two possible sweep line directions
*/
enum
EdgeDirection
{
PROCEED_UP
=
0
,
PROCEED_DOWN
=
1
};
/** Create sweep line event
@param fPos
Coordinate position of the event
@param rRect
Rectangle this event is generated for.
@param eEdgeType
Is fPos the lower or the higher value, for the
rectangle this event is generated for?
*/
SweepLineEvent
(
double
fPos
,
const
B2DRectangle
&
rRect
,
EdgeType
eEdgeType
,
EdgeDirection
eDirection
)
:
mfPos
(
fPos
),
mpAssociatedRect
(
&
rRect
),
meEdgeType
(
eEdgeType
),
meEdgeDirection
(
eDirection
)
{}
double
getPos
()
const
{
return
mfPos
;
}
const
B2DRectangle
&
getRect
()
const
{
return
*
mpAssociatedRect
;
}
EdgeType
getEdgeType
()
const
{
return
meEdgeType
;
}
EdgeDirection
getEdgeDirection
()
const
{
return
meEdgeDirection
;
}
/// For STL sort
bool
operator
<
(
const
SweepLineEvent
&
rRHS
)
const
{
return
mfPos
<
rRHS
.
mfPos
;
}
private
:
/// position of the event, in the direction of the line sweep
double
mfPos
;
/** Rectangle this event is generated for
This on the one hand saves some storage space (the
vector of rectangles is persistent, anyway), and on
the other hand provides an identifier to match active
edges and events (see below)
Ptr because class needs to be assignable
*/
const
B2DRectangle
*
mpAssociatedRect
;
/// 'upper' or 'lower' edge of original rectangle.
EdgeType
meEdgeType
;
/// 'up' or 'down'
EdgeDirection
meEdgeDirection
;
};
typedef
std
::
vector
<
SweepLineEvent
>
VectorOfEvents
;
/** Smart point container for B2DMultiRange::getPolyPolygon()
This class provides methods needed only here, and is used
as a place to store some additional information per
polygon. Also, most of the intersection logic is
implemented here.
*/
class
ImplPolygon
{
public
:
/** Create polygon
*/
ImplPolygon
()
:
mpLeadingRightEdge
(
NULL
),
mnIdx
(
-
1
),
maPoints
(),
mbIsFinished
(
false
)
{
// completely ad-hoc. but what the hell.
maPoints
.
reserve
(
11
);
}
void
setPolygonPoolIndex
(
std
::
ptrdiff_t
nIdx
)
{
mnIdx
=
nIdx
;
}
bool
isFinished
()
const
{
return
mbIsFinished
;
}
/// Add point to the end of the existing points
void
append
(
const
B2DPoint
&
rPoint
)
{
OSL_PRECOND
(
maPoints
.
empty
()
||
maPoints
.
back
().
getX
()
==
rPoint
.
getX
()
||
maPoints
.
back
().
getY
()
==
rPoint
.
getY
(),
"ImplPolygon::append(): added point violates 90 degree line angle constraint!"
);
if
(
maPoints
.
empty
()
||
maPoints
.
back
()
!=
rPoint
)
{
// avoid duplicate points
maPoints
.
push_back
(
rPoint
);
}
}
/** Perform the intersection of this polygon with an
active edge.
@param rEvent
The vertical line event that generated the
intersection
@param rActiveEdge
The active edge that generated the intersection
@param rPolygonPool
Polygon pool, we sometimes need to allocate a new one
@param bIsFinishingEdge
True, when this is hitting the last edge of the
vertical sweep - every vertical sweep starts and ends
with upper and lower edge of the _same_ rectangle.
@return the new current polygon (that's the one
processing must proceed with, when going through the
list of upcoming active edges).
*/
std
::
ptrdiff_t
intersect
(
SweepLineEvent
&
rEvent
,
ActiveEdge
&
rActiveEdge
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
,
bool
isFinishingEdge
)
{
OSL_PRECOND
(
!
isFinished
(),
"ImplPolygon::intersect(): called on already finished polygon!"
);
OSL_PRECOND
(
!
isFinishingEdge
||
(
isFinishingEdge
&&
&
rEvent
.
getRect
()
==
&
rActiveEdge
.
getRect
()),
"ImplPolygon::intersect(): inconsistent ending!"
);
const
B2DPoint
aIntersectionPoint
(
rEvent
.
getPos
(),
rActiveEdge
.
getInvariantCoord
()
);
// intersection point, goes to our polygon
// unconditionally
append
(
aIntersectionPoint
);
const
bool
isSweepLineEnteringRect
(
rEvent
.
getEdgeType
()
==
SweepLineEvent
::
STARTING_EDGE
);
if
(
isFinishingEdge
)
{
if
(
isSweepLineEnteringRect
)
handleFinalOwnRightEdge
(
rActiveEdge
);
else
handleFinalOwnLeftEdge
(
rActiveEdge
,
rPolygonPool
,
rRes
);
// we're done with this rect & sweep line
return
-
1
;
}
else
if
(
metOwnEdge
(
rEvent
,
rActiveEdge
)
)
{
handleInitialOwnEdge
(
rEvent
,
rActiveEdge
);
// point already added, all init done, continue
// with same poly
return
mnIdx
;
}
else
{
OSL_ENSURE
(
rActiveEdge
.
getTargetPolygonIndex
()
!=
-
1
,
"ImplPolygon::intersect(): non-trivial intersection hit empty polygon!"
);
const
bool
isHittingLeftEdge
(
rActiveEdge
.
getEdgeDirection
()
==
ActiveEdge
::
PROCEED_LEFT
);
if
(
isHittingLeftEdge
)
return
handleComplexLeftEdge
(
rActiveEdge
,
aIntersectionPoint
,
rPolygonPool
,
rRes
);
else
return
handleComplexRightEdge
(
rActiveEdge
,
aIntersectionPoint
,
rPolygonPool
);
}
}
private
:
std
::
ptrdiff_t
getPolygonPoolIndex
()
const
{
return
mnIdx
;
}
void
handleInitialOwnEdge
(
SweepLineEvent
&
rEvent
,
ActiveEdge
&
rActiveEdge
)
{
const
bool
isActiveEdgeProceedLeft
(
rActiveEdge
.
getEdgeDirection
()
==
ActiveEdge
::
PROCEED_LEFT
);
const
bool
isSweepLineEnteringRect
(
rEvent
.
getEdgeType
()
==
SweepLineEvent
::
STARTING_EDGE
);
(
void
)
isActiveEdgeProceedLeft
;
(
void
)
isSweepLineEnteringRect
;
OSL_ENSURE
(
isSweepLineEnteringRect
==
isActiveEdgeProceedLeft
,
"ImplPolygon::intersect(): sweep initial own edge hit: wrong polygon order"
);
OSL_ENSURE
(
isSweepLineEnteringRect
||
mpLeadingRightEdge
==
&
rActiveEdge
,
"ImplPolygon::intersect(): sweep initial own edge hit: wrong leading edge"
);
}
void
handleFinalOwnRightEdge
(
ActiveEdge
&
rActiveEdge
)
{
OSL_ENSURE
(
rActiveEdge
.
getEdgeDirection
()
==
ActiveEdge
::
PROCEED_RIGHT
,
"ImplPolygon::handleInitialOwnRightEdge(): start edge wrong polygon order"
);
rActiveEdge
.
setTargetPolygonIndex
(
mnIdx
);
mpLeadingRightEdge
=
&
rActiveEdge
;
}
void
handleFinalOwnLeftEdge
(
ActiveEdge
&
rActiveEdge
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
OSL_ENSURE
(
rActiveEdge
.
getEdgeDirection
()
==
ActiveEdge
::
PROCEED_LEFT
,
"ImplPolygon::handleFinalOwnLeftEdge(): end edge wrong polygon order"
);
const
bool
isHittingOurTail
(
rActiveEdge
.
getTargetPolygonIndex
()
==
mnIdx
);
if
(
isHittingOurTail
)
finish
(
rRes
);
// just finish. no fuss.
else
{
// temp poly hits final left edge
const
std
::
ptrdiff_t
nTmpIdx
=
rActiveEdge
.
getTargetPolygonIndex
();
ImplPolygon
&
rTmp
=
rPolygonPool
.
get
(
nTmpIdx
);
// active edge's polygon has points
// already. ours need to go in front of them.
maPoints
.
insert
(
maPoints
.
end
(),
rTmp
.
maPoints
.
begin
(),
rTmp
.
maPoints
.
end
());
// adjust leading edges, we're switching the polygon
ActiveEdge
*
const
pFarEdge
=
rTmp
.
mpLeadingRightEdge
;
mpLeadingRightEdge
=
pFarEdge
;
pFarEdge
->
setTargetPolygonIndex
(
mnIdx
);
// nTmpIdx is an empty shell, get rid of it
rPolygonPool
.
free
(
nTmpIdx
);
}
}
std
::
ptrdiff_t
handleComplexLeftEdge
(
ActiveEdge
&
rActiveEdge
,
const
B2DPoint
&
rIntersectionPoint
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
const
bool
isHittingOurTail
(
rActiveEdge
.
getTargetPolygonIndex
()
==
mnIdx
);
if
(
isHittingOurTail
)
{
finish
(
rRes
);
// so "this" is done - need new polygon to collect
// further points
const
std
::
ptrdiff_t
nIdxNewPolygon
=
rPolygonPool
.
alloc
();
rPolygonPool
.
get
(
nIdxNewPolygon
).
setPolygonPoolIndex
(
nIdxNewPolygon
);
rPolygonPool
.
get
(
nIdxNewPolygon
).
append
(
rIntersectionPoint
);
rActiveEdge
.
setTargetPolygonIndex
(
nIdxNewPolygon
);
return
nIdxNewPolygon
;
}
else
{
const
std
::
ptrdiff_t
nTmpIdx
=
rActiveEdge
.
getTargetPolygonIndex
();
ImplPolygon
&
rTmp
=
rPolygonPool
.
get
(
nTmpIdx
);
// active edge's polygon has points
// already. ours need to go in front of them.
maPoints
.
insert
(
maPoints
.
end
(),
rTmp
.
maPoints
.
begin
(),
rTmp
.
maPoints
.
end
());
rTmp
.
maPoints
.
clear
();
rTmp
.
append
(
rIntersectionPoint
);
// adjust leading edges, we're switching the polygon
ActiveEdge
*
const
pFarEdge
=
rTmp
.
mpLeadingRightEdge
;
ActiveEdge
*
const
pNearEdge
=&
rActiveEdge
;
rTmp
.
mpLeadingRightEdge
=
NULL
;
pNearEdge
->
setTargetPolygonIndex
(
nTmpIdx
);
mpLeadingRightEdge
=
pFarEdge
;
pFarEdge
->
setTargetPolygonIndex
(
mnIdx
);
return
nTmpIdx
;
}
}
std
::
ptrdiff_t
handleComplexRightEdge
(
ActiveEdge
&
rActiveEdge
,
const
B2DPoint
&
rIntersectionPoint
,
VectorOfPolygons
&
rPolygonPool
)
{
const
std
::
ptrdiff_t
nTmpIdx
=
rActiveEdge
.
getTargetPolygonIndex
();
ImplPolygon
&
rTmp
=
rPolygonPool
.
get
(
nTmpIdx
);
rTmp
.
append
(
rIntersectionPoint
);
rActiveEdge
.
setTargetPolygonIndex
(
mnIdx
);
mpLeadingRightEdge
=
&
rActiveEdge
;
rTmp
.
mpLeadingRightEdge
=
NULL
;
return
nTmpIdx
;
}
/// True when sweep line hits our own active edge
bool
metOwnEdge
(
const
SweepLineEvent
&
rEvent
,
ActiveEdge
&
rActiveEdge
)
{
const
bool
bHitOwnEdge
=&
rEvent
.
getRect
()
==
&
rActiveEdge
.
getRect
();
return
bHitOwnEdge
;
}
/// Retrieve B2DPolygon from this object
B2DPolygon
getPolygon
()
const
{
B2DPolygon
aRes
;
std
::
for_each
(
maPoints
.
begin
(),
maPoints
.
end
(),
boost
::
bind
(
&
B2DPolygon
::
append
,
boost
::
ref
(
aRes
),
_1
,
1
)
);
aRes
.
setClosed
(
true
);
return
aRes
;
}
/** Finish this polygon, push to result set.
*/
void
finish
(
B2DPolyPolygon
&
rRes
)
{
OSL_PRECOND
(
maPoints
.
empty
()
||
maPoints
.
front
().
getX
()
==
maPoints
.
back
().
getX
()
||
maPoints
.
front
().
getY
()
==
maPoints
.
back
().
getY
(),
"ImplPolygon::finish(): first and last point violate 90 degree line angle constraint!"
);
mbIsFinished
=
true
;
mpLeadingRightEdge
=
NULL
;
rRes
.
append
(
getPolygon
());
}
/** Refers to the current leading edge element of this
polygon, or NULL. The leading edge denotes the 'front'
of the polygon vertex sequence, i.e. the coordinates
at the polygon's leading edge are returned from
maPoints.front()
*/
ActiveEdge
*
mpLeadingRightEdge
;
/// current index into vector pool
std
::
ptrdiff_t
mnIdx
;
/// Container for the actual polygon points
std
::
vector
<
B2DPoint
>
maPoints
;
/// When true, this polygon is 'done', i.e. nothing must be added anymore.
bool
mbIsFinished
;
};
/** Init sweep line event list
This method fills the event list with the sweep line
events generated from the input rectangles, and sorts them
with increasing x.
*/
void
setupSweepLineEventListFromRanges
(
VectorOfEvents
&
o_rEventVector
,
const
std
::
vector
<
B2DRange
>&
rRanges
,
const
std
::
vector
<
B2VectorOrientation
>&
rOrientations
)
{
// we need exactly 2*rectVec.size() events: one for the
// left, and one for the right edge of each rectangle
o_rEventVector
.
clear
();
o_rEventVector
.
reserve
(
2
*
rRanges
.
size
()
);
// generate events
// ===============
// first pass: add all left edges in increasing order
std
::
vector
<
B2DRange
>::
const_iterator
aCurrRect
=
rRanges
.
begin
();
std
::
vector
<
B2VectorOrientation
>::
const_iterator
aCurrOrientation
=
rOrientations
.
begin
();
const
std
::
vector
<
B2DRange
>::
const_iterator
aEnd
=
rRanges
.
end
();
const
std
::
vector
<
B2VectorOrientation
>::
const_iterator
aEndOrientation
=
rOrientations
.
end
();
while
(
aCurrRect
!=
aEnd
&&
aCurrOrientation
!=
aEndOrientation
)
{
const
B2DRectangle
&
rCurrRect
(
*
aCurrRect
++
);
o_rEventVector
.
push_back
(
SweepLineEvent
(
rCurrRect
.
getMinX
(),
rCurrRect
,
SweepLineEvent
::
STARTING_EDGE
,
(
*
aCurrOrientation
++
)
==
ORIENTATION_POSITIVE
?
SweepLineEvent
::
PROCEED_UP
:
SweepLineEvent
::
PROCEED_DOWN
)
);
}
// second pass: add all right edges in reversed order
std
::
vector
<
B2DRange
>::
const_reverse_iterator
aCurrRectR
=
rRanges
.
rbegin
();
std
::
vector
<
B2VectorOrientation
>::
const_reverse_iterator
aCurrOrientationR
=
rOrientations
.
rbegin
();
const
std
::
vector
<
B2DRange
>::
const_reverse_iterator
aEndR
=
rRanges
.
rend
();
const
std
::
vector
<
B2VectorOrientation
>::
const_reverse_iterator
aEndOrientationR
=
rOrientations
.
rend
();
while
(
aCurrRectR
!=
aEndR
)
{
const
B2DRectangle
&
rCurrRect
(
*
aCurrRectR
++
);
o_rEventVector
.
push_back
(
SweepLineEvent
(
rCurrRect
.
getMaxX
(),
rCurrRect
,
SweepLineEvent
::
FINISHING_EDGE
,
(
*
aCurrOrientationR
++
)
==
ORIENTATION_POSITIVE
?
SweepLineEvent
::
PROCEED_DOWN
:
SweepLineEvent
::
PROCEED_UP
)
);
}
// sort events
// ===========
// since we use stable_sort, the order of events with the
// same x value will not change. The elaborate two-pass
// add above thus ensures, that for each two rectangles
// with similar left and right x coordinates, the
// rectangle whose left event comes first will have its
// right event come last. This is advantageous for the
// clip algorithm below, see handleRightEdgeCrossing().
// TODO(P3): Use radix sort (from
// b2dpolypolygonrasterconverter, or have your own
// templatized version).
std
::
stable_sort
(
o_rEventVector
.
begin
(),
o_rEventVector
.
end
()
);
}
/** Insert two active edge segments for the given rectangle.
This method creates two active edge segments from the
given rect, and inserts them into the active edge list,
such that this stays sorted (if it was before).
@param io_rEdgeList
Active edge list to insert into
@param io_rPolygons
Vector of polygons. Each rectangle added creates one
tentative result polygon in this vector, and the edge list
entries holds a reference to that polygon (this _requires_
that the polygon vector does not reallocate, i.e. it must
have at least the maximal number of rectangles reserved)
@param o_CurrentPolygon
The then-current polygon when processing this sweep line
event
@param rCurrEvent
The actual event that caused this call
*/
void
createActiveEdgesFromStartEvent
(
ListOfEdges
&
io_rEdgeList
,
VectorOfPolygons
&
io_rPolygonPool
,
SweepLineEvent
&
rCurrEvent
)
{
ListOfEdges
aNewEdges
;
const
B2DRectangle
&
rRect
=
rCurrEvent
.
getRect
();
const
bool
bGoesDown
=
rCurrEvent
.
getEdgeDirection
()
==
SweepLineEvent
::
PROCEED_DOWN
;
// start event - new rect starts here, needs polygon to
// collect points into
const
std
::
ptrdiff_t
nIdxPolygon
=
io_rPolygonPool
.
alloc
();
io_rPolygonPool
.
get
(
nIdxPolygon
).
setPolygonPoolIndex
(
nIdxPolygon
);
// upper edge
aNewEdges
.
push_back
(
ActiveEdge
(
rRect
,
rRect
.
getMinY
(),
bGoesDown
?
nIdxPolygon
:
-
1
,
ActiveEdge
::
UPPER
,
bGoesDown
?
ActiveEdge
::
PROCEED_LEFT
:
ActiveEdge
::
PROCEED_RIGHT
)
);
// lower edge
aNewEdges
.
push_back
(
ActiveEdge
(
rRect
,
rRect
.
getMaxY
(),
bGoesDown
?
-
1
:
nIdxPolygon
,
ActiveEdge
::
LOWER
,
bGoesDown
?
ActiveEdge
::
PROCEED_RIGHT
:
ActiveEdge
::
PROCEED_LEFT
)
);
// furthermore, have to respect a special tie-breaking
// rule here, for edges which share the same y value:
// newly added upper edges must be inserted _before_ any
// other edge with the same y value, and newly added lower
// edges must be _after_ all other edges with the same
// y. This ensures that the left vertical edge processing
// below encounters the upper edge of the current rect
// first, and the lower edge last, which automatically
// starts and finishes this rect correctly (as only then,
// the polygon will have their associated active edges
// set).
const
double
nMinY
(
rRect
.
getMinY
()
);
const
double
nMaxY
(
rRect
.
getMaxY
()
);
ListOfEdges
::
iterator
aCurr
(
io_rEdgeList
.
begin
()
);
const
ListOfEdges
::
iterator
aEnd
(
io_rEdgeList
.
end
()
);
while
(
aCurr
!=
aEnd
)
{
const
double
nCurrY
(
aCurr
->
getInvariantCoord
()
);
if
(
nCurrY
>=
nMinY
&&
aNewEdges
.
size
()
==
2
)
// only add, if not yet done.
{
// insert upper edge _before_ aCurr. Thus, it will
// be the first entry for a range of equal y
// values. Using splice here, since we hold
// references to the moved list element!
io_rEdgeList
.
splice
(
aCurr
,
aNewEdges
,
aNewEdges
.
begin
()
);
}
if
(
nCurrY
>
nMaxY
)
{
// insert lower edge _before_ aCurr. Thus, it will
// be the last entry for a range of equal y values
// (aCurr is the first entry strictly larger than
// nMaxY). Using splice here, since we hold
// references to the moved list element!
io_rEdgeList
.
splice
(
aCurr
,
aNewEdges
,
aNewEdges
.
begin
()
);
// done with insertion, can early-exit here.
return
;
}
++
aCurr
;
}
// append remainder of aNewList (might still contain 2 or
// 1 elements, depending of the contents of io_rEdgeList).
io_rEdgeList
.
splice
(
aCurr
,
aNewEdges
);
}
inline
bool
isSameRect
(
ActiveEdge
&
rEdge
,
const
basegfx
::
B2DRange
&
rRect
)
{
return
&
rEdge
.
getRect
()
==
&
rRect
;
}
// wow what a hack. necessary because stl's list::erase does
// not eat reverse_iterator
template
<
typename
Cont
,
typename
Iter
>
Iter
eraseFromList
(
Cont
&
,
Iter
);
template
<>
inline
ListOfEdges
::
iterator
eraseFromList
(
ListOfEdges
&
rList
,
ListOfEdges
::
iterator
aIter
)
{
return
rList
.
erase
(
aIter
);
}
template
<>
inline
ListOfEdges
::
reverse_iterator
eraseFromList
(
ListOfEdges
&
rList
,
ListOfEdges
::
reverse_iterator
aIter
)
{
return
ListOfEdges
::
reverse_iterator
(
rList
.
erase
(
boost
::
prior
(
aIter
.
base
())));
}
template
<
int
bPerformErase
,
typename
Iterator
>
inline
void
processActiveEdges
(
Iterator
first
,
Iterator
last
,
ListOfEdges
&
rActiveEdgeList
,
SweepLineEvent
&
rCurrEvent
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
const
basegfx
::
B2DRange
&
rCurrRect
=
rCurrEvent
.
getRect
();
// fast-forward to rCurrEvent's first active edge (holds
// for both starting and finishing sweep line events, a
// rect is regarded _outside_ any rects whose events have
// started earlier
first
=
std
::
find_if
(
first
,
last
,
boost
::
bind
(
&
isSameRect
,
_1
,
boost
::
cref
(
rCurrRect
)));
if
(
first
==
last
)
return
;
int
nCount
=
0
;
std
::
ptrdiff_t
nCurrPolyIdx
=-
1
;
while
(
first
!=
last
)
{
if
(
nCurrPolyIdx
==
-
1
)
nCurrPolyIdx
=
first
->
getTargetPolygonIndex
();
OSL_ASSERT
(
nCurrPolyIdx
!=
-
1
);
// second encounter of my rect -> second edge
// encountered, done
const
bool
bExit
=
nCount
&&
isSameRect
(
*
first
,
rCurrRect
);
// deal with current active edge
nCurrPolyIdx
=
rPolygonPool
.
get
(
nCurrPolyIdx
).
intersect
(
rCurrEvent
,
*
first
,
rPolygonPool
,
rRes
,
bExit
);
// prune upper & lower active edges, if requested
if
(
bPerformErase
&&
(
bExit
||
!
nCount
)
)
first
=
eraseFromList
(
rActiveEdgeList
,
first
);
else
++
first
;
// delayed exit, had to prune first
if
(
bExit
)
return
;
++
nCount
;
}
}
template
<
int
bPerformErase
>
inline
void
processActiveEdgesTopDown
(
SweepLineEvent
&
rCurrEvent
,
ListOfEdges
&
rActiveEdgeList
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
processActiveEdges
<
bPerformErase
>
(
rActiveEdgeList
.
begin
(),
rActiveEdgeList
.
end
(),
rActiveEdgeList
,
rCurrEvent
,
rPolygonPool
,
rRes
);
}
template
<
int
bPerformErase
>
inline
void
processActiveEdgesBottomUp
(
SweepLineEvent
&
rCurrEvent
,
ListOfEdges
&
rActiveEdgeList
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
processActiveEdges
<
bPerformErase
>
(
rActiveEdgeList
.
rbegin
(),
rActiveEdgeList
.
rend
(),
rActiveEdgeList
,
rCurrEvent
,
rPolygonPool
,
rRes
);
}
enum
{
NoErase
=
0
,
PerformErase
=
1
};
void
handleStartingEdge
(
SweepLineEvent
&
rCurrEvent
,
ListOfEdges
&
rActiveEdgeList
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
// inject two new active edges for rect
createActiveEdgesFromStartEvent
(
rActiveEdgeList
,
rPolygonPool
,
rCurrEvent
);
if
(
SweepLineEvent
::
PROCEED_DOWN
==
rCurrEvent
.
getEdgeDirection
()
)
processActiveEdgesTopDown
<
NoErase
>
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
else
processActiveEdgesBottomUp
<
NoErase
>
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
}
void
handleFinishingEdge
(
SweepLineEvent
&
rCurrEvent
,
ListOfEdges
&
rActiveEdgeList
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
if
(
SweepLineEvent
::
PROCEED_DOWN
==
rCurrEvent
.
getEdgeDirection
()
)
processActiveEdgesTopDown
<
PerformErase
>
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
else
processActiveEdgesBottomUp
<
PerformErase
>
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
}
inline
void
handleSweepLineEvent
(
SweepLineEvent
&
rCurrEvent
,
ListOfEdges
&
rActiveEdgeList
,
VectorOfPolygons
&
rPolygonPool
,
B2DPolyPolygon
&
rRes
)
{
if
(
SweepLineEvent
::
STARTING_EDGE
==
rCurrEvent
.
getEdgeType
()
)
handleStartingEdge
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
else
handleFinishingEdge
(
rCurrEvent
,
rActiveEdgeList
,
rPolygonPool
,
rRes
);
}
}
namespace
tools
{
B2DPolyPolygon
solveCrossovers
(
const
std
::
vector
<
B2DRange
>&
rRanges
,
const
std
::
vector
<
B2VectorOrientation
>&
rOrientations
)
{
// sweep-line algorithm to generate a poly-polygon
// from a bunch of rectangles
// ===============================================
//
// This algorithm uses the well-known sweep line
// concept, explained in every good text book about
// computational geometry.
//
// We start with creating two structures for every
// rectangle, one representing the left x coordinate,
// one representing the right x coordinate (and both
// referencing the original rect). These structs are
// sorted with increasing x coordinates.
//
// Then, we start processing the resulting list from
// the beginning. Every entry in the list defines a
// point in time of the line sweeping from left to
// right across all rectangles.
VectorOfEvents
aSweepLineEvents
;
setupSweepLineEventListFromRanges
(
aSweepLineEvents
,
rRanges
,
rOrientations
);
B2DPolyPolygon
aRes
;
VectorOfPolygons
aPolygonPool
;
ListOfEdges
aActiveEdgeList
;
// sometimes not enough, but a usable compromise
aPolygonPool
.
reserve
(
rRanges
.
size
()
);
std
::
for_each
(
aSweepLineEvents
.
begin
(),
aSweepLineEvents
.
end
(),
boost
::
bind
(
&
handleSweepLineEvent
,
_1
,
boost
::
ref
(
aActiveEdgeList
),
boost
::
ref
(
aPolygonPool
),
boost
::
ref
(
aRes
))
);
return
aRes
;
}
}
}
basegfx/source/range/makefile.mk
Dosyayı görüntüle @
8454c5ef
...
@@ -47,7 +47,8 @@ SLOFILES= \
...
@@ -47,7 +47,8 @@ SLOFILES= \
$(SLO)$/
b1drange.obj
\
$(SLO)$/
b1drange.obj
\
$(SLO)$/
b2drange.obj
\
$(SLO)$/
b2drange.obj
\
$(SLO)$/
b2xrange.obj
\
$(SLO)$/
b2xrange.obj
\
$(SLO)$/
b2dmultirange.obj
\
$(SLO)$/
b2dpolyrange.obj
\
$(SLO)$/
b2drangeclipper.obj
\
$(SLO)$/
b3drange.obj
$(SLO)$/
b3drange.obj
# --- Targets ----------------------------------
# --- Targets ----------------------------------
...
...
basegfx/test/basegfx2d.cxx
Dosyayı görüntüle @
8454c5ef
...
@@ -41,7 +41,9 @@
...
@@ -41,7 +41,9 @@
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/curve/b2dbeziertools.hxx>
#include <basegfx/curve/b2dbeziertools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/range/b2dmultirange.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/color/bcolor.hxx>
#include <basegfx/color/bcolor.hxx>
#include <basegfx/color/bcolortools.hxx>
#include <basegfx/color/bcolortools.hxx>
...
@@ -56,214 +58,6 @@ using namespace ::basegfx;
...
@@ -56,214 +58,6 @@ using namespace ::basegfx;
namespace
basegfx2d
namespace
basegfx2d
{
{
/// Gets a random ordinal [0,n)
inline
double
getRandomOrdinal
(
const
::
std
::
size_t
n
)
{
return
double
(
n
)
*
rand
()
/
(
RAND_MAX
+
1.0
);
}
class
b2dmultirange
:
public
CppUnit
::
TestFixture
{
private
:
B2DMultiRange
aDisjunctRanges
;
B2DMultiRange
aEqualRanges
;
B2DMultiRange
aIntersectionN
;
B2DMultiRange
aIntersectionE
;
B2DMultiRange
aIntersectionS
;
B2DMultiRange
aIntersectionW
;
B2DMultiRange
aIntersectionNE
;
B2DMultiRange
aIntersectionSE
;
B2DMultiRange
aIntersectionSW
;
B2DMultiRange
aIntersectionNW
;
B2DMultiRange
aRingIntersection
;
B2DMultiRange
aComplexIntersections
;
B2DMultiRange
aRandomIntersections
;
public
:
// initialise your test code values here.
void
setUp
()
{
B2DRange
aCenter
(
1.0
,
1.0
,
-
1.0
,
-
1.0
);
B2DRange
aOffside
(
9.0
,
9.0
,
11.0
,
11.0
);
B2DRange
aNorth
(
1.0
,
0.0
,
-
1.0
,
-
2.0
);
B2DRange
aSouth
(
1.0
,
2.0
,
-
1.0
,
0.0
);
B2DRange
aEast
(
0.0
,
1.0
,
2.0
,
-
1.0
);
B2DRange
aWest
(
-
2.0
,
1.0
,
0.0
,
-
1.0
);
B2DRange
aNorthEast
(
0.0
,
0.0
,
2.0
,
-
2.0
);
B2DRange
aSouthEast
(
0.0
,
0.0
,
2.0
,
2.0
);
B2DRange
aSouthWest
(
0.0
,
0.0
,
-
2.0
,
2.0
);
B2DRange
aNorthWest
(
0.0
,
0.0
,
-
2.0
,
-
2.0
);
B2DRange
aNorth2
(
-
1.5
,
0.5
,
1.5
,
3.5
);
B2DRange
aSouth2
(
-
1.5
,
-
0.5
,
1.5
,
-
3.5
);
B2DRange
aEast2
(
0.5
,
-
1.5
,
3.5
,
1.5
);
B2DRange
aWest2
(
-
0.5
,
-
1.5
,
-
3.5
,
1.5
);
::
std
::
ofstream
output
(
"multirange_testcases.gnuplot"
);
DebugPlotter
aPlotter
(
"multirange testcases"
,
output
);
aPlotter
.
plot
(
aCenter
,
"center"
);
aPlotter
.
plot
(
aOffside
,
"offside"
);
aPlotter
.
plot
(
aNorth
,
"north"
);
aPlotter
.
plot
(
aSouth
,
"south"
);
aPlotter
.
plot
(
aEast
,
"east"
);
aPlotter
.
plot
(
aWest
,
"west"
);
aPlotter
.
plot
(
aNorthEast
,
"northeast"
);
aPlotter
.
plot
(
aSouthEast
,
"southeast"
);
aPlotter
.
plot
(
aSouthWest
,
"southwest"
);
aPlotter
.
plot
(
aNorthWest
,
"northwest"
);
aDisjunctRanges
.
addRange
(
aCenter
);
aDisjunctRanges
.
addRange
(
aOffside
);
aEqualRanges
.
addRange
(
aCenter
);
aEqualRanges
.
addRange
(
aCenter
);
aIntersectionN
.
addRange
(
aCenter
);
aIntersectionN
.
addRange
(
aNorth
);
aIntersectionE
.
addRange
(
aCenter
);
aIntersectionE
.
addRange
(
aEast
);
aIntersectionS
.
addRange
(
aCenter
);
aIntersectionS
.
addRange
(
aSouth
);
aIntersectionW
.
addRange
(
aCenter
);
aIntersectionW
.
addRange
(
aWest
);
aIntersectionNE
.
addRange
(
aCenter
);
aIntersectionNE
.
addRange
(
aNorthEast
);
aIntersectionSE
.
addRange
(
aCenter
);
aIntersectionSE
.
addRange
(
aSouthEast
);
aIntersectionSW
.
addRange
(
aCenter
);
aIntersectionSW
.
addRange
(
aSouthWest
);
aIntersectionNW
.
addRange
(
aCenter
);
aIntersectionNW
.
addRange
(
aNorthWest
);
aRingIntersection
.
addRange
(
aNorth2
);
aRingIntersection
.
addRange
(
aEast2
);
aRingIntersection
.
addRange
(
aSouth2
);
aRingIntersection
.
addRange
(
aWest2
);
aComplexIntersections
.
addRange
(
aCenter
);
aComplexIntersections
.
addRange
(
aOffside
);
aComplexIntersections
.
addRange
(
aCenter
);
aComplexIntersections
.
addRange
(
aNorth
);
aComplexIntersections
.
addRange
(
aEast
);
aComplexIntersections
.
addRange
(
aSouth
);
aComplexIntersections
.
addRange
(
aWest
);
aComplexIntersections
.
addRange
(
aNorthEast
);
aComplexIntersections
.
addRange
(
aSouthEast
);
aComplexIntersections
.
addRange
(
aSouthWest
);
aComplexIntersections
.
addRange
(
aNorthWest
);
/*
for( int i=0; i<10; ++i )
{
B2DRange aRandomRange(
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ),
getRandomOrdinal( 10 ) );
aRandomIntersections.addRange( aRandomRange );
}
*/
}
void
tearDown
()
{
}
::
basegfx
::
B2DPolyPolygon
shiftPoly
(
int
nCount
,
const
::
basegfx
::
B2DPolyPolygon
&
rPoly
)
{
B2DHomMatrix
aMatrix
;
aMatrix
.
translate
(
nCount
*
4.0
,
10.0
-
nCount
*
2.0
);
::
basegfx
::
B2DPolyPolygon
aRes
(
rPoly
);
aRes
.
transform
(
aMatrix
);
return
aRes
;
}
void
getPolyPolygon
()
{
::
std
::
ofstream
output
(
"multirange_getpolypolygon.gnuplot"
);
DebugPlotter
aPlotter
(
"multirange getPolyPolygon"
,
output
);
B2DPolyPolygon
result
;
aPlotter
.
plot
(
shiftPoly
(
0
,
aDisjunctRanges
.
getPolyPolygon
()
),
"disjunct"
);
aPlotter
.
plot
(
shiftPoly
(
1
,
aEqualRanges
.
getPolyPolygon
()
),
"equal"
);
aPlotter
.
plot
(
shiftPoly
(
2
,
aIntersectionN
.
getPolyPolygon
()
),
"intersectionN"
);
aPlotter
.
plot
(
shiftPoly
(
3
,
aIntersectionE
.
getPolyPolygon
()
),
"intersectionE"
);
aPlotter
.
plot
(
shiftPoly
(
4
,
aIntersectionS
.
getPolyPolygon
()
),
"intersectionS"
);
aPlotter
.
plot
(
shiftPoly
(
5
,
aIntersectionW
.
getPolyPolygon
()
),
"intersectionW"
);
aPlotter
.
plot
(
shiftPoly
(
6
,
aIntersectionNE
.
getPolyPolygon
()
),
"intersectionNE"
);
aPlotter
.
plot
(
shiftPoly
(
7
,
aIntersectionSE
.
getPolyPolygon
()
),
"intersectionSE"
);
aPlotter
.
plot
(
shiftPoly
(
8
,
aIntersectionSW
.
getPolyPolygon
()
),
"intersectionSW"
);
aPlotter
.
plot
(
shiftPoly
(
9
,
aIntersectionNW
.
getPolyPolygon
()
),
"intersectionNW"
);
aPlotter
.
plot
(
shiftPoly
(
10
,
aRingIntersection
.
getPolyPolygon
()
),
"intersection ring"
);
aPlotter
.
plot
(
shiftPoly
(
11
,
aComplexIntersections
.
getPolyPolygon
()
),
"intersection complex"
);
aPlotter
.
plot
(
shiftPoly
(
12
,
aRandomIntersections
.
getPolyPolygon
()
),
"intersection random"
);
CPPUNIT_ASSERT_MESSAGE
(
"getPolyPolygon"
,
true
);
}
// Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE
(
b2dmultirange
);
CPPUNIT_TEST
(
getPolyPolygon
);
CPPUNIT_TEST_SUITE_END
();
};
// class b2dmultirange
class
b2dsvgdimpex
:
public
CppUnit
::
TestFixture
class
b2dsvgdimpex
:
public
CppUnit
::
TestFixture
{
{
...
@@ -505,6 +299,39 @@ public:
...
@@ -505,6 +299,39 @@ public:
CPPUNIT_TEST_SUITE_END
();
CPPUNIT_TEST_SUITE_END
();
};
// class b2dsvgdimpex
};
// class b2dsvgdimpex
class
b2dpolyrange
:
public
CppUnit
::
TestFixture
{
private
:
public
:
void
setUp
()
{}
void
tearDown
()
{}
void
check
()
{
B2DPolyRange
aRange
;
aRange
.
appendElement
(
B2DRange
(
0
,
0
,
1
,
1
),
ORIENTATION_POSITIVE
);
aRange
.
appendElement
(
B2DRange
(
2
,
2
,
3
,
3
),
ORIENTATION_POSITIVE
);
CPPUNIT_ASSERT_MESSAGE
(
"simple poly range - count"
,
aRange
.
count
()
==
2
);
CPPUNIT_ASSERT_MESSAGE
(
"simple poly range - first element"
,
aRange
.
getElement
(
0
).
head
==
B2DRange
(
0
,
0
,
1
,
1
));
CPPUNIT_ASSERT_MESSAGE
(
"simple poly range - second element"
,
aRange
.
getElement
(
1
).
head
==
B2DRange
(
2
,
2
,
3
,
3
));
}
// Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE
(
b2dpolyrange
);
CPPUNIT_TEST
(
check
);
CPPUNIT_TEST_SUITE_END
();
};
class
b2dbeziertools
:
public
CppUnit
::
TestFixture
class
b2dbeziertools
:
public
CppUnit
::
TestFixture
{
{
private
:
private
:
...
@@ -1618,8 +1445,9 @@ public:
...
@@ -1618,8 +1445,9 @@ public:
};
// class b2dvector
};
// class b2dvector
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dmultirange, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dsvgdimpex
,
"basegfx2d"
);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dsvgdimpex
,
"basegfx2d"
);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dpolyrange
,
"basegfx2d"
);
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dbeziertools, "basegfx2d");
//CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(basegfx2d::b2dbeziertools, "basegfx2d");
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dcubicbezier
,
"basegfx2d"
);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dcubicbezier
,
"basegfx2d"
);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dhommatrix
,
"basegfx2d"
);
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
b2dhommatrix
,
"basegfx2d"
);
...
...
basegfx/test/boxclipper.cxx
0 → 100644
Dosyayı görüntüle @
8454c5ef
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: basegfx2d.cxx,v $
* $Revision: 1.14 $
*
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenOffice.org is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenOffice.org. If not, see
* <http://www.openoffice.org/license.html>
* for a copy of the LGPLv3 License.
*
************************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basegfx.hxx"
// autogenerated file with codegen.pl
#include <cppunit/simpleheader.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/curve/b2dcubicbezier.hxx>
#include <basegfx/curve/b2dbeziertools.hxx>
#include <basegfx/range/b2dpolyrange.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <boost/bind.hpp>
using
namespace
::
basegfx
;
namespace
basegfx2d
{
/// Gets a random ordinal [0,n)
inline
double
getRandomOrdinal
(
const
::
std
::
size_t
n
)
{
// use this one when displaying polygons in OOo, which still sucks
// great rocks when trying to import non-integer svg:d attributes
// return sal_Int64(double(n) * rand() / (RAND_MAX + 1.0));
return
double
(
n
)
*
rand
()
/
(
RAND_MAX
+
1.0
);
}
inline
bool
compare
(
const
B2DPoint
&
left
,
const
B2DPoint
&
right
)
{
return
left
.
getX
()
<
right
.
getX
()
||
(
left
.
getX
()
==
right
.
getX
()
&&
left
.
getY
()
<
right
.
getY
());
}
class
boxclipper
:
public
CppUnit
::
TestFixture
{
private
:
B2DPolyRange
aDisjunctRanges
;
B2DPolyRange
aEqualRanges
;
B2DPolyRange
aIntersectionN
;
B2DPolyRange
aIntersectionE
;
B2DPolyRange
aIntersectionS
;
B2DPolyRange
aIntersectionW
;
B2DPolyRange
aIntersectionNE
;
B2DPolyRange
aIntersectionSE
;
B2DPolyRange
aIntersectionSW
;
B2DPolyRange
aIntersectionNW
;
B2DPolyRange
aRingIntersection
;
B2DPolyRange
aRingIntersection2
;
B2DPolyRange
aRingIntersectExtraStrip
;
B2DPolyRange
aComplexIntersections
;
B2DPolyRange
aRandomIntersections
;
public
:
// initialise your test code values here.
void
setUp
()
{
B2DRange
aCenter
(
100
,
100
,
-
100
,
-
100
);
B2DRange
aOffside
(
800
,
800
,
1000
,
1000
);
B2DRange
aNorth
(
100
,
0
,
-
100
,
-
200
);
B2DRange
aSouth
(
100
,
200
,
-
100
,
0
);
B2DRange
aEast
(
0
,
100
,
200
,
-
100
);
B2DRange
aWest
(
-
200
,
100
,
0
,
-
100
);
B2DRange
aNorthEast
(
0
,
0
,
200
,
-
200
);
B2DRange
aSouthEast
(
0
,
0
,
200
,
200
);
B2DRange
aSouthWest
(
0
,
0
,
-
200
,
200
);
B2DRange
aNorthWest
(
0
,
0
,
-
200
,
-
200
);
B2DRange
aNorth2
(
-
150
,
50
,
150
,
350
);
B2DRange
aSouth2
(
-
150
,
-
50
,
150
,
-
350
);
B2DRange
aEast2
(
50
,
-
150
,
350
,
150
);
B2DRange
aWest2
(
-
50
,
-
150
,
-
350
,
150
);
aDisjunctRanges
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aDisjunctRanges
.
appendElement
(
aOffside
,
ORIENTATION_NEGATIVE
);
aEqualRanges
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aEqualRanges
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionN
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionN
.
appendElement
(
aNorth
,
ORIENTATION_NEGATIVE
);
aIntersectionE
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionE
.
appendElement
(
aEast
,
ORIENTATION_NEGATIVE
);
aIntersectionS
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionS
.
appendElement
(
aSouth
,
ORIENTATION_NEGATIVE
);
aIntersectionW
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionW
.
appendElement
(
aWest
,
ORIENTATION_NEGATIVE
);
aIntersectionNE
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionNE
.
appendElement
(
aNorthEast
,
ORIENTATION_NEGATIVE
);
aIntersectionSE
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionSE
.
appendElement
(
aSouthEast
,
ORIENTATION_NEGATIVE
);
aIntersectionSW
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionSW
.
appendElement
(
aSouthWest
,
ORIENTATION_NEGATIVE
);
aIntersectionNW
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aIntersectionNW
.
appendElement
(
aNorthWest
,
ORIENTATION_NEGATIVE
);
aRingIntersection
.
appendElement
(
aNorth2
,
ORIENTATION_NEGATIVE
);
aRingIntersection
.
appendElement
(
aEast2
,
ORIENTATION_NEGATIVE
);
aRingIntersection
.
appendElement
(
aSouth2
,
ORIENTATION_NEGATIVE
);
aRingIntersection2
=
aRingIntersection
;
aRingIntersection2
.
appendElement
(
aWest2
,
ORIENTATION_NEGATIVE
);
aRingIntersectExtraStrip
=
aRingIntersection2
;
aRingIntersectExtraStrip
.
appendElement
(
B2DRange
(
0
,
-
25
,
200
,
25
),
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aOffside
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aCenter
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aNorth
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aEast
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aSouth
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aWest
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aNorthEast
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aSouthEast
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aSouthWest
,
ORIENTATION_NEGATIVE
);
aComplexIntersections
.
appendElement
(
aNorthWest
,
ORIENTATION_NEGATIVE
);
#ifdef GENERATE_RANDOM
for
(
int
i
=
0
;
i
<
800
;
++
i
)
{
B2DRange
aRandomRange
(
getRandomOrdinal
(
1000
),
getRandomOrdinal
(
1000
),
getRandomOrdinal
(
1000
),
getRandomOrdinal
(
1000
)
);
aRandomIntersections
.
appendElement
(
aRandomRange
,
ORIENTATION_NEGATIVE
);
}
#else
const
char
*
randomSvg
=
"m394 783h404v57h-404zm-197-505h571v576h-571zm356-634h75v200h-75zm-40-113h403v588h-403zm93-811h111v494h-111zm-364-619h562v121h-562zm-134-8h292v27h-292zm110 356h621v486h-621zm78-386h228v25h-228zm475-345h201v201h-201zm-2-93h122v126h-122zm-417-243h567v524h-567zm-266-738h863v456h-863zm262-333h315v698h-315zm-328-826h43v393h-43zm830-219h120v664h-120zm-311-636h221v109h-221zm-500 137h628v19h-628zm681-94h211v493h-211zm-366-646h384v355h-384zm-189-199h715v247h-715zm165-459h563v601h-563zm258-479h98v606h-98zm270-517h65v218h-65zm-44-259h96v286h-96zm-599-202h705v468h-705zm216-803h450v494h-450zm-150-22h26v167h-26zm-55-599h50v260h-50zm190-278h490v387h-490zm-290-453h634v392h-634zm257 189h552v300h-552zm-151-690h136v455h-136zm12-597h488v432h-488zm501-459h48v39h-48zm-224-112h429v22h-429zm-281 102h492v621h-492zm519-158h208v17h-208zm-681-563h56v427h-56zm126-451h615v392h-615zm-47-410h598v522h-598zm-32 316h79v110h-79zm-71-129h18v127h-18zm126-993h743v589h-743zm211-430h428v750h-428zm61-554h100v220h-100zm-353-49h658v157h-658zm778-383h115v272h-115zm-249-541h119v712h-119zm203 86h94v40h-94z"
;
B2DPolyPolygon
randomPoly
;
tools
::
importFromSvgD
(
randomPoly
,
rtl
::
OUString
::
createFromAscii
(
randomSvg
));
std
::
for_each
(
randomPoly
.
begin
(),
randomPoly
.
end
(),
boost
::
bind
(
&
B2DPolyRange
::
appendElement
,
boost
::
ref
(
aRandomIntersections
),
boost
::
bind
(
&
B2DPolygon
::
getB2DRange
,
_1
),
ORIENTATION_NEGATIVE
,
1
));
#endif
}
void
tearDown
()
{
}
B2DPolyPolygon
normalizePoly
(
const
B2DPolyPolygon
&
rPoly
)
{
B2DPolyPolygon
aRes
;
for
(
sal_uInt32
i
=
0
;
i
<
rPoly
.
count
();
++
i
)
{
B2DPolygon
aTmp
=
rPoly
.
getB2DPolygon
(
i
);
if
(
ORIENTATION_NEGATIVE
==
tools
::
getOrientation
(
aTmp
)
)
aTmp
.
flip
();
aTmp
=
tools
::
removeNeutralPoints
(
aTmp
);
B2DPoint
*
pSmallest
=
0
;
for
(
B2DPoint
*
pCurr
=
aTmp
.
begin
();
pCurr
!=
aTmp
.
end
();
++
pCurr
)
{
if
(
!
pSmallest
||
compare
(
*
pCurr
,
*
pSmallest
)
)
{
pSmallest
=
pCurr
;
}
}
if
(
pSmallest
)
std
::
rotate
(
aTmp
.
begin
(),
pSmallest
,
aTmp
.
end
());
aRes
.
append
(
aTmp
);
}
// boxclipper & generic clipper disagree slightly on area-less
// polygons (one or two points only)
aRes
=
tools
::
stripNeutralPolygons
(
aRes
);
// now, sort all polygons with increasing 0th point
std
::
sort
(
aRes
.
begin
(),
aRes
.
end
(),
boost
::
bind
(
&
compare
,
boost
::
bind
(
&
B2DPolygon
::
getB2DPoint
,
_1
,
0
),
boost
::
bind
(
&
B2DPolygon
::
getB2DPoint
,
_2
,
0
)));
return
aRes
;
}
void
verifyPoly
(
const
char
*
sName
,
const
char
*
sSvg
,
const
B2DPolyRange
&
toTest
)
{
B2DPolyPolygon
aTmp1
;
CPPUNIT_ASSERT_MESSAGE
(
sName
,
tools
::
importFromSvgD
(
aTmp1
,
rtl
::
OUString
::
createFromAscii
(
sSvg
)));
const
rtl
::
OUString
aSvg
=
tools
::
exportToSvgD
(
toTest
.
solveCrossovers
());
B2DPolyPolygon
aTmp2
;
CPPUNIT_ASSERT_MESSAGE
(
sName
,
tools
::
importFromSvgD
(
aTmp2
,
aSvg
));
CPPUNIT_ASSERT_MESSAGE
(
sName
,
normalizePoly
(
aTmp2
)
==
normalizePoly
(
aTmp1
));
}
void
verifyPoly
()
{
const
char
*
disjunct
=
"m100 100v-200h-200v200zm1100 900v-200h-200v200z"
;
const
char
*
equal
=
"m100 100v-200h-200v200zm200 0v-200h-200v200h200z"
;
const
char
*
intersectionN
=
"m100 0v-100h-200v100zm200 100v-200-100h-200v100 200z"
;
const
char
*
intersectionE
=
"m100 100v-200h-100v200zm200 0v-200h-200-100v200h100z"
;
const
char
*
intersectionS
=
"m100 100v-200h-200v200 100h200v-100zm0 0v-100h-200v100z"
;
const
char
*
intersectionW
=
"m0 100v-200h-100v200zm200 0v-200h-200-100v200h100z"
;
const
char
*
intersectionNE
=
"m100 0v-100h-100v100zm200 0v-200h-200v100h-100v200h200v-100z"
;
const
char
*
intersectionSE
=
"m200 200v-200h-100v-100h-200v200h100v100zm100-100v-100h-100v100z"
;
const
char
*
intersectionSW
=
"m0 100v-100h-100v100zm200 0v-200h-200v100h-100v200h200v-100z"
;
const
char
*
intersectionNW
=
"m100 100v-200h-100v-100h-200v200h100v100zm100-100v-100h-100v100z"
;
const
char
*
ringIntersection
=
"m150 150v-100h-100v100zm300 0v-300h-200v-200h-300v300h200v100h-200v300h300v-200zm0-200v-100h-100v100z"
;
const
char
*
ringIntersection2
=
"m-50-50v-100h-100v100zm100 200v-100h-100v100zm500 0v-300h-200v-200h-300v200h-200v300h200v200h300v-200zm-200-100v-100h100v100zm100-100v-100h-100v100zm100 200v-100h-100v100z"
;
const
char
*
ringIntersectExtraStrip
=
"m-50-50v-100h-100v100zm100 200v-100h-100v100zm500 0v-300h-200v-200h-300v200h-200v300h200v200h300v-200zm-200-100v-100h100v25h-50v50h50v25zm150-25v-50h-150v50zm100-75v-100h-100v100zm100 200v-100h-100v100z"
;
// TODO: old clipper impl. debug difference
//const char* complexIntersections="m100 0h-100v-100 100h-100 100v100-100zm0 0zm200 0h-100v-100h-100v-100 100h-100v100h-100 100v100h100v100-100h100v-100zm0 0h-100v-100 100h-100 100v100-100h100zm0 0v-100h-100-100v100 100h100 100v-100zm100 0v-100h-100v-100h-100-100v100h-100v100 100h100v100h100 100v-100h100v-100zm-200 0zm100 0v-100h-100-100v100 100h100 100v-100zm100 100v-200-100h-200-100-100v100 200 100h100 100 200v-100zm-200-100zm1000 1000v-200h-200v200z";
const
char
*
complexIntersections
=
"m0 0zm0 0zm0 0zm0 0v-100 100h-100 100v100-100h100zm-100 0v-100 100h-100 100v100-100h100zm0 0v-100h-100-100v100 100h100 100v-100zm0 0v-100h-100-100v100 100h100 100v-100zm0 0v-100h-100v-100 100h-100v100h-100 100v100h100v100-100h100v-100h100zm-100-100v-100h-100-100v100h-100v100 100h100v100h100 100v-100h100v-100-100zm0 0v-100h-200-100-100v100 200 100h100 100 200v-100-200zm600 900v200h200v-200z"
;
const
char
*
randomIntersections
=
"m63 457v-393h-43v393zm114 63v-8h-48v8zm-14 477v-127h-18v127zm693-923v-5h-119v5zm-260 457v-1h-14v1zm-220-375v-27h-8v27zm78 755v-22h-7v22zm203-774v-8h-158v8zm-108 375v-17h23v17zm813-19v-189h-21v-12h-26v-54h-17v-69h-25v-22h-62v-73h104v-5h-104-15v-17h-49v-1h-8v-16h-119v16h-386v18h-38-24v34h-23v26h-23v-26h-8v26h-18v27h18v339h8v-339h23v339h8v17h-8v13h8v5h-8v1h8v42h15v20h17v94h18 3v224h165v39h130v2h75v4h98v-4h153v-2h77v-20h4v-28h11v-218h-11v-27h3v-1h8v-17h-8v-63h8v-51h18v-32zm-581 32v-13h-14v13zm-78-78v-7h-32v7zm124 14v-21h-14v21zm595 32v-189h-26v-12h-4v-9h-13v-45h-13v-10h-12v-59h-62v-22h-26v-10h11v-63h15v-5h-15-49v-17h-8v-1h-119v1h-107v17h-279-38v34h-24v26h-23v27h23v284h-15v55h15v17h-15v13h15v5h-15v1h15v42h17v20h18v94h3 14v62h8v48h90v32h18v61h35v21h8v2h122v37h75v2h98v-2h153v-20h77v-28h4v-29h5v-40h-5v-149h-1v-27h1v-1h3v-17h-3v-46h3v-17-51h8v-32zm-563 2v-13h-14v13zm198 30v-13h-39v13zm204-43v-21h3v21zm-168-21v-21h-39v21zm306 0v-21h-5v21zm178 115v-272h-20v-12h-2v-54h-21v-164h1v-22h-27v-48h-743v47h-23v18h-71v24h-8v419h-39v19h60v156h66 32v202h-72v110h79v-88h11v39h3v48h621v-14h96v-82h35v-326zm-570-420v-4h-156v4zm63 481v-18h-11v18zm72 0v-25h-14v25zm465-112v-13h-5v13zm-46-43v-21h1v21zm-37-21v-21h-12v21zm-352 21v-21h23v21zm-23 30v-17h23v17zm-23 18v-5h23v5zm-23 82v-19h23v19zm272 75v-3h-35v3zm-76-192v-13h-39v13zm150 30v-13h-35v13zm-76 6v-1h-39v1zm11 106v-25h-11v25zm150 160v-14h-75v14zm318-304v-11h-13v-43h-2v-2h-10v-37h-4v37h-27v3h-31v-3-37h-5v37h-43v3h-2v21h2v21h-2v30h-1v-30h-8v-21h8v-21h-8v-3h-5v-62h5v-11h-5v-29h-8v-52h-15v-17-38h-15v-52h-89v16h-22v36h-175v55h-15v1h-25v51h-23v-41h-14v41h-2v105h-4v21h4v21h-4v13h4v17h-4-18v13h18v5h-18v1h18v42h4v11h2v9h14v-9h23v9h40v19h-40v25h40v2h82v2h75v43h-75v3h75 40v60h35v-60h23 34 12 15v-3h-15v-43h15v-48h10v-37h11v-31h1v1h45v30h5v-30h20v-1h11v1h8v30h19v20h3v-20h1v-30h10v-1h2v-32zm-146-329v-1h-2v1zm-117 211v-11 11zm-76 0v-11h-13v11zm13 65v-65h1v65zm-1 42v-21h1v16h35v5zm-36 30v-17h36v17zm-36 18v-5h36v5zm180-5v-13h-13v-17h5v-13h-5v-21h5v-21h-5v-3h-8v-62h8v-11h-8v-29h-9v-51h-6v-1-17h-15v-38h-54v-36h-35v36h-22v38h-67v17h-108v1h-15v51h-25v105h-23v-105h-14v105h-2v21h2v21h-2v13h2v17h-2-4v13h4v5h-4v1h4v42h2v11h14v-11h23v11h40v9h82v19h-82v25h82v2h75v2h40v43h-40v3h40 35 23v-3h-23v-43h23v-2h34v2h12v-2h6v-46h9v-20h8v-17h2v-26h-2v-5zm-127-64v-21 21zm89 51v-17h3v17zm-57-17v-13h-35v13zm58 61v-26h-19v-5h19v-13h-23v-17h23v-13h-23v-21h23v-21h-23v-65h23v-11h-23v-14h-35v-15 15h-22v14h-18v11h18v65h-18v21h18v16h22v5h-22v13h22v17h-22-18v13h18v5h-18v1h18v25h22v17h35v-17zm0-25v-1h-35v1zm-22-390v6h-175v5h-31v-15h228v4zm344 352v-189h-2v-12h-21v-54h-26v-164h26v-5h-26v-17h-119v-36h-562v35h-62v18h-23v34h-23v-10h-48v419h-8v8h8v5h71v5h-58v1h58v42h8v114h32 18v224h3v39h165v34h456v-32h77v-2h4v-20h11v-28h4v-218h-4v-28h36v-17h-36v-63h39v-83zm-50 0v-11h-1v-43h-3v-2h-6v-39h-4v-34h-13v-60h-12v-12h-31v72h-31v-72-9h-59v-17-38h-5v-59h-8v-5h8v-1h-8v-16h-2v16h-13v-11h-15v-5h-89v5h-22v11h-175v6h-15v7h-25v16h-43v36h-18v66h-54v-107h-32v107h-4v41h-8v105h-6v7h6v14h8v21h-8v13h8v17h-8-14v13h14v5h-14v1h14v42h8v20h90v19h-34v7h-15v68h26v-50h23v50h18 4v62h16v-62h15v110h8v10h3v22h119v11h75v50h75v-50h23v-11h34v11h48v-11h30v-22h21v-120h20v-3h11v3h30v-3h13-13v-27h13v-1h17v-17h-17v-46h17v-17h6v-51h3v-32zm-256-32v-21h-35v-65h35v-11h-35v-14 14h-22v11h22v65h-22v21h22v16-16zm89 69v-5h3v5zm-3 26v-26h-31v-5h31v-13h-31v-17h31v-13h-31v-21h31v-21h-31v-65h31v-11h-31v-14h-23v-15h-35v-51 51h-22v15h-18v14h-35v11h35v65h-35v21h35v16h18v5h-18v13h18v17h-18-36-39-61v13h61v5h-61v1h61v25h39v-25h36v25h18v17h22v11h35v-11h23v-17zm-19-25v-1h-4v-5h4v-13h-4-35-22v13h22v5h-22v1h22v25h35v-25zm23 252v-36h34v36zm-34-99v-43h34v43zm35-128v-26h-8v-5h8v-13h-8v-17h8v-13h-8v-21h8v-21h-8v-3h-9v-62h9v-11h-9v-29h-6v-51-1h-15v-17h-54v-38h-35v38h-22v11h-53v6h-14v1h-108v51h-15v105h-25v21h25v21h-25v13h25v17h-25-23-14-2v13h2v5h-2v1h2v42h14v-42h23v42h40v11h82v9h75v46h40v2h35v-2h23v-4h31v-42h3v46h12v-46h6v-20h9v-17zm-15-61v-13h-12v13zm12 30v-13h-12v13zm12 31v-26h-12v26zm12 131v-3h-12v3zm12 110v-14h-12v14zm27-241v-26h-9v-5h9v-13h-9v-17h9v-13h-9v-21h9v-21h-9v-3h-6v-62h6v-11h-6v-29-51h-15v-1h-54v-17h-35v11h-22v6h-53v1h-14v51h-108v105h-15v21h15v21h-15v13h15v17h-15-25v13h25v5h-25v1h25v25h15v17h21v6h61v5h75v9h18v42h22v4h35v-4h23v-42h31v-9h3v9h12v-9-11h6v-17zm0 0v-26h-6v-5h6v-13h-6v-17h6v-13h-6v-21h6v-21h-6v-3-62-11-29h-15v-51h-54v-1h-35v-6 6h-22v1h-53v51h-14v24h-87v81h-21v21h21v21h-21v13h21v17h-21-15v13h15v5h-15v1h15v25h21v17h61v6h39v-6h36v11h18v9h22v42h35v-42h23v-9h31v-11h3v11h12v-11-17zm0 0v-26-5-13-17-13-21-21-3h-12v3h-3v-65h15v-11h-15v-29h-54v-51h-35v-1 1h-22v51h-53v29h-1v-5h-13v5h-26v76h-61v21h61v21h-61v13h61v17h-61-21v13h21v5h-21v1h21v25h61v17h39v-17h36v17h18v11h22v9h35v-9h23v-11h31v-17h3v17h12v-17zm15-419v-12h-2v12zm186 356v-56h-8v-133h-4v-12h-13v-9h-13v-45h-12v-10h-62v-59-6h-26v-16h-33v-10h33v-12h-33v-22h-5v-29h49v-5h-49-8v-17h-119v17h-107-279v34h-38v26h-24v27h24v179h-7v105h-17v55h17v17h-17v13h17v5h-17v1h17v42h18v20h3v94h14 8v62h41v37h26v-37h23v48h18v32h35v61h8v21h122v2h75v37h98v-37h34v17h119v-57h11v29h66v-29h4v-40h-4v-26h3v-123h-3v-27h3v-1h1v-17h-1v-46h1v-17h3v-51-32zm0 0v-54h-4v-2h-3v-73h-10v-60h-13v-12h-12v-9h-31v9h-31v-9-55h-59v-59h-5v-5h5v-1h-5v-16h-8v-10h8v-12h-8v-22h-119v34h117v10h-28v-6h-89v6h-22v5h-175v11h-40v13h-147v11h-4v107h-8v41h-6v105h-22v21h28v21h-17v13h17v17h-14-3v13h3v5h-3v1h3v42h14v20h8v94h41 26 23 18v62h4v48h31v10h8v22h3v11h119v50h75v21h98v-71h34v71h48v-71h30v-11h21v-22h20v-120h11v120h43v-123h17-17v-27h17v-1h6v-17h-6v-46h6v-17h3v-51h1v-32zm-4 0v-11h-6v-43h-4v-2h-13v-39h-12v-34h-4v34h-27v2h-31v-2-34h-48v36h-2v37h-1v-73h-8v-29-52h-5v-17h-8v-38h-15v-59h-15v-6h-89v6h-22v7h-175v16h-15v36h-25v55h-39v11h-4v41h-18v105h-54v-105h-32v105h-4v7h4v14h86v21h-86v13h86v17h-86-4v13h4v5h-4v1h4v42h86v11h18v9h4v19h-4v25h4v50h16v-48h23v45h-8v3h8 122v96h-119v14h119v10h75v22h75v-22h23v-10h34v10h48v-24h-36v-36h15v-60h21v-3h-11v-43h2v15h9v-15h46v15h5v-15h20v-2h-20v-46h20v-37h11v37h8v46h-8v2h8v15h22v-15h1v-2h-1v-46h1v-17h12v-20h13v-31h4v-32zm-142 148v-2h-9v2zm9-2v-46h46v46zm-46 45v-28h46v28zm67-191v-11h-1v-42h-3v42h-19v11h19v32h3v-32zm-61 0v-11h-5v11zm96 0v-11h-4v-43h-13v-2h-2v-37h-10v-2h-4v2h-27v37h-31v-37-2h-5v2h-43v37h-2v3h-1v-3h-8v-62-11-29h-5v-52h-8v-17h-15v-38-52h-15v-7h-89v7h-22v16h-175v36h-15v55h-25v1h-37v10h-2v41h-4v105h-18v21h18v21h-18v13h18v17h-18-86v13h86v5h-86v1h86v42h18v11h4v9h2v19h-2v25h2v2h14v-2h23v2h40v2h82v43h-122v3h122 75v96h-75v14h75v10h75v-10h23v-14h-23v-36h23v-60h34v60h12v-60h15 10v-3h-10v-43h10v-48h11v-37h46v37h5v-37h20v-30h11v30h8v37h22v-17h1v-20h12v-31h13v-32zm-13 0v-11h-2v-43h-10v-2h-4v2h-19v1h-8v42h-31v-21-21-3h-5v3h-43v21h43v21h-43v11h43v19h-45v13h45v1h5v-1h20v-13h-20v-19h31v32h8v1h19v30h3v-30h1v-1h10v-32zm-72 148v-2h-5v2zm5 43h-5zm66-191v-11h-3v11zm-38 146v-46h11v46zm-11 45v-28h11v28zm-11 149v-4h11v4zm-11 40v-40h-8v40zm92-380v-54-2h-4v-133h-13v-12h-13v-9h-12v-45h-31v45h-31v-55-59h-59v-5h33v-1h-33v-16h-5v-10h5v-12h-5v-22h-8v-29h8v-5h-8-119-107v5h107v29h-386v26h-38v27h40v20h-4v11h-14v148h-22v105h-7v55h18v17h-18v13h18v5h-18v1h18v42h3v20h14v94h8 41v62h26v-62h23v62h18v48h4v10h31v22h8v61h122v21h75v2h98v-2h34v2h99v-84h20v-22h11v22h43v-22h23v-123h-6v-27h6v-1h3v-17h-3v-46h3v-17h1v-51h3v-32zm-43 148v-2h-22v2zm22 43h-30zm66 189v-40h-66v40zm41-380v-11h-10v-43h-4v1h-19v42h-8v11h8v32h19v1h3v-1h1v-32zm38 0v-11h-3v-43h-6v-2h-4v-39h-13v-34h-12v-60h-4v60h-27v34h-31v-34-72h-48v72h-3v-29h-8v-52-17h-5v-38h-8v-59h-15v-6h-15v-11h-89v11h-22v6h-175v7h-15v16h-25v36h-43v66h-18v41h-54v-41h-32v41h-4v105h-8v7h8v14h4v21h-4v13h4v17h-4-8v13h8v5h-8v1h8v42h4v11h86v9h18v19h-18v25h18v50h4 16 15 8v110h3v10h119v22h75v11h75v-11h23v-22h34v22h48v-22h30v-24h-30v-96h51v-3h20-20v-28h20v-15h11v15h8v1h22v-1h13v-17h-12v-46h12v-17h17v-51h6v-32z"
;
verifyPoly
(
"disjunct"
,
disjunct
,
aDisjunctRanges
);
verifyPoly
(
"equal"
,
equal
,
aEqualRanges
);
verifyPoly
(
"intersectionN"
,
intersectionN
,
aIntersectionN
);
verifyPoly
(
"intersectionE"
,
intersectionE
,
aIntersectionE
);
verifyPoly
(
"intersectionS"
,
intersectionS
,
aIntersectionS
);
verifyPoly
(
"intersectionW"
,
intersectionW
,
aIntersectionW
);
verifyPoly
(
"intersectionNE"
,
intersectionNE
,
aIntersectionNE
);
verifyPoly
(
"intersectionSE"
,
intersectionSE
,
aIntersectionSE
);
verifyPoly
(
"intersectionSW"
,
intersectionSW
,
aIntersectionSW
);
verifyPoly
(
"intersectionNW"
,
intersectionNW
,
aIntersectionNW
);
verifyPoly
(
"ringIntersection"
,
ringIntersection
,
aRingIntersection
);
verifyPoly
(
"ringIntersection2"
,
ringIntersection2
,
aRingIntersection2
);
verifyPoly
(
"ringIntersectExtraStrip"
,
ringIntersectExtraStrip
,
aRingIntersectExtraStrip
);
verifyPoly
(
"complexIntersections"
,
complexIntersections
,
aComplexIntersections
);
verifyPoly
(
"randomIntersections"
,
randomIntersections
,
aRandomIntersections
);
}
void
dumpSvg
(
const
char
*
pName
,
const
::
basegfx
::
B2DPolyPolygon
&
rPoly
)
{
(
void
)
pName
;
(
void
)
rPoly
;
#if defined(VERBOSE)
fprintf
(
stderr
,
"%s - svg:d=
\"
%s
\"\n
"
,
pName
,
rtl
::
OUStringToOString
(
basegfx
::
tools
::
exportToSvgD
(
rPoly
),
RTL_TEXTENCODING_UTF8
).
getStr
()
);
#endif
}
void
getPolyPolygon
()
{
dumpSvg
(
"disjunct"
,
aDisjunctRanges
.
solveCrossovers
());
dumpSvg
(
"equal"
,
aEqualRanges
.
solveCrossovers
());
dumpSvg
(
"intersectionN"
,
aIntersectionN
.
solveCrossovers
());
dumpSvg
(
"intersectionE"
,
aIntersectionE
.
solveCrossovers
());
dumpSvg
(
"intersectionS"
,
aIntersectionS
.
solveCrossovers
());
dumpSvg
(
"intersectionW"
,
aIntersectionW
.
solveCrossovers
());
dumpSvg
(
"intersectionNE"
,
aIntersectionNE
.
solveCrossovers
());
dumpSvg
(
"intersectionSE"
,
aIntersectionSE
.
solveCrossovers
());
dumpSvg
(
"intersectionSW"
,
aIntersectionSW
.
solveCrossovers
());
dumpSvg
(
"intersectionNW"
,
aIntersectionNW
.
solveCrossovers
());
dumpSvg
(
"ringIntersection"
,
aRingIntersection
.
solveCrossovers
());
dumpSvg
(
"ringIntersection2"
,
aRingIntersection2
.
solveCrossovers
());
dumpSvg
(
"aRingIntersectExtraStrip"
,
aRingIntersectExtraStrip
.
solveCrossovers
());
dumpSvg
(
"complexIntersections"
,
aComplexIntersections
.
solveCrossovers
());
dumpSvg
(
"randomIntersections"
,
aRandomIntersections
.
solveCrossovers
());
CPPUNIT_ASSERT_MESSAGE
(
"getPolyPolygon"
,
true
);
}
void
validatePoly
(
const
char
*
pName
,
const
B2DPolyRange
&
rRange
)
{
B2DPolyPolygon
genericClip
;
const
sal_uInt32
nCount
=
rRange
.
count
();
for
(
sal_uInt32
i
=
0
;
i
<
nCount
;
++
i
)
{
B2DPolygon
aRect
=
tools
::
createPolygonFromRect
(
rRange
.
getElement
(
i
).
head
);
if
(
rRange
.
getElement
(
i
).
tail
.
head
==
ORIENTATION_NEGATIVE
)
aRect
.
flip
();
genericClip
.
append
(
aRect
);
}
#if defined(VERBOSE)
fprintf
(
stderr
,
"%s input - svg:d=
\"
%s
\"\n
"
,
pName
,
rtl
::
OUStringToOString
(
basegfx
::
tools
::
exportToSvgD
(
genericClip
),
RTL_TEXTENCODING_UTF8
).
getStr
()
);
#endif
const
B2DPolyPolygon
boxClipResult
=
rRange
.
solveCrossovers
();
const
rtl
::
OUString
boxClipSvg
(
basegfx
::
tools
::
exportToSvgD
(
normalizePoly
(
boxClipResult
)));
#if defined(VERBOSE)
fprintf
(
stderr
,
"%s boxclipper - svg:d=
\"
%s
\"\n
"
,
pName
,
rtl
::
OUStringToOString
(
boxClipSvg
,
RTL_TEXTENCODING_UTF8
).
getStr
()
);
#endif
genericClip
=
tools
::
solveCrossovers
(
genericClip
);
const
rtl
::
OUString
genericClipSvg
(
basegfx
::
tools
::
exportToSvgD
(
normalizePoly
(
genericClip
)));
#if defined(VERBOSE)
fprintf
(
stderr
,
"%s genclipper - svg:d=
\"
%s
\"\n
"
,
pName
,
rtl
::
OUStringToOString
(
genericClipSvg
,
RTL_TEXTENCODING_UTF8
).
getStr
()
);
#endif
CPPUNIT_ASSERT_MESSAGE
(
pName
,
genericClipSvg
==
boxClipSvg
);
}
void
validatePoly
()
{
validatePoly
(
"disjunct"
,
aDisjunctRanges
);
validatePoly
(
"equal"
,
aEqualRanges
);
validatePoly
(
"intersectionN"
,
aIntersectionN
);
validatePoly
(
"intersectionE"
,
aIntersectionE
);
validatePoly
(
"intersectionS"
,
aIntersectionS
);
validatePoly
(
"intersectionW"
,
aIntersectionW
);
validatePoly
(
"intersectionNE"
,
aIntersectionNE
);
validatePoly
(
"intersectionSE"
,
aIntersectionSE
);
validatePoly
(
"intersectionSW"
,
aIntersectionSW
);
validatePoly
(
"intersectionNW"
,
aIntersectionNW
);
validatePoly
(
"ringIntersection"
,
aRingIntersection
);
validatePoly
(
"ringIntersection2"
,
aRingIntersection2
);
validatePoly
(
"ringIntersectExtraStrip"
,
aRingIntersectExtraStrip
);
// generic clipper buggy here, likely
//validatePoly("complexIntersections", aComplexIntersections);
//validatePoly("randomIntersections", aRandomIntersections);
}
// Change the following lines only, if you add, remove or rename
// member functions of the current class,
// because these macros are need by auto register mechanism.
CPPUNIT_TEST_SUITE
(
boxclipper
);
CPPUNIT_TEST
(
validatePoly
);
CPPUNIT_TEST
(
verifyPoly
);
CPPUNIT_TEST
(
getPolyPolygon
);
CPPUNIT_TEST_SUITE_END
();
};
// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION
(
basegfx2d
::
boxclipper
,
"boxclipper"
);
}
// namespace basegfx2d
// -----------------------------------------------------------------------------
// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.
// NOADDITIONAL;
basegfx/test/makefile.mk
Dosyayı görüntüle @
8454c5ef
...
@@ -85,6 +85,10 @@ SLOFILES=$(SHL1OBJS)
...
@@ -85,6 +85,10 @@ SLOFILES=$(SHL1OBJS)
.INCLUDE
:
target.mk
.INCLUDE
:
target.mk
.INCLUDE
:
_cppunit.mk
.INCLUDE
:
_cppunit.mk
.IF
"$(verbose)"
!=
""
||
"$(VERBOSE)"
!=
""
CDEFS
+=
-DVERBOSE
.ENDIF
# --- Enable testshl2 execution in normal build ------------------------
# --- Enable testshl2 execution in normal build ------------------------
$(MISC)$/unittest_succeeded
:
$(SHL1TARGETN)
$(MISC)$/unittest_succeeded
:
$(SHL1TARGETN)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment