summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2009-08-05 09:18:12 +0200
committersb <sb@openoffice.org>2009-08-05 09:18:12 +0200
commit35235ced9cdc59f312e6259cf1cdda8e1aa5a623 (patch)
treeb624001d25a2da9d831742a987e3c8797bef40fa
parent9bb3f6beedc087c550cc1d4d455204819cfc8939 (diff)
parentc0bfd066e3d8355d35c2ea22d5a98ac7f43406da (diff)
merged in DEV300_m54
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx9
-rw-r--r--basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx14
-rw-r--r--basegfx/source/curve/b2dcubicbezier.cxx36
-rw-r--r--basegfx/source/polygon/b2dlinegeometry.cxx105
-rw-r--r--basegfx/source/polygon/b2dpolygoncutandtouch.cxx9
-rw-r--r--basegfx/source/polygon/b2dpolypolygoncutter.cxx79
-rw-r--r--basegfx/source/polygon/b2dpolypolygontools.cxx12
-rw-r--r--canvas/source/cairo/cairo_canvashelper.cxx2
-rw-r--r--dtrans/source/X11/X11_selection.cxx9
-rw-r--r--dtrans/source/aqua/DropTarget.cxx12
-rw-r--r--dtrans/source/aqua/aqua_clipboard.cxx9
-rw-r--r--i18npool/source/calendar/calendar_gregorian.cxx34
-rw-r--r--i18npool/source/paper/paper.cxx9
-rw-r--r--sot/inc/sot/exchange.hxx11
-rw-r--r--sot/source/base/exchange.cxx34
-rw-r--r--svtools/inc/docmspasswdrequest.hxx72
-rw-r--r--svtools/inc/pch/precompiled_svtools.hxx1
-rw-r--r--svtools/inc/svtools/svlbox.hxx3
-rw-r--r--svtools/prj/d.lst1
-rw-r--r--svtools/source/contnr/svlbox.cxx6
-rw-r--r--svtools/source/control/scrwin.cxx4
-rw-r--r--svtools/source/misc1/adrparse.cxx16
-rw-r--r--svtools/source/misc1/docmspasswdrequest.cxx143
-rw-r--r--svtools/source/misc1/makefile.mk1
-rw-r--r--toolkit/source/awt/vclxwindow.cxx2
-rw-r--r--tools/bootstrp/md5.cxx64
-rw-r--r--tools/source/fsys/urlobj.cxx9
-rw-r--r--tools/workben/urltest.cxx19
-rwxr-xr-xtransex3/scripts/localize.pl10
-rw-r--r--unotools/inc/unotools/confignode.hxx2
-rw-r--r--unotools/source/config/confignode.cxx5
-rwxr-xr-xvcl/aqua/inc/vclnsapp.h1
-rw-r--r--vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm2
-rw-r--r--vcl/aqua/source/a11y/aqua11yutil.mm2
-rw-r--r--vcl/aqua/source/a11y/aqua11ywrapper.mm8
-rw-r--r--vcl/aqua/source/app/saldata.cxx2
-rw-r--r--vcl/aqua/source/app/salinst.cxx16
-rw-r--r--vcl/aqua/source/app/salsys.cxx8
-rwxr-xr-xvcl/aqua/source/app/vclnsapp.mm73
-rwxr-xr-xvcl/aqua/source/gdi/aquaprintview.mm5
-rwxr-xr-xvcl/aqua/source/gdi/salatslayout.cxx9
-rw-r--r--vcl/aqua/source/gdi/salgdi.cxx5
-rwxr-xr-xvcl/aqua/source/gdi/salgdiutils.cxx9
-rw-r--r--vcl/aqua/source/gdi/salnativewidgets.cxx8
-rw-r--r--vcl/aqua/source/gdi/salprn.cxx8
-rw-r--r--vcl/aqua/source/gdi/salvd.cxx4
-rw-r--r--vcl/aqua/source/window/salframe.cxx14
-rwxr-xr-xvcl/aqua/source/window/salframeview.mm10
-rw-r--r--vcl/aqua/source/window/salmenu.cxx12
-rw-r--r--vcl/inc/sft.h641
-rw-r--r--vcl/inc/vcl/gdimtf.hxx8
-rw-r--r--vcl/inc/vcl/graph.hxx44
-rw-r--r--vcl/inc/vcl/impgraph.hxx5
-rw-r--r--vcl/inc/vcl/outdev.hxx24
-rw-r--r--vcl/inc/vcl/sndstyle.hxx2
-rw-r--r--vcl/source/app/dbggui.cxx2
-rw-r--r--vcl/source/control/lstbox.cxx62
-rw-r--r--vcl/source/fontsubset/sft.cxx2
-rw-r--r--vcl/source/gdi/gdimtf.cxx430
-rw-r--r--vcl/source/gdi/graph.cxx38
-rw-r--r--vcl/source/gdi/impgraph.cxx38
-rw-r--r--vcl/source/gdi/makefile.mk1
-rw-r--r--vcl/source/gdi/outdev.cxx312
-rw-r--r--vcl/source/gdi/outdev3.cxx24
-rw-r--r--vcl/source/gdi/outdev6.cxx14
-rw-r--r--vcl/source/glyphs/gcach_ftyp.cxx24
-rw-r--r--vcl/source/window/menu.cxx13
-rw-r--r--vcl/source/window/window.cxx12
-rw-r--r--vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx4
-rw-r--r--vcl/unx/gtk/window/gtkframe.cxx2
-rw-r--r--vcl/unx/source/gdi/salgdi.cxx3087
-rw-r--r--vcl/unx/source/window/salframe.cxx28
-rw-r--r--vcl/win/source/gdi/salgdi_gdiplus.cxx162
-rw-r--r--vcl/win/source/window/salframe.cxx10
74 files changed, 3287 insertions, 2640 deletions
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
index 9474e51e3904..12532ff078f3 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx
@@ -104,6 +104,15 @@ namespace basegfx
// DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A)
B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+ /** merge all single PolyPolygons to a single, OR-ed PolyPolygon
+
+ @param rInput
+ The source PolyPolygons
+
+ @return A single PolyPolygon containing the Or-merged result
+ */
+ B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput);
+
} // end of namespace tools
} // end of namespace basegfx
diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
index 5c75edd7f262..c4687b3cfc5f 100644
--- a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
+++ b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx
@@ -262,6 +262,20 @@ namespace basegfx
bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue);
bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB);
+ /** snap some polygon coordinates to discrete coordinates
+
+ This method allows to snap some polygon points to discrete (integer) values
+ which equals e.g. a snap to discrete coordinates. It will snap points of
+ horizontal and vertical edges
+
+ @param rCandidate
+ The source polygon
+
+ @return
+ The modified version of the source polygon
+ */
+ B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate);
+
} // end of namespace tools
} // end of namespace basegfx
diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx
index 76d1b74ddbca..e7247a95333b 100644
--- a/basegfx/source/curve/b2dcubicbezier.cxx
+++ b/basegfx/source/curve/b2dcubicbezier.cxx
@@ -443,21 +443,32 @@ namespace basegfx
bool bAIsTrivial(aVecA.equalZero());
bool bBIsTrivial(aVecB.equalZero());
+ // #i102241# prepare inverse edge length to normalize cross values;
+ // else the small compare value used in fTools::equalZero
+ // will be length dependent and this detection will work as less
+ // precise as longer the edge is. In principle, the length of the control
+ // vector would need to be used too, but to be trivial it is assumed to
+ // be of roughly equal length to the edge, so edge length can be used
+ // for both. Only needed when one of both is not trivial per se.
+ const double fInverseEdgeLength(bAIsTrivial && bBIsTrivial
+ ? 1.0
+ : 1.0 / aEdge.getLength());
+
// if A is not zero, check if it could be
if(!bAIsTrivial)
{
- // parallel to edge? Check aVecA, aEdge
- // B2DVector::areParallel is too correct, uses differences in the e15 region,
- // thus do own test here
- const double fValA(aVecA.getX() * aEdge.getY());
- const double fValB(aVecA.getY() * aEdge.getX());
+ // #i102241# parallel to edge? Check aVecA, aEdge. Use cross() which does what
+ // we need here with the precision we need
+ const double fCross(aVecA.cross(aEdge) * fInverseEdgeLength);
- if(fTools::equalZero(fabs(fValA) - fabs(fValB)))
+ if(fTools::equalZero(fCross))
{
// get scale to edge. Use bigger distance for numeric quality
- const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecA.getX() / aEdge.getX() : aVecA.getY() / aEdge.getY());
+ const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY())
+ ? aVecA.getX() / aEdge.getX()
+ : aVecA.getY() / aEdge.getY());
- // end point of vector in edge range?
+ // relative end point of vector in edge range?
if(fTools::moreOrEqual(fScale, 0.0) && fTools::lessOrEqual(fScale, 1.0))
{
bAIsTrivial = true;
@@ -470,13 +481,14 @@ namespace basegfx
if(bAIsTrivial && !bBIsTrivial)
{
// parallel to edge? Check aVecB, aEdge
- const double fValA(aVecB.getX() * aEdge.getY());
- const double fValB(aVecB.getY() * aEdge.getX());
+ const double fCross(aVecB.cross(aEdge) * fInverseEdgeLength);
- if(fTools::equalZero(fabs(fValA) - fabs(fValB)))
+ if(fTools::equalZero(fCross))
{
// get scale to edge. Use bigger distance for numeric quality
- const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecB.getX() / aEdge.getX() : aVecB.getY() / aEdge.getY());
+ const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY())
+ ? aVecB.getX() / aEdge.getX()
+ : aVecB.getY() / aEdge.getY());
// end point of vector in edge range? Caution: controlB is directed AGAINST edge
if(fTools::lessOrEqual(fScale, 0.0) && fTools::moreOrEqual(fScale, -1.0))
diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx
index 0cda1036e13b..1a9264ab769e 100644
--- a/basegfx/source/polygon/b2dlinegeometry.cxx
+++ b/basegfx/source/polygon/b2dlinegeometry.cxx
@@ -352,13 +352,12 @@ namespace basegfx
// Unfortunately, while it would be geometrically correct to not add
// the in-between points EdgeEnd and EdgeStart, it leads to rounding
// errors when converting to integer polygon coordinates for painting
- const B2DVector aEdgeVector(rEdge.getEndPoint() - rEdge.getStartPoint());
-
if(rEdge.isBezier())
{
// prepare target and data common for upper and lower
B2DPolygon aBezierPolygon;
- const double fEdgeLength(aEdgeVector.getLength());
+ const B2DVector aPureEdgeVector(rEdge.getEndPoint() - rEdge.getStartPoint());
+ const double fEdgeLength(aPureEdgeVector.getLength());
const bool bIsEdgeLengthZero(fTools::equalZero(fEdgeLength));
const B2DVector aTangentA(rEdge.getTangent(0.0));
const B2DVector aTangentB(rEdge.getTangent(1.0));
@@ -441,7 +440,11 @@ namespace basegfx
}
else
{
- const B2DVector aPerpendEdgeVector(getNormalizedPerpendicular(aEdgeVector) * fHalfLineWidth);
+ // #i101491# emulate rEdge.getTangent call which applies a factor of 0.3 to the
+ // full-length edge vector to have numerically exactly the same results as in the
+ // createAreaGeometryForJoin implementation
+ const B2DVector aEdgeTangent((rEdge.getEndPoint() - rEdge.getStartPoint()) * 0.3);
+ const B2DVector aPerpendEdgeVector(getNormalizedPerpendicular(aEdgeTangent) * fHalfLineWidth);
B2DPolygon aEdgePolygon;
// create upper edge
@@ -495,45 +498,75 @@ namespace basegfx
}
}
- // create first polygon part for edge
- aEdgePolygon.append(aEndPoint);
- aEdgePolygon.append(rPoint);
- aEdgePolygon.append(aStartPoint);
-
- if(B2DLINEJOIN_MITER == eJoin)
+ switch(eJoin)
{
- // Look for the cut point between start point along rTangentPrev and
- // end point along rTangentEdge. -rTangentEdge should be used, but since
- // the cut value is used for interpolating along the first edge, the negation
- // is not needed since the same fCut will be found on the first edge.
- // If it exists, insert it to complete the mitered fill polygon.
- double fCutPos(0.0);
- tools::findCut(aStartPoint, rTangentPrev, aEndPoint, rTangentEdge, CUTFLAG_ALL, &fCutPos);
-
- if(0.0 != fCutPos)
+ case B2DLINEJOIN_MITER :
{
- const B2DPoint aCutPoint(interpolate(aStartPoint, aStartPoint + rTangentPrev, fCutPos));
- aEdgePolygon.append(aCutPoint);
- }
- }
- else if(B2DLINEJOIN_ROUND == eJoin)
- {
- // use tooling to add needed EllipseSegment
- double fAngleStart(atan2(rPerpendPrev.getY(), rPerpendPrev.getX()));
- double fAngleEnd(atan2(rPerpendEdge.getY(), rPerpendEdge.getX()));
+ aEdgePolygon.append(aEndPoint);
+ aEdgePolygon.append(rPoint);
+ aEdgePolygon.append(aStartPoint);
+
+ // Look for the cut point between start point along rTangentPrev and
+ // end point along rTangentEdge. -rTangentEdge should be used, but since
+ // the cut value is used for interpolating along the first edge, the negation
+ // is not needed since the same fCut will be found on the first edge.
+ // If it exists, insert it to complete the mitered fill polygon.
+ double fCutPos(0.0);
+ tools::findCut(aStartPoint, rTangentPrev, aEndPoint, rTangentEdge, CUTFLAG_ALL, &fCutPos);
+
+ if(0.0 != fCutPos)
+ {
+ const B2DPoint aCutPoint(interpolate(aStartPoint, aStartPoint + rTangentPrev, fCutPos));
+ aEdgePolygon.append(aCutPoint);
+ }
- // atan2 results are [-PI .. PI], consolidate to [0.0 .. 2PI]
- if(fAngleStart < 0.0)
- {
- fAngleStart += F_2PI;
+ break;
}
-
- if(fAngleEnd < 0.0)
+ case B2DLINEJOIN_ROUND :
{
- fAngleEnd += F_2PI;
+ // use tooling to add needed EllipseSegment
+ double fAngleStart(atan2(rPerpendPrev.getY(), rPerpendPrev.getX()));
+ double fAngleEnd(atan2(rPerpendEdge.getY(), rPerpendEdge.getX()));
+
+ // atan2 results are [-PI .. PI], consolidate to [0.0 .. 2PI]
+ if(fAngleStart < 0.0)
+ {
+ fAngleStart += F_2PI;
+ }
+
+ if(fAngleEnd < 0.0)
+ {
+ fAngleEnd += F_2PI;
+ }
+
+ const B2DPolygon aBow(tools::createPolygonFromEllipseSegment(rPoint, fHalfLineWidth, fHalfLineWidth, fAngleStart, fAngleEnd));
+
+ if(aBow.count() > 1)
+ {
+ // #i101491#
+ // use the original start/end positions; the ones from bow creation may be numerically
+ // different due to their different creation. To guarantee good merging quality with edges
+ // and edge roundings (and to reduce point count)
+ aEdgePolygon = aBow;
+ aEdgePolygon.setB2DPoint(0, aStartPoint);
+ aEdgePolygon.setB2DPoint(aEdgePolygon.count() - 1, aEndPoint);
+ aEdgePolygon.append(rPoint);
+
+ break;
+ }
+ else
+ {
+ // wanted fall-through to default
+ }
}
+ default: // B2DLINEJOIN_BEVEL
+ {
+ aEdgePolygon.append(aEndPoint);
+ aEdgePolygon.append(rPoint);
+ aEdgePolygon.append(aStartPoint);
- aEdgePolygon.append(tools::createPolygonFromEllipseSegment(rPoint, fHalfLineWidth, fHalfLineWidth, fAngleStart, fAngleEnd));
+ break;
+ }
}
// create last polygon part for edge
diff --git a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
index a1b7a69775ad..26016942717d 100644
--- a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
+++ b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx
@@ -110,7 +110,10 @@ namespace basegfx
{
// #i76891# mergeTemporaryPointsAndPolygon redesigned to be able to correctly handle
// single edges with/without control points
- if(rTempPoints.size())
+ // #i101491# added counter for non-changing element count
+ const sal_uInt32 nTempPointCount(rTempPoints.size());
+
+ if(nTempPointCount)
{
B2DPolygon aRetval;
const sal_uInt32 nCount(rCandidate.count());
@@ -138,7 +141,7 @@ namespace basegfx
double fLeftStart(0.0);
// now add all points targeted to be at this index
- while(nNewInd < rTempPoints.size() && rTempPoints[nNewInd].getIndex() == a)
+ while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a)
{
const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];
@@ -160,7 +163,7 @@ namespace basegfx
else
{
// add all points targeted to be at this index
- while(nNewInd < rTempPoints.size() && rTempPoints[nNewInd].getIndex() == a)
+ while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a)
{
const temporaryPoint& rTempPoint = rTempPoints[nNewInd++];
const B2DPoint aNewPoint(rTempPoint.getPoint());
diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
index b06e6fbafff7..0674bfe3953e 100644
--- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx
+++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx
@@ -929,6 +929,85 @@ namespace basegfx
}
}
+ B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput)
+ {
+ std::vector< basegfx::B2DPolyPolygon > aInput(rInput);
+
+ // first step: prepareForPolygonOperation and simple merge of non-overlapping
+ // PolyPolygons for speedup; this is possible for the wanted OR-operation
+ if(aInput.size())
+ {
+ std::vector< basegfx::B2DPolyPolygon > aResult;
+ aResult.reserve(aInput.size());
+
+ for(sal_uInt32 a(0); a < aInput.size(); a++)
+ {
+ const basegfx::B2DPolyPolygon aCandidate(prepareForPolygonOperation(aInput[a]));
+
+ if(aResult.size())
+ {
+ const B2DRange aCandidateRange(aCandidate.getB2DRange());
+ bool bCouldMergeSimple(false);
+
+ for(sal_uInt32 b(0); !bCouldMergeSimple && b < aResult.size(); b++)
+ {
+ basegfx::B2DPolyPolygon aTarget(aResult[b]);
+ const B2DRange aTargetRange(aTarget.getB2DRange());
+
+ if(!aCandidateRange.overlaps(aTargetRange))
+ {
+ aTarget.append(aCandidate);
+ aResult[b] = aTarget;
+ bCouldMergeSimple = true;
+ }
+ }
+
+ if(!bCouldMergeSimple)
+ {
+ aResult.push_back(aCandidate);
+ }
+ }
+ else
+ {
+ aResult.push_back(aCandidate);
+ }
+ }
+
+ aInput = aResult;
+ }
+
+ // second step: melt pairwise to a single PolyPolygon
+ while(aInput.size() > 1)
+ {
+ std::vector< basegfx::B2DPolyPolygon > aResult;
+ aResult.reserve((aInput.size() / 2) + 1);
+
+ for(sal_uInt32 a(0); a < aInput.size(); a += 2)
+ {
+ if(a + 1 < aInput.size())
+ {
+ // a pair for processing
+ aResult.push_back(solvePolygonOperationOr(aInput[a], aInput[a + 1]));
+ }
+ else
+ {
+ // last single PolyPolygon; copy to target to not lose it
+ aResult.push_back(aInput[a]);
+ }
+ }
+
+ aInput = aResult;
+ }
+
+ // third step: get result
+ if(1 == aInput.size())
+ {
+ return aInput[0];
+ }
+
+ return B2DPolyPolygon();
+ }
+
//////////////////////////////////////////////////////////////////////////////
} // end of namespace tools
diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx
index c92f2f29147b..e6b3a448530d 100644
--- a/basegfx/source/polygon/b2dpolypolygontools.cxx
+++ b/basegfx/source/polygon/b2dpolypolygontools.cxx
@@ -569,6 +569,18 @@ namespace basegfx
return equal(rCandidateA, rCandidateB, fSmallValue);
}
+ B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate)
+ {
+ B2DPolyPolygon aRetval;
+
+ for(sal_uInt32 a(0L); a < rCandidate.count(); a++)
+ {
+ aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a)));
+ }
+
+ return aRetval;
+ }
+
} // end of namespace tools
} // end of namespace basegfx
diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx
index f1c54e9b4ab7..9cf2dd978759 100644
--- a/canvas/source/cairo/cairo_canvashelper.cxx
+++ b/canvas/source/cairo/cairo_canvashelper.cxx
@@ -888,7 +888,7 @@ namespace cairocanvas
nY = aP.getY();
cairo_matrix_transform_point( &aOrigMatrix, &nX, &nY );
- if( ! bIsBezier && bIsRectangle ) {
+ if( ! bIsBezier && (bIsRectangle || aOperation == Clip) ) {
nX = basegfx::fround( nX );
nY = basegfx::fround( nY );
}
diff --git a/dtrans/source/X11/X11_selection.cxx b/dtrans/source/X11/X11_selection.cxx
index affc92e98908..21030a220917 100644
--- a/dtrans/source/X11/X11_selection.cxx
+++ b/dtrans/source/X11/X11_selection.cxx
@@ -515,6 +515,15 @@ SelectionManager::~SelectionManager()
// destroy message window
if( m_aWindow )
XDestroyWindow( m_pDisplay, m_aWindow );
+ // release cursors
+ if (m_aMoveCursor != None)
+ XFreeCursor(m_pDisplay, m_aMoveCursor);
+ if (m_aCopyCursor != None)
+ XFreeCursor(m_pDisplay, m_aCopyCursor);
+ if (m_aLinkCursor != None)
+ XFreeCursor(m_pDisplay, m_aLinkCursor);
+ if (m_aNoneCursor != None)
+ XFreeCursor(m_pDisplay, m_aNoneCursor);
// paranoia setting, the drag thread should have
// done that already
diff --git a/dtrans/source/aqua/DropTarget.cxx b/dtrans/source/aqua/DropTarget.cxx
index bb45742732e7..6f973d7aa08f 100644
--- a/dtrans/source/aqua/DropTarget.cxx
+++ b/dtrans/source/aqua/DropTarget.cxx
@@ -245,8 +245,8 @@ NSDragOperation DropTarget::draggingEntered(id sender)
CocoaToVCL(dragLocation, bounds);
- sal_Int32 posX = dragLocation.x;
- sal_Int32 posY = dragLocation.y;
+ sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
+ sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
NSPasteboard* dragPboard = [sender draggingPasteboard];
mXCurrentDragClipboard = new AquaClipboard(mXComponentContext, dragPboard, false);
@@ -284,8 +284,8 @@ NSDragOperation DropTarget::draggingUpdated(id sender)
CocoaToVCL(dragLocation, bounds);
- sal_Int32 posX = dragLocation.x;
- sal_Int32 posY = dragLocation.y;
+ sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
+ sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
DropTargetDragEvent dtde(static_cast<OWeakObject*>(this),
0,
@@ -350,8 +350,8 @@ MacOSBOOL DropTarget::performDragOperation(id sender)
CocoaToVCL(dragLocation, bounds);
- sal_Int32 posX = dragLocation.x;
- sal_Int32 posY = dragLocation.y;
+ sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x);
+ sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y);
DropTargetDropEvent dtde(static_cast<OWeakObject*>(this),
0,
diff --git a/dtrans/source/aqua/aqua_clipboard.cxx b/dtrans/source/aqua/aqua_clipboard.cxx
index d0b821099ea0..370edee90eb7 100644
--- a/dtrans/source/aqua/aqua_clipboard.cxx
+++ b/dtrans/source/aqua/aqua_clipboard.cxx
@@ -323,8 +323,13 @@ void AquaClipboard::fireLostClipboardOwnershipEvent(Reference<XClipboardOwner> o
void AquaClipboard::provideDataForType(NSPasteboard* sender, NSString* type)
{
DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent);
- NSData* pBoardData = (NSData*)dp->getSystemData();
- [sender setData: pBoardData forType: type];
+ NSData* pBoardData = NULL;
+
+ if (dp.get() != NULL)
+ {
+ pBoardData = (NSData*)dp->getSystemData();
+ [sender setData: pBoardData forType: type];
+ }
}
diff --git a/i18npool/source/calendar/calendar_gregorian.cxx b/i18npool/source/calendar/calendar_gregorian.cxx
index 96eee0772bc1..50b61eae5cf1 100644
--- a/i18npool/source/calendar/calendar_gregorian.cxx
+++ b/i18npool/source/calendar/calendar_gregorian.cxx
@@ -148,10 +148,42 @@ void SAL_CALL
Calendar_gregorian::init(Era *_eraArray)
{
cCalendar = "com.sun.star.i18n.Calendar_gregorian";
+
+ // #i102356# With icu::Calendar::createInstance(UErrorCode) in a Thai
+ // th_TH system locale we accidentally used a Buddhist calendar. Though
+ // the ICU documentation says that should be the case only for
+ // th_TH_TRADITIONAL (and ja_JP_TRADITIONAL Gengou), a plain th_TH
+ // already triggers that behavior, ja_JP does not. Strange enough,
+ // passing a th_TH locale to the calendar creation doesn't trigger
+ // this.
+ // See also http://userguide.icu-project.org/datetime/calendar
+
+ // Whatever ICU offers as the default calendar for a locale, ensure we
+ // have a Gregorian calendar as requested.
+
+ /* XXX: with the current implementation the aLocale member variable is
+ * not set prior to loading a calendar from locale data. This
+ * creates an empty (root) locale for ICU, but at least the correct
+ * calendar is used. The language part must not be NULL (respectively
+ * not all, language and country and variant), otherwise the current
+ * default locale would be used again and the calendar keyword ignored.
+ * */
+ icu::Locale aIcuLocale( "", NULL, NULL, "calendar=gregorian");
+
UErrorCode status;
- body = icu::Calendar::createInstance(status = U_ZERO_ERROR);
+ body = icu::Calendar::createInstance( aIcuLocale, status = U_ZERO_ERROR);
if (!body || !U_SUCCESS(status)) throw ERROR;
+#if 0
+ {
+ icu::Locale loc;
+ loc = body->getLocale( ULOC_ACTUAL_LOCALE, status = U_ZERO_ERROR);
+ fprintf( stderr, "\nICU calendar actual locale: %s\n", loc.getName());
+ loc = body->getLocale( ULOC_VALID_LOCALE, status = U_ZERO_ERROR);
+ fprintf( stderr, "ICU calendar valid locale: %s\n", loc.getName());
+ }
+#endif
+
eraArray=_eraArray;
}
diff --git a/i18npool/source/paper/paper.cxx b/i18npool/source/paper/paper.cxx
index a81b9b370b8c..726a4c3bd898 100644
--- a/i18npool/source/paper/paper.cxx
+++ b/i18npool/source/paper/paper.cxx
@@ -63,7 +63,7 @@ struct PageDesc
(long)(((v) * 35.27777778) + 0.5)
#define IN2MM100( v ) \
- ((long)((v) * 2540))
+ ((long)(((v) * 2540) + 0.5))
#define MM2MM100( v ) \
((long)((v) * 100))
@@ -362,11 +362,16 @@ PaperInfo PaperInfo::getSystemDefaultPaper()
{
// if set to "use system", try to get locale from system
if( aLocaleStr.getLength() == 0 )
+ {
+ aArgs[ 0 ] <<= CREATE_OUSTRING( "org.openoffice.System/L10N/" );
+ xConfigNA.set( xConfigProv->createInstanceWithArguments(
+ CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ),
+ UNO_QUERY_THROW );
xConfigNA->getByName( CREATE_OUSTRING( "Locale" ) ) >>= aLocaleStr;
+ }
}
catch( Exception& ) {}
-
if (aLocaleStr.getLength() == 0)
aLocaleStr = CREATE_OUSTRING("en-US");
diff --git a/sot/inc/sot/exchange.hxx b/sot/inc/sot/exchange.hxx
index 68862367e4f0..0c235fffcdbb 100644
--- a/sot/inc/sot/exchange.hxx
+++ b/sot/inc/sot/exchange.hxx
@@ -196,10 +196,7 @@ public:
static ULONG RegisterFormatMimeType( const String& rMimeType );
static ULONG GetFormat( const ::com::sun::star::datatransfer::DataFlavor& rFlavor );
- static ULONG GetStaticNameFormat( const String& rName );
-
static String GetFormatName( ULONG nFormat );
- static String GetFormatStaticName( ULONG nFormat );
static sal_Bool GetFormatDataFlavor( ULONG nFormat, ::com::sun::star::datatransfer::DataFlavor& rFlavor );
static String GetFormatMimeType( ULONG nFormat );
static BOOL IsInternal( const SvGlobalName& );
@@ -216,14 +213,6 @@ public:
static ULONG RegisterSotFormatName( SotFormatStringId nId )
{ return nId; }
- // Anzahl der bereits registrierten Formate bzw. der hoechsten
- // registrierten ID abfragen (fuer System-Registrierung)
- // ACHTUNG: Die Algorithmen zur Registrierung beim System
- // verlassen sich darauf, dass die hier gelieferte maximale
- // Format-ID 'klein' ist, so dass eine Schleife ueber alle
- // Formate laufen kann.
- static ULONG GetMaxFormat( void );
-
// same for XTransferable interface
static USHORT GetExchangeAction(
// XTransferable
diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx
index 05de84bdfd46..6dedd84cdaeb 100644
--- a/sot/source/base/exchange.cxx
+++ b/sot/source/base/exchange.cxx
@@ -481,18 +481,6 @@ ULONG SotExchange::GetFormat( const DataFlavor& rFlavor )
/*************************************************************************
|*
-|* SotExchange::GetStaticNameFormat()
-|*
-|* Beschreibung CLIP.SDW
-*************************************************************************/
-ULONG SotExchange::GetStaticNameFormat( const String& rName )
-{
- // has to be changed to return the format for the static name (KA 27.09.2001)
- return SotExchange::RegisterFormatName( rName );
-}
-
-/*************************************************************************
-|*
|* SotExchange::GetFormatName()
|*
|* Beschreibung CLIP.SDW
@@ -508,28 +496,6 @@ String SotExchange::GetFormatName( ULONG nFormat )
return aRet;
}
-/*************************************************************************
-|*
-|* SotExchange::GetFormatStaticName()
-|*
-|* Beschreibung CLIP.SDW
-*************************************************************************/
-String SotExchange::GetFormatStaticName( ULONG nFormat )
-{
- // has to be changed to return the static format name (KA 27.09.2001)
- return SotExchange::GetFormatName( nFormat );
-}
-
-/*************************************************************************
-|*
-|* SotExchange::GetMaxFormat()
-|*
-*************************************************************************/
-ULONG SotExchange::GetMaxFormat( void )
-{
- return( SOT_FORMATSTR_ID_USER_END + InitFormats_Impl().Count() );
-}
-
BOOL SotExchange::IsInternal( const SvGlobalName& rName )
{
if ( rName == SvGlobalName(SO3_SW_CLASSID_60) ||
diff --git a/svtools/inc/docmspasswdrequest.hxx b/svtools/inc/docmspasswdrequest.hxx
new file mode 100644
index 000000000000..684bffe71760
--- /dev/null
+++ b/svtools/inc/docmspasswdrequest.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docmspasswdrequest.hxx,v $
+ * $Revision: 1.0 $
+ *
+ * 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 INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX
+#define INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX
+
+#include "svtools/svldllapi.h"
+#include <com/sun/star/task/DocumentMSPasswordRequest.hpp>
+#include <com/sun/star/task/XInteractionRequest.hpp>
+#include <rtl/ustring.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+class MSAbortContinuation;
+class MSPasswordContinuation;
+
+class SVL_DLLPUBLIC RequestMSDocumentPassword : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest >
+{
+ ::com::sun::star::uno::Any m_aRequest;
+
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >
+ > m_lContinuations;
+
+ MSAbortContinuation* m_pAbort;
+ MSPasswordContinuation* m_pPassword;
+
+public:
+ RequestMSDocumentPassword( ::com::sun::star::task::PasswordRequestMode nMode, ::rtl::OUString aName );
+
+ sal_Bool isAbort();
+ sal_Bool isPassword();
+
+ ::rtl::OUString getPassword();
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getRequest()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >
+ > SAL_CALL getContinuations()
+ throw( ::com::sun::star::uno::RuntimeException );
+};
+
+#endif /* INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX */
diff --git a/svtools/inc/pch/precompiled_svtools.hxx b/svtools/inc/pch/precompiled_svtools.hxx
index 440bd04dce36..cab81cac04ec 100644
--- a/svtools/inc/pch/precompiled_svtools.hxx
+++ b/svtools/inc/pch/precompiled_svtools.hxx
@@ -227,6 +227,7 @@
#include <com/sun/star/system/XProxySettings.hpp>
#include <com/sun/star/system/XSystemShellExecute.hpp>
#include <com/sun/star/task/DocumentPasswordRequest.hpp>
+#include <com/sun/star/task/DocumentMSPasswordRequest.hpp>
#include <com/sun/star/task/MasterPasswordRequest.hpp>
#include <com/sun/star/task/NoMasterException.hpp>
#include <com/sun/star/task/PasswordRequestMode.hpp>
diff --git a/svtools/inc/svtools/svlbox.hxx b/svtools/inc/svtools/svlbox.hxx
index ba119263eff8..7371c2feee05 100644
--- a/svtools/inc/svtools/svlbox.hxx
+++ b/svtools/inc/svtools/svlbox.hxx
@@ -328,6 +328,9 @@ protected:
// wird an der Target-View aufgerufen (im Drop-Handler)
virtual void ReadDragServerInfo( const Point&,SvLBoxDDInfo* );
+ // invalidate children on enable/disable
+ virtual void StateChanged( StateChangedType );
+
virtual ULONG Insert( SvLBoxEntry* pEnt,SvLBoxEntry* pPar,ULONG nPos=LIST_APPEND);
virtual ULONG Insert( SvLBoxEntry* pEntry,ULONG nRootPos = LIST_APPEND );
void InsertTree( SvLBoxEntry* pTree, SvLBoxEntry* pTarget) {pModel->InsertTree( pTree, pTarget ); }
diff --git a/svtools/prj/d.lst b/svtools/prj/d.lst
index 6b85194db6c1..4ff74419b9d4 100644
--- a/svtools/prj/d.lst
+++ b/svtools/prj/d.lst
@@ -312,6 +312,7 @@ mkdir: %_DEST%\inc%_EXT%\svtools
..\inc\textwindowaccessibility.hxx %_DEST%\inc%_EXT%\svtools\textwindowaccessibility.hxx
..\inc\docpasswdrequest.hxx %_DEST%\inc%_EXT%\svtools\docpasswdrequest.hxx
+..\inc\docmspasswdrequest.hxx %_DEST%\inc%_EXT%\svtools\docmspasswdrequest.hxx
..\inc\fontsubstconfig.hxx %_DEST%\inc%_EXT%\svtools\fontsubstconfig.hxx
..\inc\apearcfg.hxx %_DEST%\inc%_EXT%\svtools\apearcfg.hxx
..\inc\fltrcfg.hxx %_DEST%\inc%_EXT%\svtools\fltrcfg.hxx
diff --git a/svtools/source/contnr/svlbox.cxx b/svtools/source/contnr/svlbox.cxx
index 1c81343cd84f..e56db398b8fb 100644
--- a/svtools/source/contnr/svlbox.cxx
+++ b/svtools/source/contnr/svlbox.cxx
@@ -1203,6 +1203,12 @@ void SvLBox::ViewDataInitialized( SvLBoxEntry* )
DBG_CHKTHIS(SvLBox,0);
}
+void SvLBox::StateChanged( StateChangedType eType )
+{
+ if( eType == STATE_CHANGE_ENABLE )
+ Invalidate( INVALIDATE_CHILDREN );
+ Control::StateChanged( eType );
+}
void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow)
{
diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx
index 9805110c9254..162f23948385 100644
--- a/svtools/source/control/scrwin.cxx
+++ b/svtools/source/control/scrwin.cxx
@@ -273,8 +273,8 @@ void __EXPORT ScrollableWindow::Resize()
// disable painting in the corner between the scrollbars
if ( bVVisible && bHVisible )
{
- aCornerWin.SetPosSizePixel(
- *((Point*) &aOutPixSz), Size(nScrSize, nScrSize) );
+ aCornerWin.SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()),
+ Size(nScrSize, nScrSize) );
aCornerWin.Show();
}
else
diff --git a/svtools/source/misc1/adrparse.cxx b/svtools/source/misc1/adrparse.cxx
index d9b389513f80..37c25d6c669f 100644
--- a/svtools/source/misc1/adrparse.cxx
+++ b/svtools/source/misc1/adrparse.cxx
@@ -172,8 +172,8 @@ inline void SvAddressParser_Impl::addTokenToRealName()
if (!m_pRealNameBegin)
m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin;
else if (m_pRealNameEnd < m_pCurTokenBegin - 1
- || m_pRealNameEnd == m_pCurTokenBegin - 1
- && *m_pRealNameEnd != ' ')
+ || (m_pRealNameEnd == m_pCurTokenBegin - 1
+ && *m_pRealNameEnd != ' '))
m_bRealNameReparse = true;
m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd;
}
@@ -634,8 +634,8 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser,
else
{
m_pAddrSpec = m_aInnerAddrSpec.isValid()
- || !m_aOuterAddrSpec.isValid()
- && m_aInnerAddrSpec.isPoorlyValid() ?
+ || (!m_aOuterAddrSpec.isValid()
+ && m_aInnerAddrSpec.isPoorlyValid()) ?
&m_aInnerAddrSpec :
m_aOuterAddrSpec.isPoorlyValid() ?
&m_aOuterAddrSpec : 0;
@@ -663,11 +663,11 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser,
}
UniString aTheRealName;
if (!m_pRealNameBegin
- || m_pAddrSpec == &m_aOuterAddrSpec
+ || (m_pAddrSpec == &m_aOuterAddrSpec
&& m_pRealNameBegin
== m_aOuterAddrSpec.m_pBegin
&& m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd
- && m_pFirstCommentBegin)
+ && m_pFirstCommentBegin))
if (!m_pFirstCommentBegin)
aTheRealName = aTheAddrSpec;
else if (m_bFirstCommentReparse)
@@ -820,7 +820,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase,
return false;
if (*p == '"')
break;
- if (*p == '\x0D' || *p == '\\' && ++p == pEnd
+ if (*p == '\x0D' || (*p == '\\' && ++p == pEnd)
|| !INetMIME::isUSASCII(*p))
return false;
if (INetMIME::needsQuotedStringEscape(*p))
@@ -868,7 +868,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase,
return false;
if (*p == ']')
break;
- if (*p == '\x0D' || *p == '[' || *p == '\\' && ++p == pEnd
+ if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd)
|| !INetMIME::isUSASCII(*p))
return false;
if (*p >= '[' && *p <= ']')
diff --git a/svtools/source/misc1/docmspasswdrequest.cxx b/svtools/source/misc1/docmspasswdrequest.cxx
new file mode 100644
index 000000000000..e892d3a57d1a
--- /dev/null
+++ b/svtools/source/misc1/docmspasswdrequest.cxx
@@ -0,0 +1,143 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright IBM Corporation 2009.
+ * Copyright 2009 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docmspasswdrequest.cxx,v $
+ * $Revision: 1.0 $
+ *
+ * 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_svtools.hxx"
+
+#include "docmspasswdrequest.hxx"
+#include <com/sun/star/task/XInteractionAbort.hpp>
+#include <com/sun/star/task/XInteractionPassword.hpp>
+
+//==========================================================================
+
+class MSAbortContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionAbort >
+{
+ sal_Bool mbSelected;
+
+public:
+ MSAbortContinuation() : mbSelected( sal_False ) {}
+
+ sal_Bool isSelected() { return mbSelected; }
+
+ void reset() { mbSelected = sal_False; }
+
+ virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException) { mbSelected = sal_True; }
+};
+
+//==========================================================================
+
+class MSPasswordContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionPassword >
+{
+ sal_Bool mbSelected;
+ ::rtl::OUString maPassword;
+
+public:
+ MSPasswordContinuation() : mbSelected( sal_False ) {}
+
+ sal_Bool isSelected() { return mbSelected; }
+
+ void reset() { mbSelected = sal_False; }
+
+ virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setPassword( const ::rtl::OUString& aPass ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getPassword( ) throw (::com::sun::star::uno::RuntimeException);
+};
+
+void SAL_CALL MSPasswordContinuation::select()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ mbSelected = sal_True;
+}
+
+void SAL_CALL MSPasswordContinuation::setPassword( const ::rtl::OUString& aPass )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ maPassword = aPass;
+}
+
+::rtl::OUString SAL_CALL MSPasswordContinuation::getPassword()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ return maPassword;
+}
+
+//==========================================================================
+
+RequestMSDocumentPassword::RequestMSDocumentPassword( ::com::sun::star::task::PasswordRequestMode nMode, ::rtl::OUString aName )
+{
+ ::rtl::OUString temp;
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2;
+ ::com::sun::star::task::DocumentMSPasswordRequest
+ aDocumentMSPasswordRequest( temp,
+ temp2,
+ ::com::sun::star::task::InteractionClassification_QUERY,
+ nMode,
+ aName );
+
+ m_aRequest <<= aDocumentMSPasswordRequest;
+
+ m_pAbort = new MSAbortContinuation;
+ m_pPassword = new MSPasswordContinuation;
+
+ m_lContinuations.realloc( 2 );
+ m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pAbort );
+ m_lContinuations[1] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pPassword );
+}
+
+sal_Bool RequestMSDocumentPassword::isAbort()
+{
+ return m_pAbort->isSelected();
+}
+
+sal_Bool RequestMSDocumentPassword::isPassword()
+{
+ return m_pPassword->isSelected();
+}
+
+::rtl::OUString RequestMSDocumentPassword::getPassword()
+{
+ return m_pPassword->getPassword();
+}
+
+::com::sun::star::uno::Any SAL_CALL RequestMSDocumentPassword::getRequest()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return m_aRequest;
+}
+
+::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > >
+ SAL_CALL RequestMSDocumentPassword::getContinuations()
+ throw( ::com::sun::star::uno::RuntimeException )
+{
+ return m_lContinuations;
+}
+
+
diff --git a/svtools/source/misc1/makefile.mk b/svtools/source/misc1/makefile.mk
index 0d1e67fd9021..3ca57ff36f92 100644
--- a/svtools/source/misc1/makefile.mk
+++ b/svtools/source/misc1/makefile.mk
@@ -50,6 +50,7 @@ SLOFILES=\
$(EXCEPTIONSFILES) \
$(SLO)$/adrparse.obj \
$(SLO)$/docpasswdrequest.obj \
+ $(SLO)$/docmspasswdrequest.obj \
$(SLO)$/filenotation.obj \
$(SLO)$/inethist.obj \
$(SLO)$/inettype.obj \
diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx
index 125d134cd3fd..337400c08713 100644
--- a/toolkit/source/awt/vclxwindow.cxx
+++ b/toolkit/source/awt/vclxwindow.cxx
@@ -2537,7 +2537,7 @@ void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno:
vcl::PDFExtOutDevData* pPDFExport = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData());
bool bDrawSimple = ( pDev->GetOutDevType() == OUTDEV_PRINTER )
|| ( pDev->GetOutDevViewType() == OUTDEV_VIEWTYPE_PRINTPREVIEW )
- || ( pPDFExport && ! pPDFExport->GetIsExportFormFields() );
+ || ( pPDFExport != NULL );
if ( bDrawSimple )
{
pWindow->Draw( pDev, aP, aSz, WINDOW_DRAW_NOCONTROLS );
diff --git a/tools/bootstrp/md5.cxx b/tools/bootstrp/md5.cxx
index bca89725fac2..a234f278cc9d 100644
--- a/tools/bootstrp/md5.cxx
+++ b/tools/bootstrp/md5.cxx
@@ -44,8 +44,62 @@
#define FILE_OPEN_READ "r"
#endif
+// Extended calc_md5_checksum to recognize Windows executables and libraries. To
+// create the same md5 checksum for a (code/data) identical file it ignores a different
+// date and header checksum. Please see crashrep/source/win32/soreport.cpp
+// where the same method is also used. The crash reporter uses the MD5
+// checksums to transfer them to the crash database. You have to make sure that both
+// methods use the same algorithm otherwise there could be problems with stack reports.
+
+void normalize_pe_image(sal_uInt8* buffer, size_t nBufferSize)
+{
+ const int OFFSET_PE_OFFSET = 0x3c;
+ const int OFFSET_COFF_TIMEDATESTAMP = 4;
+ const int PE_SIGNATURE_SIZE = 4;
+ const int COFFHEADER_SIZE = 20;
+ const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64;
+
+ // Check the header part of the file buffer
+ if (buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z'))
+ {
+ unsigned long PEHeaderOffset = (long)buffer[OFFSET_PE_OFFSET];
+ if (PEHeaderOffset < nBufferSize-4)
+ {
+ if ( buffer[PEHeaderOffset+0] == sal_uInt8('P') &&
+ buffer[PEHeaderOffset+1] == sal_uInt8('E') &&
+ buffer[PEHeaderOffset+2] == 0 &&
+ buffer[PEHeaderOffset+3] == 0 )
+ {
+ PEHeaderOffset += PE_SIGNATURE_SIZE;
+ if (PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP < nBufferSize-4)
+ {
+ // Set timedatestamp and checksum fields to a normalized
+ // value to enforce the same MD5 checksum for identical
+ // Windows executables/libraries.
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+0] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+1] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+2] = 0;
+ buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+3] = 0;
+ }
+
+ if (PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM < nBufferSize-4)
+ {
+ // Set checksum to a normalized value
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+1] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+2] = 0;
+ buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+3] = 0;
+ }
+ }
+ }
+ }
+}
+
rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum )
{
+ const size_t BUFFER_SIZE = 0x1000;
+ const size_t MINIMAL_SIZE = 512;
+
sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5];
rtlDigestError error = rtl_Digest_E_None;
@@ -58,11 +112,19 @@ rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum )
if ( digest )
{
size_t nBytesRead;
- sal_uInt8 buffer[0x1000];
+ sal_uInt8 buffer[BUFFER_SIZE];
+ bool bHeader(true);
while ( rtl_Digest_E_None == error &&
0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
{
+ if (bHeader)
+ {
+ bHeader = false;
+ if (nBytesRead >= MINIMAL_SIZE && buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z') )
+ normalize_pe_image(buffer, nBytesRead);
+ }
+
error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
}
diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx
index e3484aee4e2d..2aff0d734bf6 100644
--- a/tools/source/fsys/urlobj.cxx
+++ b/tools/source/fsys/urlobj.cxx
@@ -1523,8 +1523,15 @@ bool INetURLObject::convertRelToAbs(rtl::OUString const & rTheRelURIRef,
else if (pEnd - q >= 2 && q[0] == '\\' && q[1] == '\\')
{
q += 2;
- if (scanDomain(q, pEnd) > 0 && (q == pEnd || *q == '\\'))
+ sal_Int32 n = rtl_ustr_indexOfChar_WithLength(
+ q, pEnd - q, '\\');
+ sal_Unicode const * qe = n == -1 ? pEnd : q + n;
+ if (parseHostOrNetBiosName(
+ q, qe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW,
+ true, NULL))
+ {
bFSys = true; // 1st
+ }
}
if (bFSys)
{
diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx
index 542297eb4bd6..a232f8ebdd93 100644
--- a/tools/workben/urltest.cxx
+++ b/tools/workben/urltest.cxx
@@ -799,6 +799,25 @@ main()
bSuccess = false;
}
}
+ {
+ bool bWasAbsolute;
+ if (!rtl::OUString(INetURLObject(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "file:///"))).
+ smartRel2Abs(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "\\\\unc_host\\path")),
+ bWasAbsolute).
+ GetMainURL(INetURLObject::NO_DECODE)).
+ equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("file://unc_host/path"))
+ || !bWasAbsolute)
+ {
+ printf("BAD smartRel2Abs(\"\\\\unc_host\\path\")\n");
+ bSuccess = false;
+ }
+ }
}
if (true)
diff --git a/transex3/scripts/localize.pl b/transex3/scripts/localize.pl
index 5fd591fc4e7e..10e8124027b1 100755
--- a/transex3/scripts/localize.pl
+++ b/transex3/scripts/localize.pl
@@ -103,7 +103,15 @@ if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) {
$DELIMITER = "/";
}
-my $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$ENV{UPDMINOREXT}.$DELIMITER ;
+my $binpath = '';
+if( defined $ENV{UPDMINOREXT} )
+{
+ $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$ENV{UPDMINOREXT}.$DELIMITER ;
+}
+else
+{
+ $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$DELIMITER ;
+}
#%sl_modules = fetch_sourcelanguage_dirlist();
diff --git a/unotools/inc/unotools/confignode.hxx b/unotools/inc/unotools/confignode.hxx
index a50025a6ab50..580274004e1a 100644
--- a/unotools/inc/unotools/confignode.hxx
+++ b/unotools/inc/unotools/confignode.hxx
@@ -86,7 +86,7 @@ namespace utl
const OConfigurationNode& operator=(const OConfigurationNode& _rSource);
/// dtor
- ~OConfigurationNode();
+ ~OConfigurationNode() {}
/** open a sub node
@param _rPath access path of the to-be-opened sub node. May be a hierarchical path.
diff --git a/unotools/source/config/confignode.cxx b/unotools/source/config/confignode.cxx
index a5114320f4a5..9ba3f642c328 100644
--- a/unotools/source/config/confignode.cxx
+++ b/unotools/source/config/confignode.cxx
@@ -130,11 +130,6 @@ namespace utl
}
//------------------------------------------------------------------------
- OConfigurationNode::~OConfigurationNode()
- {
- }
-
- //------------------------------------------------------------------------
void OConfigurationNode::_disposing( const EventObject& _rSource )
{
Reference< XComponent > xDisposingSource(_rSource.Source, UNO_QUERY);
diff --git a/vcl/aqua/inc/vclnsapp.h b/vcl/aqua/inc/vclnsapp.h
index a5c339c238bd..fc637ff75a31 100755
--- a/vcl/aqua/inc/vclnsapp.h
+++ b/vcl/aqua/inc/vclnsapp.h
@@ -59,7 +59,6 @@
-(void)scrollbarSettingsChanged: (NSNotification*) pNotification;
-(void)addFallbackMenuItem: (NSMenuItem*)pNewItem;
-(void)removeFallbackMenuItem: (NSMenuItem*)pOldItem;
--(void)getSystemVersionMajor:(unsigned *)major minor:(unsigned *)minor bugFix:(unsigned *)bugFix;
-(void)addDockMenuItem: (NSMenuItem*)pNewItem;
-(void)applicationWillBecomeActive: (NSNotification *)pNotification;
-(void)applicationWillResignActive: (NSNotification *)pNotification;
diff --git a/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm b/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm
index 53472e6ae34d..e521e7362323 100644
--- a/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm
+++ b/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm
@@ -249,6 +249,8 @@ using namespace ::rtl;
// empty
} catch ( IndexOutOfBoundsException & e ) {
// empty
+ } catch ( RuntimeException& ) {
+ // at least don't crash
}
return string;
}
diff --git a/vcl/aqua/source/a11y/aqua11yutil.mm b/vcl/aqua/source/a11y/aqua11yutil.mm
index 6d12fbee7a91..44f95169ca68 100644
--- a/vcl/aqua/source/a11y/aqua11yutil.mm
+++ b/vcl/aqua/source/a11y/aqua11yutil.mm
@@ -51,7 +51,7 @@ using namespace ::com::sun::star::awt;
+(Point)nsPointToVclPoint:(NSValue *)nsPoint {
// VCL coordinates are in upper-left-notation, Cocoa likes it the Cartesian way (lower-left)
NSRect screenRect = [ [ NSScreen mainScreen ] frame ];
- return Point ( [ nsPoint pointValue ].x, screenRect.size.height - [ nsPoint pointValue ].y );
+ return Point ( static_cast<long>([ nsPoint pointValue ].x), static_cast<long>(screenRect.size.height - [ nsPoint pointValue ].y) );
}
@end
diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm b/vcl/aqua/source/a11y/aqua11ywrapper.mm
index d6f99c7020d6..99bcbd20f698 100644
--- a/vcl/aqua/source/a11y/aqua11ywrapper.mm
+++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm
@@ -728,9 +728,15 @@ static MacOSBOOL isPopupMenuOpen = NO;
if ( nativeSubrole != nil && ! [ nativeSubrole isEqualToString: @"" ] ) {
[ attributeNames addObject: NSAccessibilitySubroleAttribute ];
}
+ try
+ {
if ( [ self accessibleContext ] -> getAccessibleChildCount() > 0 ) {
[ attributeNames addObject: NSAccessibilityChildrenAttribute ];
}
+ }
+ catch( DisposedException& ) {}
+ catch( RuntimeException& ) {}
+
if ( title != nil && ! [ title isEqualToString: @"" ] ) {
[ attributeNames addObject: NSAccessibilityTitleAttribute ];
}
@@ -986,7 +992,7 @@ Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAcces
}
Reference < XAccessibleContext > hitChild;
NSRect screenRect = [ [ NSScreen mainScreen ] frame ];
- Point hitPoint ( point.x , screenRect.size.height - point.y );
+ Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) );
// check child windows first
NSWindow * window = (NSWindow *) [ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ];
NSArray * childWindows = [ window childWindows ];
diff --git a/vcl/aqua/source/app/saldata.cxx b/vcl/aqua/source/app/saldata.cxx
index a70854306122..180f6a106459 100644
--- a/vcl/aqua/source/app/saldata.cxx
+++ b/vcl/aqua/source/app/saldata.cxx
@@ -93,7 +93,7 @@ SalData::~SalData()
}
osl_destroyThreadKey( s_aAutoReleaseKey );
- s_aAutoReleaseKey = NULL;
+ s_aAutoReleaseKey = 0;
}
if ( mpMainController )
[mpMainController release];
diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx
index b9d66d1e02d3..71bfb7953187 100644
--- a/vcl/aqua/source/app/salinst.cxx
+++ b/vcl/aqua/source/app/salinst.cxx
@@ -140,10 +140,6 @@ bool AquaSalInstance::isOnCommandLine( const rtl::OUString& rArg )
// returns an NSAutoreleasePool that must be released when the event loop begins
static void initNSApp()
{
- SInt32 major = NULL;
- SInt32 minor = NULL;
- SInt32 bugFix = NULL;
-
// create our cocoa NSApplication
[VCL_NSApplication sharedApplication];
@@ -176,7 +172,17 @@ static void initNSApp()
object: nil ];
// get System Version and store the value in GetSalData()->mnSystemVersion
- [NSApp getSystemVersionMajor: (unsigned int *)major minor:(unsigned int *)minor bugFix:(unsigned int *)bugFix ];
+ OSErr err = noErr;
+ SInt32 systemVersion = VER_TIGER; // Initialize with minimal requirement
+ if( (err = Gestalt(gestaltSystemVersion, &systemVersion)) == noErr )
+ {
+ GetSalData()->mnSystemVersion = systemVersion;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "System Version %x\n", (unsigned int)systemVersion);
+#endif
+ }
+ else
+ NSLog(@"Unable to obtain system version: %ld", (long)err);
// Initialize Apple Remote
GetSalData()->mpMainController = [[MainController alloc] init];
diff --git a/vcl/aqua/source/app/salsys.cxx b/vcl/aqua/source/app/salsys.cxx
index 28acb47ccade..78b5defe6dd9 100644
--- a/vcl/aqua/source/app/salsys.cxx
+++ b/vcl/aqua/source/app/salsys.cxx
@@ -75,8 +75,8 @@ Rectangle AquaSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen )
if( pScreen )
{
NSRect aFrame = [pScreen frame];
- aRet = Rectangle( Point( aFrame.origin.x, aFrame.origin.y ),
- Size( aFrame.size.width, aFrame.size.height ) );
+ aRet = Rectangle( Point( static_cast<long int>(aFrame.origin.x), static_cast<long int>(aFrame.origin.y) ),
+ Size( static_cast<long int>(aFrame.size.width), static_cast<long int>(aFrame.size.height) ) );
}
return aRet;
}
@@ -94,8 +94,8 @@ Rectangle AquaSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen )
if( pScreen )
{
NSRect aFrame = [pScreen visibleFrame];
- aRet = Rectangle( Point( aFrame.origin.x, aFrame.origin.y ),
- Size( aFrame.size.width, aFrame.size.height ) );
+ aRet = Rectangle( Point( static_cast<long int>(aFrame.origin.x), static_cast<long int>(aFrame.origin.y) ),
+ Size( static_cast<long int>(aFrame.size.width), static_cast<long int>(aFrame.size.height) ) );
}
return aRet;
}
diff --git a/vcl/aqua/source/app/vclnsapp.mm b/vcl/aqua/source/app/vclnsapp.mm
index 4ad5e7ff9271..43d44c709c12 100755
--- a/vcl/aqua/source/app/vclnsapp.mm
+++ b/vcl/aqua/source/app/vclnsapp.mm
@@ -105,44 +105,33 @@
}
}
- /* #i89611#
- Cmd-Option-Space is for some reason not consumed by the menubar,
- but also not by the input method (like e.g. Cmd-Space) and stays
- without function.
-
- However MOD1 + MOD2 combinations are not used throughout OOo code
- since they tend to clash with system shortcuts on all platforms so
- we can skip this case here.
- */
// get information whether the event was handled; keyDown returns nothing
GetSalData()->maKeyEventAnswer[ pEvent ] = false;
bool bHandled = false;
- if( nModMask != (NSCommandKeyMask | NSAlternateKeyMask) )
+ // dispatch to view directly to avoid the key event being consumed by the menubar
+ // popup windows do not get the focus, so they don't get these either
+ // simplest would be dispatch this to the key window always if it is without parent
+ // however e.g. in document we want the menu shortcut if e.g. the stylist has focus
+ if( pFrame->mpParent && (pFrame->mnStyle & SAL_FRAME_STYLE_FLOAT) == 0 )
{
- // dispatch to view directly to avoid the key event being consumed by the menubar
- // popup windows do not get the focus, so they don't get these either
- // simplest would be dispatch this to the key window always if it is without parent
- // however e.g. in document we want the menu shortcut if e.g. the stylist has focus
- if( pFrame->mpParent && (pFrame->mnStyle & SAL_FRAME_STYLE_FLOAT) == 0 )
- {
- [[pKeyWin contentView] keyDown: pEvent];
- bHandled = GetSalData()->maKeyEventAnswer[ pEvent ];
- }
-
- // see whether the main menu consumes this event
- // if not, we want to dispatch it ourselves. Unless we do this "trick"
- // the main menu just beeps for an unknown or disabled key equivalent
- // and swallows the event wholesale
- NSMenu* pMainMenu = [NSApp mainMenu];
- if( ! bHandled && (pMainMenu == 0 || ! [pMainMenu performKeyEquivalent: pEvent]) )
- {
- [[pKeyWin contentView] keyDown: pEvent];
- bHandled = GetSalData()->maKeyEventAnswer[ pEvent ];
- }
- else
- bHandled = true; // event handled already or main menu just handled it
+ [[pKeyWin contentView] keyDown: pEvent];
+ bHandled = GetSalData()->maKeyEventAnswer[ pEvent ];
+ }
+
+ // see whether the main menu consumes this event
+ // if not, we want to dispatch it ourselves. Unless we do this "trick"
+ // the main menu just beeps for an unknown or disabled key equivalent
+ // and swallows the event wholesale
+ NSMenu* pMainMenu = [NSApp mainMenu];
+ if( ! bHandled && (pMainMenu == 0 || ! [pMainMenu performKeyEquivalent: pEvent]) )
+ {
+ [[pKeyWin contentView] keyDown: pEvent];
+ bHandled = GetSalData()->maKeyEventAnswer[ pEvent ];
}
+ else
+ bHandled = true; // event handled already or main menu just handled it
+
GetSalData()->maKeyEventAnswer.erase( pEvent );
if( bHandled )
return;
@@ -374,26 +363,6 @@
AquaSalMenu::removeFallbackMenuItem( pItem );
}
-- (void)getSystemVersionMajor:(unsigned *)major
- minor:(unsigned *)minor
- bugFix:(unsigned *)bugFix
-{
- OSErr err;
- SInt32 systemVersion = VER_TIGER; // Initialize with minimal requirement
- if ((err = Gestalt(gestaltSystemVersion, &systemVersion)) == noErr)
- {
- GetSalData()->mnSystemVersion = systemVersion;
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "System Version %x\n", (unsigned int)systemVersion);
- fprintf( stderr, "Stored System Version %x\n", (unsigned int)GetSalData()->mnSystemVersion);
-#endif
- }
- else
- NSLog(@"Unable to obtain system version: %ld", (long)err);
-
- return;
-}
-
-(void)addDockMenuItem: (NSMenuItem*)pNewItem
{
NSMenu* pDock = AquaSalInstance::GetDynamicDockMenu();
diff --git a/vcl/aqua/source/gdi/aquaprintview.mm b/vcl/aqua/source/gdi/aquaprintview.mm
index 6099fbaed741..ba139da5f5a4 100755
--- a/vcl/aqua/source/gdi/aquaprintview.mm
+++ b/vcl/aqua/source/gdi/aquaprintview.mm
@@ -58,6 +58,9 @@
{
NSSize aPaperSize = [mpInfoPrinter->getPrintInfo() paperSize];
int nWidth = (int)aPaperSize.width;
+ // #i101108# sanity check
+ if( nWidth < 1 )
+ nWidth = 1;
NSRect aRect = { { page % nWidth, page / nWidth }, aPaperSize };
return aRect;
}
@@ -71,7 +74,7 @@
-(void)drawRect: (NSRect)rect
{
NSPoint aPoint = [self locationOfPrintRect: rect];
- mpInfoPrinter->setStartPageOffset( rect.origin.x, rect.origin.y );
+ mpInfoPrinter->setStartPageOffset( static_cast<int>(rect.origin.x), static_cast<int>(rect.origin.y) );
NSSize aPaperSize = [mpInfoPrinter->getPrintInfo() paperSize];
int nPage = (int)(aPaperSize.width * rect.origin.y + rect.origin.x);
diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx
index 98700feba39d..7ecef01cf0d5 100755
--- a/vcl/aqua/source/gdi/salatslayout.cxx
+++ b/vcl/aqua/source/gdi/salatslayout.cxx
@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
- * $RCSfile: salatslayout.cxx,v $
- * $Revision: 1.12 $
- *
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -431,8 +428,8 @@ void ATSLayout::DrawText( SalGraphics& rGraphics ) const
if( rAquaGraphics.mnATSUIRotation != 0 )
{
const double fRadians = rAquaGraphics.mnATSUIRotation * (M_PI/0xB40000);
- nXOfsFixed = +rSubPortion.mnXOffset * cos( fRadians );
- nYOfsFixed = +rSubPortion.mnXOffset * sin( fRadians );
+ nXOfsFixed = static_cast<Fixed>(static_cast<double>(+rSubPortion.mnXOffset) * cos( fRadians ));
+ nYOfsFixed = static_cast<Fixed>(static_cast<double>(+rSubPortion.mnXOffset) * sin( fRadians ));
}
// draw sub-portions
@@ -745,6 +742,8 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons
// get a quick overview on what could fit
const long nPixelWidth = (nMaxWidth - (nCharExtra * mnCharCount)) / nFactor;
+ if( nPixelWidth <= 0 )
+ return mnMinCharPos;
// check assumptions
DBG_ASSERT( !mnTrailingSpaceWidth, "ATSLayout::GetTextBreak() with nTSW!=0" );
diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx
index 3ee54afe2fba..f8410a47dfd6 100644
--- a/vcl/aqua/source/gdi/salgdi.cxx
+++ b/vcl/aqua/source/gdi/salgdi.cxx
@@ -974,6 +974,11 @@ bool AquaSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine,
if( rLineWidths.getX() != rLineWidths.getY() )
return false;
+ // #i101491# Aqua does not support B2DLINEJOIN_NONE; return false to use
+ // the fallback (own geometry preparation)
+ if(basegfx::B2DLINEJOIN_NONE == eLineJoin)
+ return false;
+
// setup line attributes
CGLineJoin aCGLineJoin = kCGLineJoinMiter;
switch( eLineJoin ) {
diff --git a/vcl/aqua/source/gdi/salgdiutils.cxx b/vcl/aqua/source/gdi/salgdiutils.cxx
index 066268791b11..99a1629006d2 100755
--- a/vcl/aqua/source/gdi/salgdiutils.cxx
+++ b/vcl/aqua/source/gdi/salgdiutils.cxx
@@ -102,8 +102,8 @@ void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContex
else
{
const CGSize aSize = CGLayerGetSize( mxLayer );
- mnWidth = aSize.width;
- mnHeight = aSize.height;
+ mnWidth = static_cast<int>(aSize.width);
+ mnHeight = static_cast<int>(aSize.height);
}
// prepare graphics for drawing
@@ -219,7 +219,10 @@ void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeigh
{
// update a little more around the designated rectangle
// this helps with antialiased rendering
- const Rectangle aVclRect( Point( lX-1, lY-1 ), Size( lWidth+2, lHeight+2) );
+ const Rectangle aVclRect(Point(static_cast<long int>(lX-1),
+ static_cast<long int>(lY-1) ),
+ Size( static_cast<long int>(lWidth+2),
+ static_cast<long int>(lHeight+2) ) );
mpFrame->maInvalidRect.Union( aVclRect );
}
}
diff --git a/vcl/aqua/source/gdi/salnativewidgets.cxx b/vcl/aqua/source/gdi/salnativewidgets.cxx
index 9f2c7c4fa3a7..6cd4e78a2d1a 100644
--- a/vcl/aqua/source/gdi/salnativewidgets.cxx
+++ b/vcl/aqua/source/gdi/salnativewidgets.cxx
@@ -612,7 +612,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType,
aPushInfo.animation.time.start = 0;
aPushInfo.animation.time.current = 0;
PushButtonValue* pPBVal = (PushButtonValue*)aValue.getOptionalVal();
- int nPaintHeight = rc.size.height;
+ int nPaintHeight = static_cast<int>(rc.size.height);
if( pPBVal && pPBVal->mbBevelButton )
{
@@ -1162,8 +1162,10 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType,
if( mxClipPath )
aRect = CGPathGetBoundingBox( mxClipPath );
if( aRect.size.width != 0 && aRect.size.height != 0 )
- buttonRect.Intersection( Rectangle( Point( aRect.origin.x, aRect.origin.y ),
- Size( aRect.size.width, aRect.size.height ) ) );
+ buttonRect.Intersection( Rectangle( Point( static_cast<long int>(aRect.origin.x),
+ static_cast<long int>(aRect.origin.y) ),
+ Size( static_cast<long int>(aRect.size.width),
+ static_cast<long int>(aRect.size.height) ) ) );
}
RefreshRect( buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight() );
diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx
index 5db6ad30bb8b..b9a1f4ef7748 100644
--- a/vcl/aqua/source/gdi/salprn.cxx
+++ b/vcl/aqua/source/gdi/salprn.cxx
@@ -310,8 +310,12 @@ BOOL AquaSalInfoPrinter::SetData( ULONG i_nFlags, ImplJobSetup* io_pSetupData )
double width = 0, height = 0;
if( io_pSetupData->mePaperFormat == PAPER_USER )
{
- width = TenMuToPt( io_pSetupData->mnPaperWidth );
- height = TenMuToPt( io_pSetupData->mnPaperHeight );
+ // #i101108# sanity check
+ if( io_pSetupData->mnPaperWidth && io_pSetupData->mnPaperHeight )
+ {
+ width = TenMuToPt( io_pSetupData->mnPaperWidth );
+ height = TenMuToPt( io_pSetupData->mnPaperHeight );
+ }
}
else
getPaperSize( width, height, io_pSetupData->mePaperFormat );
diff --git a/vcl/aqua/source/gdi/salvd.cxx b/vcl/aqua/source/gdi/salvd.cxx
index d7690e4e38bd..4d25d5d8b63b 100644
--- a/vcl/aqua/source/gdi/salvd.cxx
+++ b/vcl/aqua/source/gdi/salvd.cxx
@@ -228,8 +228,8 @@ void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
if( mxLayer )
{
const CGSize aSize = CGLayerGetSize( mxLayer );
- rWidth = aSize.width;
- rHeight = aSize.height;
+ rWidth = static_cast<long>(aSize.width);
+ rHeight = static_cast<long>(aSize.height);
}
else
{
diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx
index 8c40e1acfe66..9c713ea26a52 100644
--- a/vcl/aqua/source/window/salframe.cxx
+++ b/vcl/aqua/source/window/salframe.cxx
@@ -1182,7 +1182,7 @@ void AquaSalFrame::UpdateSettings( AllSettings& rSettings )
getAppleScrollBarVariant();
// set scrollbar size
- aStyleSettings.SetScrollBarSize( [NSScroller scrollerWidth] );
+ aStyleSettings.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidth]) );
// images in menus false for MacOSX
aStyleSettings.SetUseImagesInMenus( false );
@@ -1203,7 +1203,15 @@ const SystemEnvData* AquaSalFrame::GetSystemData() const
void AquaSalFrame::Beep( SoundType eSoundType )
{
- NSBeep();
+ switch( eSoundType )
+ {
+ case SOUND_DISABLE:
+ // don't beep
+ break;
+ default:
+ NSBeep();
+ break;
+ }
}
// -----------------------------------------------------------------------
@@ -1240,7 +1248,7 @@ void AquaSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, USHOR
if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 )
nX = mpParent->maGeometry.nWidth - nWidth-1 - nX;
else
- nX = mpParent->maGeometry.nWidth - aContentRect.size.width-1 - nX;
+ nX = mpParent->maGeometry.nWidth - static_cast<long int>( aContentRect.size.width-1) - nX;
}
NSRect aParentFrameRect = [mpParent->mpWindow frame];
aParentContentRect = [NSWindow contentRectForFrameRect: aParentFrameRect styleMask: mpParent->mnStyleMask];
diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm
index a6213ca7b64d..c7facd8c6c09 100755
--- a/vcl/aqua/source/window/salframeview.mm
+++ b/vcl/aqua/source/window/salframeview.mm
@@ -841,6 +841,16 @@ private:
if( pUnmodifiedString && [pUnmodifiedString length] == 1 )
{
+ /* #i103102# key events with command and alternate don't make it through
+ interpretKeyEvents (why ?). Try to dispatch them here first,
+ if not successful continue normally
+ */
+ if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask))
+ == (NSAlternateKeyMask | NSCommandKeyMask) )
+ {
+ if( [self sendSingleCharacter: mpLastEvent] )
+ return YES;
+ }
unichar keyChar = [pUnmodifiedString characterAtIndex: 0];
USHORT nKeyCode = ImplMapCharCode( keyChar );
diff --git a/vcl/aqua/source/window/salmenu.cxx b/vcl/aqua/source/window/salmenu.cxx
index 4fafbbdbb4cf..5c838701933c 100644
--- a/vcl/aqua/source/window/salmenu.cxx
+++ b/vcl/aqua/source/window/salmenu.cxx
@@ -651,11 +651,9 @@ void AquaSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSMI, const Image& r
NSImage* pImage = CreateNSImage( rImage );
+ [pSalMenuItem->mpMenuItem setImage: pImage];
if( pImage )
- {
- [pSalMenuItem->mpMenuItem setImage: pImage];
[pImage release];
- }
}
void AquaSalMenu::SetItemText( unsigned i_nPos, SalMenuItem* i_pSalMenuItem, const XubString& i_rText )
@@ -894,7 +892,13 @@ Rectangle AquaSalMenu::GetMenuBarButtonRectPixel( USHORT i_nItemId, SalFrame* i_
aRect.origin.x -= i_pReferenceFrame->maGeometry.nX;
aRect.origin.y -= i_pReferenceFrame->maGeometry.nY + aRect.size.height;
- return Rectangle( Point( aRect.origin.x, aRect.origin.y ), Size( aRect.size.width, aRect.size.height ) );
+ return Rectangle( Point(static_cast<long int>(aRect.origin.x),
+ static_cast<long int>(aRect.origin.y)
+ ),
+ Size( static_cast<long int>(aRect.size.width),
+ static_cast<long int>(aRect.size.height)
+ )
+ );
}
// =======================================================================
diff --git a/vcl/inc/sft.h b/vcl/inc/sft.h
deleted file mode 100644
index efda0903afc5..000000000000
--- a/vcl/inc/sft.h
+++ /dev/null
@@ -1,641 +0,0 @@
-/*************************************************************************
- *
- * 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: sft.h,v $
- * $Revision: 1.21 $
- *
- * 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.
- *
- ************************************************************************/
-
-/* $Id: sft.h,v 1.21 2008-06-25 14:20:49 kz Exp $ */
-
-/**
-
- *
- * @file sft.h
- * @brief Sun Font Tools
- * @author Alexander Gelfenbain
- */
-
-/*
- * If NO_MAPPERS is defined, MapChar() and MapString() and consequently GetTTSimpleCharMetrics()
- * don't get compiled in. This is done to avoid including a large chunk of code (TranslateXY() from
- * xlat.c in the projects that don't require it.
- *
- * If NO_TYPE3 is defined CreateT3FromTTGlyphs() does not get compiled in.
- * If NO_TYPE42 is defined Type42-related code is excluded
- * If NO_TTCR is defined TrueType creation related code is excluded\
- * If NO_LIST is defined list.h and piblic functions that use it don't get compiled
- */
-
-/*
- * Generated fonts contain an XUID entry in the form of:
- *
- * 103 0 T C1 N C2 C3
- *
- * 103 - Sun's Adobe assigned XUID number. Contact person: Alexander Gelfenbain <gelf@eng.sun.com>
- *
- * T - font type. 0: Type 3, 1: Type 42
- * C1 - CRC-32 of the entire source TrueType font
- * N - number of glyphs in the subset
- * C2 - CRC-32 of the array of glyph IDs used to generate the subset
- * C3 - CRC-32 of the array of encoding numbers used to generate the subset
- *
- */
-
-
-#ifndef __SUBFONT_H
-#define __SUBFONT_H
-
-#ifdef UNX
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-#include <stdio.h>
-
-#include <sal/types.h>
-
-#ifndef NO_LIST
-#include "list.h"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*@{*/
-#ifndef __cplusplus
-#define false 0 /**< standard false value */
-#define true 1 /**< standard true value */
-#endif
-/*@}*/
-
-/*@{*/
- typedef sal_Int16 F2Dot14; /**< fixed: 2.14 */
- typedef sal_Int32 F16Dot16; /**< fixed: 16.16 */
-/*@}*/
-
- typedef struct {
- sal_uInt16 s;
- sal_uInt16 d;
- } sal_uInt16pair;
-
-/** Return value of OpenTTFont() and CreateT3FromTTGlyphs() */
- enum SFErrCodes {
- SF_OK, /**< no error */
- SF_BADFILE, /**< file not found */
- SF_FILEIO, /**< file I/O error */
- SF_MEMORY, /**< memory allocation error */
- SF_GLYPHNUM, /**< incorrect number of glyphs */
- SF_BADARG, /**< incorrect arguments */
- SF_TTFORMAT, /**< incorrect TrueType font format */
- SF_TABLEFORMAT, /**< incorrect format of a TrueType table */
- SF_FONTNO /**< incorrect logical font number of a TTC font */
- };
-
-#ifndef FW_THIN /* WIN32 compilation would conflict */
-/** Value of the weight member of the TTGlobalFontInfo struct */
- enum WeightClass {
- FW_THIN = 100, /**< Thin */
- FW_EXTRALIGHT = 200, /**< Extra-light (Ultra-light) */
- FW_LIGHT = 300, /**< Light */
- FW_NORMAL = 400, /**< Normal (Regular) */
- FW_MEDIUM = 500, /**< Medium */
- FW_SEMIBOLD = 600, /**< Semi-bold (Demi-bold) */
- FW_BOLD = 700, /**< Bold */
- FW_EXTRABOLD = 800, /**< Extra-bold (Ultra-bold) */
- FW_BLACK = 900 /**< Black (Heavy) */
- };
-
-/** Value of the width member of the TTGlobalFontInfo struct */
-#ifndef OS2
- enum WidthClass {
- FWIDTH_ULTRA_CONDENSED = 1, /**< 50% of normal */
- FWIDTH_EXTRA_CONDENSED = 2, /**< 62.5% of normal */
- FWIDTH_CONDENSED = 3, /**< 75% of normal */
- FWIDTH_SEMI_CONDENSED = 4, /**< 87.5% of normal */
- FWIDTH_NORMAL = 5, /**< Medium, 100% */
- FWIDTH_SEMI_EXPANDED = 6, /**< 112.5% of normal */
- FWIDTH_EXPANDED = 7, /**< 125% of normal */
- FWIDTH_EXTRA_EXPANDED = 8, /**< 150% of normal */
- FWIDTH_ULTRA_EXPANDED = 9 /**< 200% of normal */
- };
-#endif // OS2
-#endif /* FW_THIN */
-
-/** Type of the 'kern' table, stored in _TrueTypeFont::kerntype */
- enum KernType {
- KT_NONE = 0, /**< no kern table */
- KT_APPLE_NEW = 1, /**< new Apple kern table */
- KT_MICROSOFT = 2 /**< Microsoft table */
- };
-
-/* Composite glyph flags definition */
- enum CompositeFlags {
- ARG_1_AND_2_ARE_WORDS = 1,
- ARGS_ARE_XY_VALUES = 1<<1,
- ROUND_XY_TO_GRID = 1<<2,
- WE_HAVE_A_SCALE = 1<<3,
- MORE_COMPONENTS = 1<<5,
- WE_HAVE_AN_X_AND_Y_SCALE = 1<<6,
- WE_HAVE_A_TWO_BY_TWO = 1<<7,
- WE_HAVE_INSTRUCTIONS = 1<<8,
- USE_MY_METRICS = 1<<9,
- OVERLAP_COMPOUND = 1<<10
- };
-
-#ifndef NO_TTCR
-/** Flags for TrueType generation */
- enum TTCreationFlags {
- TTCF_AutoName = 1, /**< Automatically generate a compact 'name' table.
- If this flag is not set, name table is generated
- either from an array of NameRecord structs passed as
- arguments or if the array is NULL, 'name' table
- of the generated TrueType file will be a copy
- of the name table of the original file.
- If this flag is set the array of NameRecord structs
- is ignored and a very compact 'name' table is automatically
- generated. */
-
- TTCF_IncludeOS2 = 2 /** If this flag is set OS/2 table from the original font will be
- copied to the subset */
- };
-#endif
-
-
-
-
-/** Structure used by GetTTSimpleGlyphMetrics() and GetTTSimpleCharMetrics() functions */
- typedef struct {
- sal_uInt16 adv; /**< advance width or height */
- sal_Int16 sb; /**< left or top sidebearing */
- } TTSimpleGlyphMetrics;
-
-
-
-/** Structure used by the TrueType Creator and GetRawGlyphData() */
-
- typedef struct {
- sal_uInt32 glyphID; /**< glyph ID */
- sal_uInt16 nbytes; /**< number of bytes in glyph data */
- sal_uInt8 *ptr; /**< pointer to glyph data */
- sal_uInt16 aw; /**< advance width */
- sal_Int16 lsb; /**< left sidebearing */
- sal_uInt16 compflag; /**< 0- if non-composite, 1- otherwise */
- sal_uInt16 npoints; /**< number of points */
- sal_uInt16 ncontours; /**< number of contours */
- /* */
- sal_uInt32 newID; /**< used internally by the TTCR */
- } GlyphData;
-
-/** Structure used by the TrueType Creator and CreateTTFromTTGlyphs() */
- typedef struct {
- sal_uInt16 platformID; /**< Platform ID */
- sal_uInt16 encodingID; /**< Platform-specific encoding ID */
- sal_uInt16 languageID; /**< Language ID */
- sal_uInt16 nameID; /**< Name ID */
- sal_uInt16 slen; /**< String length in bytes */
- sal_uInt8 *sptr; /**< Pointer to string data (not zero-terminated!) */
- } NameRecord;
-
-
-
-/** Return value of GetTTGlobalFontInfo() */
-
- typedef struct {
- char *family; /**< family name */
- sal_uInt16 *ufamily; /**< family name UCS2 */
- char *subfamily; /**< subfamily name */
- sal_uInt16 *usubfamily; /**< subfamily name UCS2 */
- char *psname; /**< PostScript name */
- sal_uInt16 macStyle; /**< macstyle bits from 'HEAD' table */
- int weight; /**< value of WeightClass or 0 if can't be determined */
- int width; /**< value of WidthClass or 0 if can't be determined */
- int pitch; /**< 0: proportianal font, otherwise: monospaced */
- int italicAngle; /**< in counter-clockwise degrees * 65536 */
- int xMin; /**< global bounding box: xMin */
- int yMin; /**< global bounding box: yMin */
- int xMax; /**< global bounding box: xMax */
- int yMax; /**< global bounding box: yMax */
- int ascender; /**< typographic ascent. */
- int descender; /**< typographic descent. */
- int linegap; /**< typographic line gap.\ Negative values are treated as
- zero in Win 3.1, System 6 and System 7. */
- int vascent; /**< typographic ascent for vertical writing mode */
- int vdescent; /**< typographic descent for vertical writing mode */
- int typoAscender; /**< OS/2 portable typographic ascender */
- int typoDescender; /**< OS/2 portable typographic descender */
- int typoLineGap; /**< OS/2 portable typographc line gap */
- int winAscent; /**< ascender metric for Windows */
- int winDescent; /**< descender metric for Windows */
- int symbolEncoded; /**< 1: MS symbol encoded 0: not symbol encoded */
- int rangeFlag; /**< if set to 1 Unicode Range flags are applicable */
- sal_uInt32 ur1; /**< bits 0 - 31 of Unicode Range flags */
- sal_uInt32 ur2; /**< bits 32 - 63 of Unicode Range flags */
- sal_uInt32 ur3; /**< bits 64 - 95 of Unicode Range flags */
- sal_uInt32 ur4; /**< bits 96 - 127 of Unicode Range flags */
- sal_uInt8 panose[10]; /**< PANOSE classification number */
- sal_uInt16 typeFlags; /**< type flags (copyright information) */
- } TTGlobalFontInfo;
-
-/** Structure used by KernGlyphs() */
- typedef struct {
- int x; /**< positive: right, negative: left */
- int y; /**< positive: up, negative: down */
- } KernData;
-
-
-/** ControlPoint structure used by GetTTGlyphPoints() */
- typedef struct {
- sal_uInt32 flags; /**< 00000000 00000000 e0000000 bbbbbbbb */
- /**< b - byte flags from the glyf array */
- /**< e == 0 - regular point */
- /**< e == 1 - end contour */
- sal_Int16 x; /**< X coordinate in EmSquare units */
- sal_Int16 y; /**< Y coordinate in EmSquare units */
- } ControlPoint;
-
- typedef struct _TrueTypeFont TrueTypeFont;
-
-/**
- * @defgroup sft Sun Font Tools Exported Functions
- */
-
-
-/**
- * Get the number of fonts contained in a TrueType collection
- * @param fname - file name
- * @return number of fonts or zero, if file is not a TTC file.
- * @ingroup sft
- */
- int CountTTCFonts(const char* fname);
-
-
-/**
- * TrueTypeFont constructor.
- * The font file has to be provided as a memory buffer and length
- * @param facenum - logical font number within a TTC file. This value is ignored
- * for TrueType fonts
- * @return value of SFErrCodes enum
- * @ingroup sft
- */
- int OpenTTFontBuffer(void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf); /*FOLD01*/
-#if !defined(WIN32) && !defined(OS2)
-/**
- * TrueTypeFont constructor.
- * Reads the font file and allocates the memory for the structure.
- * on WIN32 the font has to be provided as a memory buffer and length
- * @param facenum - logical font number within a TTC file. This value is ignored
- * for TrueType fonts
- * @return value of SFErrCodes enum
- * @ingroup sft
- */
- int OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf);
-#endif
-
-/**
- * TrueTypeFont destructor. Deallocates the memory.
- * @ingroup sft
- */
- void CloseTTFont(TrueTypeFont *);
-
-/**
- * Extracts TrueType control points, and stores them in an allocated array pointed to
- * by *pointArray. This function returns the number of extracted points.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param glyphID Glyph ID
- * @param pointArray Return value - address of the pointer to the first element of the array
- * of points allocated by the function
- * @return Returns the number of points in *pointArray or -1 if glyphID is
- * invalid.
- * @ingroup sft
- *
- */
- int GetTTGlyphPoints(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray);
-
-/**
- * Extracts raw glyph data from the 'glyf' table and returns it in an allocated
- * GlyphData structure.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param glyphID Glyph ID
- *
- * @return pointer to an allocated GlyphData structure or NULL if
- * glyphID is not present in the font
- * @ingroup sft
- *
- */
- GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, sal_uInt32 glyphID);
-
-#ifndef NO_LIST
-/**
- * For a specified glyph adds all component glyphs IDs to the list and
- * return their number. If the glyph is a single glyph it has one component
- * glyph (which is added to the list) and the function returns 1.
- * For a composite glyphs it returns the number of component glyphs
- * and adds all of them to the list.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param glyphID Glyph ID
- * @param glyphlist list of glyphs
- *
- * @return number of component glyphs
- * @ingroup sft
- *
- */
- int GetTTGlyphComponents(TrueTypeFont *ttf, sal_uInt32 glyphID, list glyphlist);
-#endif
-
-/**
- * Extracts all Name Records from the font and stores them in an allocated
- * array of NameRecord structs
- *
- * @param ttf pointer to the TrueTypeFont struct
- * @param nr pointer to the array of NameRecord structs
- *
- * @return number of NameRecord structs
- * @ingroup sft
- */
-
- int GetTTNameRecords(TrueTypeFont *ttf, NameRecord **nr);
-
-/**
- * Deallocates previously allocated array of NameRecords.
- *
- * @param nr array of NameRecord structs
- * @param n number of elements in the array
- *
- * @ingroup sft
- */
- void DisposeNameRecords(NameRecord* nr, int n);
-
-
-#ifndef NO_TYPE3
-/**
- * Generates a new PostScript Type 3 font and dumps it to <b>outf</b> file.
- * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
- * @param ttf pointer to the TrueTypeFont structure
- * @param outf the resulting font is written to this stream
- * @param fname font name for the new font. If it is NULL the PostScript name of the
- * original font will be used
- * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf
- * @param encoding array of encoding values. encoding[i] specifies the position of the glyph
- * glyphArray[i] in the encoding vector of the resulting Type3 font
- * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding
- * @param wmode writing mode for the output file: 0 - horizontal, 1 - vertical
- * @return return the value of SFErrCodes enum
- * @see SFErrCodes
- * @ingroup sft
- *
- */
- int CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname, sal_uInt16 *glyphArray, sal_uInt8 *encoding, int nGlyphs, int wmode);
-#endif
-
-#ifndef NO_TTCR
-/**
- * Generates a new TrueType font and dumps it to <b>outf</b> file.
- * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
- * @param ttf pointer to the TrueTypeFont structure
- * @param fname file name for the output TrueType font file
- * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf. The first
- * element of this array has to be glyph 0 (default glyph)
- * @param encoding array of encoding values. encoding[i] specifies character code for
- * the glyphID glyphArray[i]. Character code 0 usually points to a default
- * glyph (glyphID 0)
- * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding
- * @param nNameRecs number of NameRecords for the font, if 0 the name table from the
- * original font will be used
- * @param nr array of NameRecords
- * @param flags or'ed TTCreationFlags
- * @return return the value of SFErrCodes enum
- * @see SFErrCodes
- * @ingroup sft
- *
- */
- int CreateTTFromTTGlyphs(TrueTypeFont *ttf,
- const char *fname,
- sal_uInt16 *glyphArray,
- sal_uInt8 *encoding,
- int nGlyphs,
- int nNameRecs,
- NameRecord *nr,
- sal_uInt32 flags);
-#endif
-
-#ifndef NO_TYPE42
-/**
- * Generates a new PostScript Type42 font and dumps it to <b>outf</b> file.
- * This functions subsititues glyph 0 for all glyphIDs that are not found in the font.
- * @param ttf pointer to the TrueTypeFont structure
- * @param outf output stream for a resulting font
- * @param psname PostScript name of the resulting font
- * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf. The first
- * element of this array has to be glyph 0 (default glyph)
- * @param encoding array of encoding values. encoding[i] specifies character code for
- * the glyphID glyphArray[i]. Character code 0 usually points to a default
- * glyph (glyphID 0)
- * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding
- * @return SF_OK - no errors
- * SF_GLYPHNUM - too many glyphs (> 255)
- * SF_TTFORMAT - corrupted TrueType fonts
- *
- * @see SFErrCodes
- * @ingroup sft
- *
- */
- int CreateT42FromTTGlyphs(TrueTypeFont *ttf,
- FILE *outf,
- const char *psname,
- sal_uInt16 *glyphArray,
- sal_uInt8 *encoding,
- int nGlyphs);
-#endif
-
-
-/**
- * Queries glyph metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf
- * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding
- * @param mode writing mode: 0 - horizontal, 1 - vertical
- * @ingroup sft
- *
- */
- TTSimpleGlyphMetrics *GetTTSimpleGlyphMetrics(TrueTypeFont *ttf, sal_uInt16 *glyphArray, int nGlyphs, int mode);
-
-#ifndef NO_MAPPERS
-/**
- * Queries glyph metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it.
- * This function behaves just like GetTTSimpleGlyphMetrics() but it takes a range of Unicode
- * characters instead of an array of glyphs.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param firstChar Unicode value of the first character in the range
- * @param nChars number of Unicode characters in the range
- * @param mode writing mode: 0 - horizontal, 1 - vertical
- *
- * @see GetTTSimpleGlyphMetrics
- * @ingroup sft
- *
- */
- TTSimpleGlyphMetrics *GetTTSimpleCharMetrics(TrueTypeFont *ttf, sal_uInt16 firstChar, int nChars, int mode);
-
-/**
- * Maps a Unicode (UCS-2) string to a glyph array. Returns the number of glyphs in the array,
- * which for TrueType fonts is always the same as the number of input characters.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param str pointer to a UCS-2 string
- * @param nchars number of characters in <b>str</b>
- * @param glyphArray pointer to the glyph array where glyph IDs are to be recorded.
- *
- * @return MapString() returns -1 if the TrueType font has no usable 'cmap' tables.
- * Otherwise it returns the number of characters processed: <b>nChars</b>
- *
- * glyphIDs of TrueType fonts are 2 byte positive numbers. glyphID of 0 denotes a missing
- * glyph and traditionally defaults to an empty square.
- * glyphArray should be at least sizeof(sal_uInt16) * nchars bytes long. If glyphArray is NULL
- * MapString() replaces the UCS-2 characters in str with glyphIDs.
- * @ingroup sft
- */
- int MapString(TrueTypeFont *ttf, sal_uInt16 *str, int nchars, sal_uInt16 *glyphArray, int bvertical);
-
-/**
- * Maps a Unicode (UCS-2) character to a glyph ID and returns it. Missing glyph has
- * a glyphID of 0 so this function can be used to test if a character is encoded in the font.
- *
- * @param ttf pointer to the TrueTypeFont structure
- * @param ch Unicode (UCS-2) character
- * @return glyph ID, if the character is missing in the font, the return value is 0.
- * @ingroup sft
- */
- sal_uInt16 MapChar(TrueTypeFont *ttf, sal_uInt16 ch, int bvertical);
-
-/**
- * Returns 0 when the font does not substitute vertical glyphs
- *
- * @param ttf pointer to the TrueTypeFont structure
- */
- int DoesVerticalSubstitution( TrueTypeFont *ttf, int bvertical);
-
-#endif
-
-/**
- * Returns global font information about the TrueType font.
- * @see TTGlobalFontInfo
- *
- * @param ttf pointer to a TrueTypeFont structure
- * @param info pointer to a TTGlobalFontInfo structure
- * @ingroup sft
- *
- */
- void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info);
-
-#ifdef TEST5
-/**
- * Returns kerning information for an array of glyphs.
- * Kerning is not cumulative.
- * kern[i] contains kerning information for a pair of glyphs at positions i and i+1
- *
- * @param ttf pointer to a TrueTypeFont structure
- * @param glyphs array of source glyphs
- * @param nglyphs number of glyphs in the array
- * @param wmode writing mode: 0 - horizontal, 1 - vertical
- * @param kern array of KernData structures. It should contain nglyphs-1 elements
- * @see KernData
- * @ingroup sft
- *
- */
- void KernGlyphs(TrueTypeFont *ttf, sal_uInt16 *glyphs, int nglyphs, int wmode, KernData *kern);
-#endif
-
-/**
- * Returns nonzero if font is a symbol encoded font
- */
- int CheckSymbolEncoding(TrueTypeFont* ttf);
-
-/**
- * returns the number of glyphs in a font
- */
- int GetTTGlyphCount( TrueTypeFont* ttf );
-
-/*- private definitions */ /*FOLD00*/
-
- struct _TrueTypeFont {
- sal_uInt32 tag;
-
- char *fname;
- sal_Int32 fsize;
- sal_uInt8 *ptr;
-
- char *psname;
- char *family;
- sal_uInt16 *ufamily;
- char *subfamily;
- sal_uInt16 *usubfamily;
-
- sal_uInt32 ntables;
- sal_uInt32 *goffsets;
- sal_uInt32 nglyphs;
- sal_uInt32 unitsPerEm;
- sal_uInt32 numberOfHMetrics;
- sal_uInt32 numOfLongVerMetrics; /* if this number is not 0, font has vertical metrics information */
- sal_uInt8 *cmap;
- int cmapType;
- sal_uInt32 (*mapper)(const sal_uInt8 *, sal_uInt32); /* character to glyphID translation function */
- void **tables; /* array of pointers to tables */
- sal_uInt32 *tlens; /* array of table lengths */
- int kerntype; /* Defined in the KernType enum */
- sal_uInt32 nkern; /* number of kern subtables */
- sal_uInt8 **kerntables; /* array of pointers to kern subtables */
- void *pGSubstitution; /* info provided by GSUB for UseGSUB() */
- };
-
-#ifdef __cplusplus
-}
-#endif
-
-/* indexes into _TrueTypeFont::tables[] and _TrueTypeFont::tlens[] */
-#define O_maxp 0 /* 'maxp' */
-#define O_glyf 1 /* 'glyf' */
-#define O_head 2 /* 'head' */
-#define O_loca 3 /* 'loca' */
-#define O_name 4 /* 'name' */
-#define O_hhea 5 /* 'hhea' */
-#define O_hmtx 6 /* 'hmtx' */
-#define O_cmap 7 /* 'cmap' */
-#define O_vhea 8 /* 'vhea' */
-#define O_vmtx 9 /* 'vmtx' */
-#define O_OS2 10 /* 'OS/2' */
-#define O_post 11 /* 'post' */
-#define O_kern 12 /* 'kern' */
-#define O_cvt 13 /* 'cvt_' - only used in TT->TT generation */
-#define O_prep 14 /* 'prep' - only used in TT->TT generation */
-#define O_fpgm 15 /* 'fpgm' - only used in TT->TT generation */
-#define O_gsub 16 /* 'GSUB' */
-#define NUM_TAGS 17
-
-#endif /* __SUBFONT_H */
diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx
index 62439d4d4613..c53460d35584 100644
--- a/vcl/inc/vcl/gdimtf.hxx
+++ b/vcl/inc/vcl/gdimtf.hxx
@@ -164,6 +164,14 @@ public:
void Scale( double fScaleX, double fScaleY );
void Scale( const Fraction& rScaleX, const Fraction& rScaleY );
void Rotate( long nAngle10 );
+ /* get the bound rect of the contained actions
+ * caveats:
+ * - clip actions will limit the contained actions,
+ * but the current clipregion of the passed OutputDevice will not
+ * - coordinates of actions will be transformed to preferred mapmode
+ * - the returned rectangle is relative to the preferred mapmode of the metafile
+ */
+ Rectangle GetBoundRect( OutputDevice& i_rReference );
void Adjust( short nLuminancePercent = 0, short nContrastPercent = 0,
short nChannelRPercent = 0, short nChannelGPercent = 0,
diff --git a/vcl/inc/vcl/graph.hxx b/vcl/inc/vcl/graph.hxx
index f56c55b7db42..9d70c67d3e55 100644
--- a/vcl/inc/vcl/graph.hxx
+++ b/vcl/inc/vcl/graph.hxx
@@ -53,6 +53,36 @@ class OutputDevice;
class Font;
class GfxLink;
+class VCL_DLLPUBLIC GraphicConversionParameters
+{
+private:
+ Size maSizePixel; // default is (0,0)
+
+ // bitfield
+ unsigned mbUnlimitedSize : 1; // default is false
+ unsigned mbAntiAliase : 1; // default is false
+ unsigned mbSnapHorVerLines : 1; // default is false
+
+public:
+ GraphicConversionParameters(
+ const Size& rSizePixel = Size(),
+ bool bUnlimitedSize = false,
+ bool bAntiAliase = false,
+ bool bSnapHorVerLines = false)
+ : maSizePixel(rSizePixel),
+ mbUnlimitedSize(bUnlimitedSize),
+ mbAntiAliase(bAntiAliase),
+ mbSnapHorVerLines(bSnapHorVerLines)
+ {
+ }
+
+ // data read access
+ const Size getSizePixel() const { return maSizePixel; }
+ bool getUnlimitedSize() const { return mbUnlimitedSize; }
+ bool getAntiAliase() const { return mbAntiAliase; }
+ bool getSnapHorVerLines() const { return mbSnapHorVerLines; }
+};
+
class VCL_DLLPUBLIC Graphic : public SvDataCopyStream
{
private:
@@ -96,12 +126,14 @@ public:
BOOL IsAlpha() const;
BOOL IsAnimated() const;
- Bitmap GetBitmap() const;
- Bitmap GetBitmap( const Size* pSizePixel ) const;
- BitmapEx GetBitmapEx() const;
- BitmapEx GetBitmapEx( const Size* pSizePixel ) const;
- Bitmap GetUnlimitedBitmap( const Size* pSizePixel ) const;
- BitmapEx GetUnlimitedBitmapEx( const Size* pSizePixel ) const;
+ // #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic
+ // if it is a MetaFile. To be able to control this conversion it is necessary to
+ // allow giving parameters which control AntiAliasing and LineSnapping of the
+ // MetaFile when played. Defaults will use a no-AAed, not snapped conversion as
+ // before.
+ Bitmap GetBitmap(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const;
+ BitmapEx GetBitmapEx(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const;
+
Animation GetAnimation() const;
const GDIMetaFile& GetGDIMetaFile() const;
diff --git a/vcl/inc/vcl/impgraph.hxx b/vcl/inc/vcl/impgraph.hxx
index 34b61a5fe21c..3b36173891ae 100644
--- a/vcl/inc/vcl/impgraph.hxx
+++ b/vcl/inc/vcl/impgraph.hxx
@@ -55,6 +55,7 @@ struct ImpSwapInfo
class OutputDevice;
class GfxLink;
struct ImpSwapFile;
+class GraphicConversionParameters;
class ImpGraphic
{
@@ -102,8 +103,8 @@ private:
BOOL ImplIsAlpha() const;
BOOL ImplIsAnimated() const;
- Bitmap ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const;
- BitmapEx ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const;
+ Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const;
+ BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const;
Animation ImplGetAnimation() const;
const GDIMetaFile& ImplGetGDIMetaFile() const;
diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx
index 3f821f995a51..f4e42846dd5e 100644
--- a/vcl/inc/vcl/outdev.hxx
+++ b/vcl/inc/vcl/outdev.hxx
@@ -563,6 +563,20 @@ public:
// tells whether this output device is RTL in an LTR UI or LTR in a RTL UI
SAL_DLLPRIVATE bool ImplIsAntiparallel() const ;
+ // #i101491#
+ // Helper which holds the old line geometry creation and is extended to use AA when
+ // switched on. Advantage is that line geometry is only temporarily used for paint
+ SAL_DLLPRIVATE void ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo);
+
+ // #i101491#
+ // Helper who implements the DrawPolyPolygon functionality for basegfx::B2DPolyPolygon
+ // without MetaFile processing
+ SAL_DLLPRIVATE void ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly);
+
+ // #i101491#
+ // Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool. Contains no AA check.
+ SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin);
+
protected:
OutputDevice();
@@ -655,20 +669,20 @@ public:
void GetKerningPairs( ULONG nPairs, KerningPair* pKernPairs ) const;
BOOL GetTextBoundRect( Rectangle& rRect,
- const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0,
- xub_StrLen nLen = STRING_LEN ) const;
+ const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN,
+ ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const;
BOOL GetTextOutline( PolyPolygon&,
const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0,
xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE,
- const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const;
+ ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const;
BOOL GetTextOutlines( PolyPolyVector&,
const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0,
xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE,
- const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const;
+ ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const;
BOOL GetTextOutlines( ::basegfx::B2DPolyPolygonVector&,
const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0,
xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE,
- const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const;
+ ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const;
BOOL GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex,
int nLen, int nBase, MetricVector& rVector );
diff --git a/vcl/inc/vcl/sndstyle.hxx b/vcl/inc/vcl/sndstyle.hxx
index 2fc568a5e86d..55255171ad9f 100644
--- a/vcl/inc/vcl/sndstyle.hxx
+++ b/vcl/inc/vcl/sndstyle.hxx
@@ -44,6 +44,6 @@ typedef USHORT SoundType;
#define SOUND_ERROR ((SoundType)3)
#define SOUND_QUERY ((SoundType)4)
-#define SOUND_DISABLE (SOUND_DEFAULT)
+#define SOUND_DISABLE ((SoundType)5)
#endif // _SV_SNDSTYLE_HXX
diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx
index c8567264b9b9..36d0991c7640 100644
--- a/vcl/source/app/dbggui.cxx
+++ b/vcl/source/app/dbggui.cxx
@@ -1782,7 +1782,7 @@ void DbgDialogTest( Window* pWindow )
i++;
}
- delete pRectAry;
+ delete [] pRectAry;
}
// =======================================================================
diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx
index 687352716ae8..641665aacf6b 100644
--- a/vcl/source/control/lstbox.cxx
+++ b/vcl/source/control/lstbox.cxx
@@ -31,21 +31,21 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
-#ifndef _SV_RC_H
-#include <tools/rc.h>
-#endif
-#include <vcl/svdata.hxx>
-#include <vcl/decoview.hxx>
-#include <vcl/event.hxx>
-#include <vcl/scrbar.hxx>
-#include <vcl/button.hxx>
-#include <vcl/edit.hxx>
-#include <vcl/subedit.hxx>
-#include <vcl/ilstbox.hxx>
-#include <vcl/lstbox.hxx>
-#include <vcl/combobox.hxx>
-#include <vcl/controllayout.hxx>
-#include <tools/debug.hxx>
+#include "tools/rc.h"
+
+#include "vcl/svdata.hxx"
+#include "vcl/decoview.hxx"
+#include "vcl/event.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/button.hxx"
+#include "vcl/edit.hxx"
+#include "vcl/subedit.hxx"
+#include "vcl/ilstbox.hxx"
+#include "vcl/lstbox.hxx"
+#include "vcl/combobox.hxx"
+#include "vcl/controllayout.hxx"
+
+#include "tools/debug.hxx"
@@ -650,6 +650,7 @@ void ListBox::Resize()
long nTop = 0;
long nBottom = aOutSz.Height();
+ // note: in case of no border, pBorder will actually be this
Window *pBorder = GetWindow( WINDOW_BORDER );
ImplControlValue aControlValue;
Point aPoint;
@@ -678,6 +679,17 @@ void ListBox::Resize()
// use the themes drop down size
Rectangle aContentRect = aContent.GetBoundRect();
+ if( ! (GetStyle() & WB_BORDER) && ImplGetSVData()->maNWFData.mbNoFocusRects )
+ {
+ // no border but focus ring behavior -> we have a problem; the
+ // native rect relies on the border to draw the focus
+ // let's do the best we can and center vertically, so it doesn't look
+ // completely wrong.
+ Size aSz( GetOutputSizePixel() );
+ long nDiff = aContentRect.Top() - (aSz.Height() - aContentRect.GetHeight())/2;
+ aContentRect.Top() -= nDiff;
+ aContentRect.Bottom() -= nDiff;
+ }
mpImplWin->SetPosSizePixel( aContentRect.TopLeft(), aContentRect.GetSize() );
}
else
@@ -1273,6 +1285,26 @@ Size ListBox::CalcMinimumSize() const
else
{
aSz.Height() = mpImplLB->CalcSize( 1 ).Height();
+ if( aSz.Height() < mnDDHeight )
+ {
+ aSz.Height() = mnDDHeight;
+ // FIXME: this is currently only on mac/aqua
+ if( ImplGetSVData()->maNWFData.mbNoFocusRects &&
+ IsNativeWidgetEnabled() &&
+ const_cast<ListBox*>(this)->IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) )
+ {
+ ImplControlValue aControlValue;
+ Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 20, mnDDHeight ) ) );
+ Region aBoundingRgn( aCtrlRegion );
+ Region aContentRgn( aCtrlRegion );
+ // adjust the size of the edit field
+ if( const_cast<ListBox*>(this)->GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL,
+ aCtrlRegion, 0, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn) )
+ {
+ aSz.Height() = aContentRgn.GetBoundRect().GetHeight();
+ }
+ }
+ }
aSz.Width() = mpImplLB->GetMaxEntryWidth();
aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize();
}
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index 10d4cf774b04..7744b2f9a59c 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -329,7 +329,7 @@ _inline void PutInt16(sal_Int16 val, sal_uInt8 *ptr, size_t offset, int bigendia
}
-#if defined(OSL_BIG_ENDIAN)
+#if defined(OSL_BIGENDIAN)
#define Int16FromMOTA(a) (a)
#define Int32FromMOTA(a) (a)
#else
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index 3a29e6d56095..6483c8292df7 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -1403,6 +1403,436 @@ void GDIMetaFile::Rotate( long nAngle10 )
// ------------------------------------------------------------------------
+static void ImplActionBounds( Rectangle& o_rOutBounds,
+ const Rectangle& i_rInBounds,
+ const std::vector<Rectangle>& i_rClipStack )
+{
+ Rectangle aBounds( i_rInBounds );
+ if( ! i_rInBounds.IsEmpty() && ! i_rClipStack.empty() && ! i_rClipStack.back().IsEmpty() )
+ aBounds.Intersection( i_rClipStack.back() );
+ if( ! aBounds.IsEmpty() )
+ {
+ if( ! o_rOutBounds.IsEmpty() )
+ o_rOutBounds.Union( aBounds );
+ else
+ o_rOutBounds = aBounds;
+ }
+}
+
+Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference )
+{
+ GDIMetaFile aMtf;
+ VirtualDevice aMapVDev( i_rReference );
+
+ aMapVDev.EnableOutput( FALSE );
+ aMapVDev.SetMapMode( GetPrefMapMode() );
+
+ std::vector<Rectangle> aClipStack( 1, Rectangle() );
+ std::vector<USHORT> aPushFlagStack;
+
+ Rectangle aBound;
+
+ for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() )
+ {
+ const USHORT nActionType = pAction->GetType();
+
+ switch( nActionType )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ MetaPixelAction* pAct = (MetaPixelAction*) pAction;
+ ImplActionBounds( aBound,
+ Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ),
+ aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
+ aClipStack );
+ }
+ break;
+
+ case( META_POINT_ACTION ):
+ {
+ MetaPointAction* pAct = (MetaPointAction*) pAction;
+ ImplActionBounds( aBound,
+ Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ),
+ aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
+ aClipStack );
+ }
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ MetaLineAction* pAct = (MetaLineAction*) pAction;
+ Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() );
+ Rectangle aRect( aP1, aP2 );
+ aRect.Justify();
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ {
+ MetaRectAction* pAct = (MetaRectAction*) pAction;
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction;
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ MetaEllipseAction* pAct = (MetaEllipseAction*) pAction;
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ {
+ MetaArcAction* pAct = (MetaArcAction*) pAction;
+ // FIXME: this is imprecise
+ // e.g. for small arcs the whole rectangle is WAY too large
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ MetaPieAction* pAct = (MetaPieAction*) pAction;
+ // FIXME: this is imprecise
+ // e.g. for small arcs the whole rectangle is WAY too large
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ MetaChordAction* pAct = (MetaChordAction*) pAction;
+ // FIXME: this is imprecise
+ // e.g. for small arcs the whole rectangle is WAY too large
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction;
+ Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ {
+ MetaPolygonAction* pAct = (MetaPolygonAction*) pAction;
+ Rectangle aRect( pAct->GetPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction;
+ Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_TEXT_ACTION ):
+ {
+ MetaTextAction* pAct = (MetaTextAction*) pAction;
+ Rectangle aRect;
+ // hdu said base = index
+ aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() );
+ Point aPt( pAct->GetPoint() );
+ aRect.Move( aPt.X(), aPt.Y() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_TEXTARRAY_ACTION ):
+ {
+ MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction;
+ Rectangle aRect;
+ // hdu said base = index
+ aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
+ 0, pAct->GetDXArray() );
+ Point aPt( pAct->GetPoint() );
+ aRect.Move( aPt.X(), aPt.Y() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_STRETCHTEXT_ACTION ):
+ {
+ MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction;
+ Rectangle aRect;
+ // hdu said base = index
+ aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(),
+ pAct->GetWidth(), NULL );
+ Point aPt( pAct->GetPoint() );
+ aRect.Move( aPt.X(), aPt.Y() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_TEXTLINE_ACTION ):
+ {
+ MetaTextLineAction* pAct = (MetaTextLineAction*) pAction;
+ // measure a test string to get ascend and descent right
+ static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 };
+ String aStr( pStr );
+
+ Rectangle aRect;
+ aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL );
+ Point aPt( pAct->GetStartPoint() );
+ aRect.Move( aPt.X(), aPt.Y() );
+ aRect.Right() = aRect.Left() + pAct->GetWidth();
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_BMPSCALE_ACTION ):
+ {
+ MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_BMPSCALEPART_ACTION ):
+ {
+ MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction;
+ Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_BMPEXSCALE_ACTION ):
+ {
+ MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_BMPEXSCALEPART_ACTION ):
+ {
+ MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction;
+ Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ MetaGradientAction* pAct = (MetaGradientAction*) pAction;
+ Rectangle aRect( pAct->GetRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_GRADIENTEX_ACTION ):
+ {
+ MetaGradientExAction* pAct = (MetaGradientExAction*) pAction;
+ Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_COMMENT_ACTION ):
+ {
+ // nothing to do
+ };
+ break;
+
+ case( META_HATCH_ACTION ):
+ {
+ MetaHatchAction* pAct = (MetaHatchAction*) pAction;
+ Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_TRANSPARENT_ACTION ):
+ {
+ MetaTransparentAction* pAct = (MetaTransparentAction*) pAction;
+ Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_FLOATTRANSPARENT_ACTION ):
+ {
+ MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction;
+ GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() );
+ // get the bound rect of the contained metafile
+ Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) );
+ // scale the rect now on the assumption that the correct top left of the metafile
+ // (not its bounds !) is (0,0)
+ Size aPSize( aTransMtf.GetPrefSize() );
+ aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() );
+ Size aActSize( pAct->GetSize() );
+ double fX = double(aActSize.Width())/double(aPSize.Width());
+ double fY = double(aActSize.Height())/double(aPSize.Height());
+ aRect.Left() = long(double(aRect.Left())*fX);
+ aRect.Right() = long(double(aRect.Right())*fX);
+ aRect.Top() = long(double(aRect.Top())*fY);
+ aRect.Bottom() = long(double(aRect.Bottom())*fY);
+
+ // transform the rect to current VDev state
+ aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() );
+
+ ImplActionBounds( aBound, aRect, aClipStack );
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ MetaEPSAction* pAct = (MetaEPSAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), pAct->GetSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_CLIPREGION_ACTION ):
+ {
+ MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction;
+ if( pAct->IsClipping() )
+ aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() );
+ else
+ aClipStack.back() = Rectangle();
+ }
+ break;
+
+ case( META_ISECTRECTCLIPREGION_ACTION ):
+ {
+ MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction;
+ Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) );
+ if( aClipStack.back().IsEmpty() )
+ aClipStack.back() = aRect;
+ else
+ aClipStack.back().Intersection( aRect );
+ }
+ break;
+
+ case( META_ISECTREGIONCLIPREGION_ACTION ):
+ {
+ MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction;
+ Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) );
+ if( aClipStack.back().IsEmpty() )
+ aClipStack.back() = aRect;
+ else
+ aClipStack.back().Intersection( aRect );
+ }
+ break;
+
+ case( META_BMP_ACTION ):
+ {
+ MetaBmpAction* pAct = (MetaBmpAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_BMPEX_ACTION ):
+ {
+ MetaBmpExAction* pAct = (MetaBmpExAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_MASK_ACTION ):
+ {
+ MetaMaskAction* pAct = (MetaMaskAction*) pAction;
+ Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_MASKSCALE_ACTION ):
+ {
+ MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
+ Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_MASKSCALEPART_ACTION ):
+ {
+ MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction;
+ Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_WALLPAPER_ACTION ):
+ {
+ MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction;
+ Rectangle aRect( pAct->GetRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_TEXTRECT_ACTION ):
+ {
+ MetaTextRectAction* pAct = (MetaTextRectAction*) pAction;
+ Rectangle aRect( pAct->GetRect() );
+ ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack );
+ }
+ break;
+
+ case( META_MOVECLIPREGION_ACTION ):
+ {
+ MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction;
+ if( ! aClipStack.back().IsEmpty() )
+ {
+ Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() );
+ aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() );
+ aClipStack.back().Move( aDelta.Width(), aDelta.Width() );
+ }
+ }
+ break;
+
+ default:
+ {
+ pAction->Execute( &aMapVDev );
+
+ if( nActionType == META_PUSH_ACTION )
+ {
+ MetaPushAction* pAct = (MetaPushAction*) pAction;
+ aPushFlagStack.push_back( pAct->GetFlags() );
+ if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 )
+ {
+ Rectangle aRect( aClipStack.back() );
+ aClipStack.push_back( aRect );
+ }
+ }
+ else if( nActionType == META_POP_ACTION )
+ {
+ // sanity check
+ if( ! aPushFlagStack.empty() )
+ {
+ if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 )
+ {
+ if( aClipStack.size() > 1 )
+ aClipStack.pop_back();
+ }
+ aPushFlagStack.pop_back();
+ }
+ }
+ }
+ break;
+ }
+ }
+ return aBound;
+}
+
+// ------------------------------------------------------------------------
+
Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam )
{
return Color( rColor.GetTransparency(),
diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx
index dfa155e29eae..77f065912e5d 100644
--- a/vcl/source/gdi/graph.cxx
+++ b/vcl/source/gdi/graph.cxx
@@ -430,44 +430,16 @@ BOOL Graphic::IsAnimated() const
// ------------------------------------------------------------------------
-Bitmap Graphic::GetBitmap() const
+Bitmap Graphic::GetBitmap(const GraphicConversionParameters& rParameters) const
{
- return GetBitmap( NULL );
+ return mpImpGraphic->ImplGetBitmap(rParameters);
}
// ------------------------------------------------------------------------
-BitmapEx Graphic::GetBitmapEx() const
+BitmapEx Graphic::GetBitmapEx(const GraphicConversionParameters& rParameters) const
{
- return GetBitmapEx( NULL );
-}
-
-// ------------------------------------------------------------------------
-
-Bitmap Graphic::GetBitmap( const Size* pSizePixel ) const
-{
- return mpImpGraphic->ImplGetBitmap( pSizePixel, FALSE );
-}
-
-// ------------------------------------------------------------------------
-
-BitmapEx Graphic::GetBitmapEx( const Size* pSizePixel ) const
-{
- return mpImpGraphic->ImplGetBitmapEx( pSizePixel, FALSE );
-}
-
-// ------------------------------------------------------------------------
-
-Bitmap Graphic::GetUnlimitedBitmap( const Size* pSizePixel ) const
-{
- return mpImpGraphic->ImplGetBitmap( pSizePixel, TRUE ) ;
-}
-
-// ------------------------------------------------------------------------
-
-BitmapEx Graphic::GetUnlimitedBitmapEx( const Size* pSizePixel ) const
-{
- return mpImpGraphic->ImplGetBitmapEx( pSizePixel, TRUE ) ;
+ return mpImpGraphic->ImplGetBitmapEx(rParameters);
}
// ------------------------------------------------------------------------
@@ -553,7 +525,7 @@ Size Graphic::GetSizePixel( const OutputDevice* pRefDevice ) const
Size aRet;
if( GRAPHIC_BITMAP == mpImpGraphic->ImplGetType() )
- aRet = mpImpGraphic->ImplGetBitmapEx( NULL, FALSE ).GetSizePixel();
+ aRet = mpImpGraphic->ImplGetBitmapEx(GraphicConversionParameters()).GetSizePixel();
else
aRet = ( pRefDevice ? pRefDevice : Application::GetDefaultDevice() )->LogicToPixel( GetPrefSize(), GetPrefMapMode() );
diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx
index a67d6fa7feac..d73f35bef962 100644
--- a/vcl/source/gdi/impgraph.cxx
+++ b/vcl/source/gdi/impgraph.cxx
@@ -483,7 +483,7 @@ BOOL ImpGraphic::ImplIsAnimated() const
// ------------------------------------------------------------------------
-Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const
+Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
{
Bitmap aRetBmp;
@@ -494,8 +494,8 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons
aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor );
- if( pSizePixel )
- aRetBmp.Scale( *pSizePixel );
+ if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
+ aRetBmp.Scale(rParameters.getSizePixel());
}
else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
{
@@ -508,16 +508,18 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons
Size aDrawSize( aVDev.LogicToPixel( maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode() ) );
Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
- if( pSizePixel && aSizePix.Width() && aSizePix.Height() )
+ if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
{
- aDrawSize.Width() = FRound( (double) pSizePixel->Width() * (double) aDrawSize.Width() / (double) aSizePix.Width() );
- aDrawSize.Height() = FRound( (double) pSizePixel->Height() * (double) aDrawSize.Height() / (double) aSizePix.Height() );
+ aDrawSize.Width() = FRound((double)rParameters.getSizePixel().Width() *
+ (double)aDrawSize.Width() / (double)aSizePix.Width());
+ aDrawSize.Height() = FRound((double)rParameters.getSizePixel().Height() *
+ (double)aDrawSize.Height() / (double)aSizePix.Height());
- aSizePix = *pSizePixel;
+ aSizePix = rParameters.getSizePixel();
}
- if( aSizePix.Width() && aSizePix.Height() && !bUnlimited &&
- ( aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT ) )
+ if( aSizePix.Width() && aSizePix.Height() && !rParameters.getUnlimitedSize()
+ && (aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
{
const Size aOldSizePix( aSizePix );
double fWH = (double) aSizePix.Width() / aSizePix.Height();
@@ -533,6 +535,16 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons
if( aVDev.SetOutputSizePixel( aSizePix ) )
{
+ if(rParameters.getAntiAliase())
+ {
+ aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
+ }
+
+ if(rParameters.getSnapHorVerLines())
+ {
+ aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE);
+ }
+
ImplDraw( &aVDev, aNullPt, aDrawSize );
aRetBmp = aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() );
}
@@ -549,7 +561,7 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons
// ------------------------------------------------------------------------
-BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const
+BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const
{
BitmapEx aRetBmpEx;
@@ -557,13 +569,13 @@ BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited )
{
aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
- if( pSizePixel )
- aRetBmpEx.Scale( *pSizePixel );
+ if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
+ aRetBmpEx.Scale(rParameters.getSizePixel());
}
else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
{
const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
- aRetBmpEx = BitmapEx( ImplGetBitmap( pSizePixel, bUnlimited ), aMonoMask.ImplGetBitmap( pSizePixel, bUnlimited ) );
+ aRetBmpEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters));
}
return aRetBmpEx;
diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk
index 977e5386fe97..4d0ded320060 100644
--- a/vcl/source/gdi/makefile.mk
+++ b/vcl/source/gdi/makefile.mk
@@ -137,6 +137,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \
$(SLO)$/pngwrite.obj \
$(SLO)$/virdev.obj \
$(SLO)$/impprn.obj \
+ $(SLO)$/gdimtf.obj \
$(SLO)$/graphictools.obj
diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx
index 0e9da9f81136..5b543258cb0b 100644
--- a/vcl/source/gdi/outdev.cxx
+++ b/vcl/source/gdi/outdev.cxx
@@ -68,6 +68,8 @@
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/polygon/b2dlinegeometry.hxx>
#include <com/sun/star/awt/XGraphics.hpp>
#include <com/sun/star/uno/Sequence.hxx>
@@ -2285,8 +2287,35 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
if ( mbInitLineColor )
ImplInitLineColor();
- Point aStartPt = ImplLogicToDevicePixel( rStartPt );
- Point aEndPt = ImplLogicToDevicePixel( rEndPt );
+ // #i101598# support AA and snap for lines, too
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsLineColor())
+ {
+ // at least transform with double precision to device coordinates; this will
+ // avoid pixel snap of single, appended lines
+ const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
+ const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+ basegfx::B2DPolygon aB2DPolyLine;
+
+ aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
+ aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
+ aB2DPolyLine.transform( aTransform );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
+ }
+
+ if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this))
+ {
+ return;
+ }
+ }
+
+ const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
+ const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
@@ -2444,22 +2473,30 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly )
if ( mbInitLineColor )
ImplInitLineColor();
+ const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsLineColor());
+
// use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon(), 0.0, basegfx::B2DLINEJOIN_NONE))
{
- ::basegfx::B2DPolygon aB2DPolyLine = rPoly.getB2DPolygon();
+ basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- aB2DPolyLine.transform( aTransform );
const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE))
+ // transform the polygon
+ aB2DPolyLine.transform( aTransform );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
{
- // #i98289#
aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
}
- if( mpGraphics->DrawPolyLine( aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_ROUND, this ) )
+ if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this))
+ {
return;
+ }
}
Polygon aPoly = ImplLogicToDevicePixel( rPoly );
@@ -2499,9 +2536,23 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo
return;
}
+ // #i101491#
+ // Try direct Fallback to B2D-Version of DrawPolyLine
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && LINE_SOLID == rLineInfo.GetStyle())
+ {
+ DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), basegfx::B2DLINEJOIN_ROUND);
+ return;
+ }
+
if ( mpMetaFile )
mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
+ ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo);
+}
+
+void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
+{
USHORT nPoints = rPoly.GetSize();
if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
@@ -2527,6 +2578,10 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo
return;
const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
+ const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsLineColor());
if( aInfo.GetWidth() > 1L )
{
@@ -2540,9 +2595,32 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo
ImplInitLineColor();
SetFillColor( aOldLineColor );
ImplInitFillColor();
+ bool bDone(false);
+
+ if(bTryAA)
+ {
+ // #i101491# try AAed version
+ // Use old on-the-fly geometry preparation, combine with AA
+ bool bSuccess(true);
- for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
- mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this );
+ for(const Polygon* pPoly = aLineCvt.ImplGetFirst(); bSuccess && pPoly; pPoly = aLineCvt.ImplGetNext())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(pPoly->getB2DPolygon()), 0.0, this);
+ }
+
+ if(bSuccess)
+ {
+ bDone = true;
+ }
+ }
+
+ if(!bDone)
+ {
+ for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() )
+ {
+ mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this );
+ }
+ }
SetLineColor( aOldLineColor );
SetFillColor( aOldFillColor );
@@ -2598,13 +2676,40 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly )
ImplInitFillColor();
// use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
{
- ::basegfx::B2DPolyPolygon aB2DPolyPolygon( rPoly.getB2DPolygon() );
const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- aB2DPolyPolygon.transform( aTransform );
- if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) )
+ basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolygon.transform(aTransform);
+ aB2DPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
+ }
+
+ bSuccess = mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
+ }
+
+ if(bSuccess)
+ {
return;
+ }
}
Polygon aPoly = ImplLogicToDevicePixel( rPoly );
@@ -2661,13 +2766,43 @@ void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
ImplInitFillColor();
// use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
{
- ::basegfx::B2DPolyPolygon aB2DPolyPolygon = rPolyPoly.getB2DPolyPolygon();
const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- aB2DPolyPolygon.transform( aTransform );
- if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) )
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolyPolygon.transform(aTransform);
+ aB2DPolyPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
+ }
+
+ for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
+ {
+ bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
+ }
+ }
+
+ if(bSuccess)
+ {
return;
+ }
}
if ( nPoly == 1 )
@@ -2729,6 +2864,12 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly
mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
#endif
+ // call helper
+ ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
+}
+
+void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
+{
// AW: Do NOT paint empty PolyPolygons
if(!rB2DPolyPoly.count())
return;
@@ -2748,13 +2889,43 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly
if( mbInitFillColor )
ImplInitFillColor();
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && (IsLineColor() || IsFillColor()))
{
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly;
- aB2DPP.transform( aTransform );
- if( mpGraphics->DrawPolyPolygon( aB2DPP, 0.0, this ) )
+ const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
+ bool bSuccess(true);
+
+ // transform the polygon and ensure closed
+ aB2DPolyPolygon.transform(aTransform);
+ aB2DPolyPolygon.setClosed(true);
+
+ if(IsFillColor())
+ {
+ bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
+ }
+
+ if(bSuccess && IsLineColor())
+ {
+ const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
+
+ if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ {
+ aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
+ }
+
+ for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
+ {
+ bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
+ }
+ }
+
+ if(bSuccess)
+ {
return;
+ }
}
// fallback to old polygon drawing if needed
@@ -2765,6 +2936,38 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly
// -----------------------------------------------------------------------
+bool OutputDevice::ImpTryDrawPolyLineDirect(
+ const basegfx::B2DPolygon& rB2DPolygon,
+ double fLineWidth,
+ basegfx::B2DLineJoin eLineJoin)
+{
+ const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
+ basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
+
+ // transform the line width if used
+ if( fLineWidth != 0.0 )
+ {
+ aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
+ }
+
+ // transform the polygon
+ basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
+ aB2DPolygon.transform(aTransform);
+
+ if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
+ && aB2DPolygon.count() < 1000)
+ {
+ // #i98289#, #i101491#
+ // better to remove doubles on device coordinates. Also assume from a given amount
+ // of points that the single edges are not long enough to smooth
+ aB2DPolygon.removeDoublePoints();
+ aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
+ }
+
+ // draw the polyline
+ return mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, eLineJoin, this);
+}
+
void OutputDevice::DrawPolyLine(
const basegfx::B2DPolygon& rB2DPolygon,
double fLineWidth,
@@ -2808,37 +3011,62 @@ void OutputDevice::DrawPolyLine(
if( mbInitLineColor )
ImplInitLineColor();
- // #i98289# use b2dpolygon drawing if possible
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsLineColor());
+
+ // use b2dpolygon drawing if possible
+ if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, eLineJoin))
{
- const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- ::basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
+ return;
+ }
- // transform the line width if used
- if( fLineWidth != 0.0 )
- aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
+ // #i101491#
+ // no output yet; fallback to geometry decomposition and use filled polygon paint
+ // when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon
+ // will do internal needed AA checks etc.
+ if(fLineWidth >= 2.5
+ && rB2DPolygon.count()
+ && rB2DPolygon.count() <= 1000)
+ {
+ const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
+ const basegfx::B2DPolyPolygon aAreaPolyPolygon(basegfx::tools::createAreaGeometry(
+ rB2DPolygon, fHalfLineWidth, eLineJoin));
- // transform the polygon
- ::basegfx::B2DPolygon aB2DPL = rB2DPolygon;
- aB2DPL.transform( aTransform );
+ const Color aOldLineColor(maLineColor);
+ const Color aOldFillColor(maFillColor);
+
+ SetLineColor();
+ ImplInitLineColor();
+ SetFillColor(aOldLineColor);
+ ImplInitFillColor();
+
+ ImpDrawPolyPolygonWithB2DPolyPolygon(aAreaPolyPolygon);
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE))
+ SetLineColor(aOldLineColor);
+ ImplInitLineColor();
+ SetFillColor(aOldFillColor);
+ ImplInitFillColor();
+
+ if(bTryAA)
{
- // #i98289#
- aB2DPL = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPL);
+ // when AA it is necessary to also paint the filled polygon's outline
+ // to avoid optical gaps
+ for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
+ {
+ ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a), 0.0, basegfx::B2DLINEJOIN_NONE);
+ }
}
-
- // draw the polyline
- if( mpGraphics->DrawPolyLine( aB2DPL, aB2DLineWidth, eLineJoin, this ) )
- return;
}
- // fallback to old polygon drawing if needed
+ // fallback to old polygon drawing if needed. This will really
+ // use ImplLineConverter, but still try to AA lines
const Polygon aToolsPolygon( rB2DPolygon );
LineInfo aLineInfo;
if( fLineWidth != 0.0 )
aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
- DrawPolyLine( aToolsPolygon, aLineInfo );
+ ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
}
// -----------------------------------------------------------------------
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index 537964582ceb..710620d54ab8 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -7,7 +7,6 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: outdev3.cxx,v $
- * $Revision: 1.240.14.5 $
*
* This file is part of OpenOffice.org.
*
@@ -6484,7 +6483,7 @@ SalLayout* OutputDevice::ImplLayout( const String& rOrigStr,
nRTLOffset = nPixelWidth;
else
nRTLOffset = pSalLayout->GetTextWidth() / pSalLayout->GetUnitsPerPixel();
- pSalLayout->DrawOffset().X() = -nRTLOffset;
+ pSalLayout->DrawOffset().X() = 1 - nRTLOffset;
}
return pSalLayout;
@@ -6919,13 +6918,13 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect,
nStyle &= ~TEXT_DRAW_CLIP;
}
- // Vertikales Alignment
+ // horizontal text alignment
if ( nStyle & TEXT_DRAW_RIGHT )
aPos.X() += nWidth-nTextWidth;
else if ( nStyle & TEXT_DRAW_CENTER )
aPos.X() += (nWidth-nTextWidth)/2;
- // Font Alignment
+ // vertical font alignment
if ( eAlign == ALIGN_BOTTOM )
aPos.Y() += nTextHeight;
else if ( eAlign == ALIGN_BASELINE )
@@ -7919,8 +7918,8 @@ BOOL OutputDevice::GetGlyphBoundRects( const Point& rOrigin, const String& rStr,
// -----------------------------------------------------------------------
BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect,
- const String& rStr, xub_StrLen nBase, xub_StrLen nIndex,
- xub_StrLen nLen ) const
+ const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen,
+ ULONG nLayoutWidth, const sal_Int32* pDXAry ) const
{
DBG_TRACE( "OutputDevice::GetTextBoundRect()" );
DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
@@ -7929,13 +7928,14 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect,
rRect.SetEmpty();
SalLayout* pSalLayout = NULL;
+ const Point aPoint;
// calculate offset when nBase!=nIndex
long nXOffset = 0;
if( nBase != nIndex )
{
xub_StrLen nStart = Min( nBase, nIndex );
xub_StrLen nOfsLen = Max( nBase, nIndex ) - nStart;
- pSalLayout = ImplLayout( rStr, nStart, nOfsLen );
+ pSalLayout = ImplLayout( rStr, nStart, nOfsLen, aPoint, nLayoutWidth, pDXAry );
if( pSalLayout )
{
nXOffset = pSalLayout->GetTextWidth();
@@ -7947,7 +7947,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect,
}
}
- pSalLayout = ImplLayout( rStr, nIndex, nLen );
+ pSalLayout = ImplLayout( rStr, nIndex, nLen, aPoint, nLayoutWidth, pDXAry );
Rectangle aPixelRect;
if( pSalLayout )
{
@@ -7997,7 +7997,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect,
aVDev.SetTextAlign( ALIGN_TOP );
// layout the text on the virtual device
- pSalLayout = aVDev.ImplLayout( rStr, nIndex, nLen );
+ pSalLayout = aVDev.ImplLayout( rStr, nIndex, nLen, aPoint, nLayoutWidth, pDXAry );
if( !pSalLayout )
return false;
@@ -8097,7 +8097,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect,
BOOL OutputDevice::GetTextOutlines( ::basegfx::B2DPolyPolygonVector& rVector,
const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen,
- BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const
+ BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const
{
// the fonts need to be initialized
if( mbNewFont )
@@ -8326,7 +8326,7 @@ BOOL OutputDevice::GetTextOutlines( ::basegfx::B2DPolyPolygonVector& rVector,
BOOL OutputDevice::GetTextOutlines( PolyPolyVector& rResultVector,
const String& rStr, xub_StrLen nBase, xub_StrLen nIndex,
- xub_StrLen nLen, BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const
+ xub_StrLen nLen, BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const
{
rResultVector.clear();
@@ -8349,7 +8349,7 @@ BOOL OutputDevice::GetTextOutlines( PolyPolyVector& rResultVector,
BOOL OutputDevice::GetTextOutline( PolyPolygon& rPolyPoly,
const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen,
- BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const
+ BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const
{
rPolyPoly.Clear();
diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx
index cee4f475a577..a11e276982f7 100644
--- a/vcl/source/gdi/outdev6.cxx
+++ b/vcl/source/gdi/outdev6.cxx
@@ -185,14 +185,20 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly,
if( mbInitFillColor )
ImplInitFillColor();
- if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw))
+ if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
+ && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
+ && ROP_OVERPAINT == GetRasterOp()
+ && IsFillColor())
{
// b2dpolygon support not implemented yet on non-UNX platforms
const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
- ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly;
- aB2DPP.transform( aTransform );
+ basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
- if( mpGraphics->DrawPolyPolygon( aB2DPP, fTransparency, this ) )
+ // transform the polygon and ensure closed
+ aB2DPolyPolygon.transform(aTransform);
+ aB2DPolyPolygon.setClosed(true);
+
+ if(mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, fTransparency, this))
{
#if 0
// MetaB2DPolyPolygonAction is not implemented yet:
diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx
index d149ee26284f..591557eaa091 100644
--- a/vcl/source/glyphs/gcach_ftyp.cxx
+++ b/vcl/source/glyphs/gcach_ftyp.cxx
@@ -1058,7 +1058,7 @@ static inline void SplitGlyphFlags( const FreetypeServerFont& rFont, int& nGlyph
// -----------------------------------------------------------------------
int FreetypeServerFont::ApplyGlyphTransform( int nGlyphFlags,
- FT_GlyphRec_* pGlyphFT, bool bForBitmapProcessing ) const
+ FT_Glyph pGlyphFT, bool bForBitmapProcessing ) const
{
int nAngle = GetFontSelData().mnOrientation;
// shortcut most common case
@@ -1130,9 +1130,9 @@ int FreetypeServerFont::ApplyGlyphTransform( int nGlyphFlags,
else
{
// FT<=2005 ignores transforms for bitmaps, so do it manually
- FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<FT_BitmapGlyph&>(pGlyphFT);
- rBmpGlyphFT->left += (aVector.x + 32) >> 6;
- rBmpGlyphFT->top += (aVector.y + 32) >> 6;
+ FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<FT_BitmapGlyph>(pGlyphFT);
+ pBmpGlyphFT->left += (aVector.x + 32) >> 6;
+ pBmpGlyphFT->top += (aVector.y + 32) >> 6;
}
return nAngle;
@@ -1440,12 +1440,12 @@ bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap
}
}
- const FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph&>(pGlyphFT);
+ const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT);
// NOTE: autohinting in FT<=2.0.2 miscalculates the offsets below by +-1
- rRawBitmap.mnXOffset = +rBmpGlyphFT->left;
- rRawBitmap.mnYOffset = -rBmpGlyphFT->top;
+ rRawBitmap.mnXOffset = +pBmpGlyphFT->left;
+ rRawBitmap.mnYOffset = -pBmpGlyphFT->top;
- const FT_Bitmap& rBitmapFT = rBmpGlyphFT->bitmap;
+ const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap;
rRawBitmap.mnHeight = rBitmapFT.rows;
rRawBitmap.mnBitCount = 1;
if( mbArtBold && !pFTEmbolden )
@@ -1595,11 +1595,11 @@ bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap
}
}
- const FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph&>(pGlyphFT);
- rRawBitmap.mnXOffset = +rBmpGlyphFT->left;
- rRawBitmap.mnYOffset = -rBmpGlyphFT->top;
+ const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT);
+ rRawBitmap.mnXOffset = +pBmpGlyphFT->left;
+ rRawBitmap.mnYOffset = -pBmpGlyphFT->top;
- const FT_Bitmap& rBitmapFT = rBmpGlyphFT->bitmap;
+ const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap;
rRawBitmap.mnHeight = rBitmapFT.rows;
rRawBitmap.mnWidth = rBitmapFT.width;
rRawBitmap.mnBitCount = 8;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index c827905e94e6..ccf75dbd59b3 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -3480,11 +3480,6 @@ USHORT PopupMenu::Execute( Window* pExecWindow, const Rectangle& rRect, USHORT n
USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupModeFlags, Menu* pSFrom, BOOL bPreSelectFirst )
{
-
- // #59614# Mit TH abgesprochen dass die ASSERTION raus kommt,
- // weil es evtl. legitim ist...
-// DBG_ASSERT( !PopupMenu::IsInExecute() || pSFrom, "PopupMenu::Execute() called in PopupMenu::Execute()" );
-
if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) )
return 0;
@@ -3660,8 +3655,16 @@ USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupM
{
pWin->ImplAddDel( &aDelData );
+ ImplDelData aModalWinDel;
+ pW->ImplAddDel( &aModalWinDel );
+ pW->ImplIncModalCount();
+
pWin->Execute();
+ DBG_ASSERT( ! aModalWinDel.IsDead(), "window for popup died, modal count incorrect !" );
+ if( ! aModalWinDel.IsDead() )
+ pW->ImplDecModalCount();
+
if ( !aDelData.IsDelete() )
pWin->ImplRemoveDel( &aDelData );
else
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 86d6347617b0..5333d20d4306 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -6221,6 +6221,15 @@ void Window::SetParent( Window* pNewParent )
pSysWin->GetTaskPaneList()->RemoveWindow( this );
}
}
+ // remove ownerdraw decorated windows from list in the top-most frame window
+ if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
+ {
+ ::std::vector< Window* >& rList = ImplGetOwnerDrawList();
+ ::std::vector< Window* >::iterator p;
+ p = ::std::find( rList.begin(), rList.end(), this );
+ if( p != rList.end() )
+ rList.erase( p );
+ }
ImplSetFrameParent( pNewParent );
@@ -6350,6 +6359,9 @@ void Window::SetParent( Window* pNewParent )
if( bChangeTaskPaneList )
pNewSysWin->GetTaskPaneList()->AddWindow( this );
+ if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame )
+ ImplGetOwnerDrawList().push_back( this );
+
if ( bVisible )
Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
}
diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
index 9dbb218403d0..fdaa102c614b 100644
--- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
+++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx
@@ -454,6 +454,10 @@ void GtkData::deInitNWF( void )
gtk_widget_destroy( gWidgetData[i].gMenuWidget );
if( gWidgetData[i].gTooltipPopup )
gtk_widget_destroy( gWidgetData[i].gTooltipPopup );
+ delete gWidgetData[i].gCacheTabPages;
+ gWidgetData[i].gCacheTabPages = NULL;
+ delete gWidgetData[i].gCacheTabItems;
+ gWidgetData[i].gCacheTabItems = NULL;
delete gWidgetData[i].gNWPixmapCacheList;
gWidgetData[i].gNWPixmapCacheList = NULL;
}
diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx
index 57f48df66c3c..b6770ca1a77e 100644
--- a/vcl/unx/gtk/window/gtkframe.cxx
+++ b/vcl/unx/gtk/window/gtkframe.cxx
@@ -834,7 +834,7 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle )
}
if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) )
{
- eType = GDK_WINDOW_TYPE_HINT_DOCK;
+ eType = GDK_WINDOW_TYPE_HINT_TOOLBAR;
gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true );
}
diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx
index db49c97de00c..6695d4abeb21 100644
--- a/vcl/unx/source/gdi/salgdi.cxx
+++ b/vcl/unx/source/gdi/salgdi.cxx
@@ -1,1539 +1,1548 @@
-/*************************************************************************
- *
- * 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
- *
- * 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_vcl.hxx"
-
-#include "Xproto.h"
-
-#include "salunx.h"
-#include "saldata.hxx"
-#include "saldisp.hxx"
-#include "salgdi.h"
-#include "salframe.h"
-#include "salvd.h"
-#include "xrender_peer.hxx"
-
-#include "vcl/printergfx.hxx"
-#include "vcl/jobdata.hxx"
-
-#include "tools/debug.hxx"
-
-#include "basegfx/polygon/b2dpolygon.hxx"
-#include "basegfx/polygon/b2dpolypolygon.hxx"
-#include "basegfx/polygon/b2dpolypolygontools.hxx"
-#include "basegfx/polygon/b2dpolygontools.hxx"
-#include "basegfx/polygon/b2dpolygonclipper.hxx"
-#include "basegfx/polygon/b2dlinegeometry.hxx"
-#include "basegfx/matrix/b2dhommatrix.hxx"
-#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
-
-#include <vector>
-#include <queue>
-#include <set>
-
-// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#define STATIC_POINTS 64
-
-class SalPolyLine
-{
- XPoint Points_[STATIC_POINTS];
- XPoint *pFirst_;
-public:
- inline SalPolyLine( ULONG nPoints );
- inline SalPolyLine( ULONG nPoints, const SalPoint *p );
- inline ~SalPolyLine();
- inline XPoint &operator [] ( ULONG n ) const
- { return pFirst_[n]; }
-};
-
-inline SalPolyLine::SalPolyLine( ULONG nPoints )
- : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
-{}
-
-inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p )
- : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
-{
- for( ULONG i = 0; i < nPoints; i++ )
- {
- pFirst_[i].x = (short)p[i].mnX;
- pFirst_[i].y = (short)p[i].mnY;
- }
- pFirst_[nPoints] = pFirst_[0]; // close polyline
-}
-
-inline SalPolyLine::~SalPolyLine()
-{ if( pFirst_ != Points_ ) delete [] pFirst_; }
-
-#undef STATIC_POINTS
-// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-X11SalGraphics::X11SalGraphics()
-{
- m_pFrame = NULL;
- m_pVDev = NULL;
- m_pDeleteColormap = NULL;
- hDrawable_ = None;
- m_aRenderPicture = 0;
- m_pRenderFormat = NULL;
-
- pClipRegion_ = NULL;
- pPaintRegion_ = NULL;
-
- pPenGC_ = NULL;
- nPenPixel_ = 0;
- nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
- pFontGC_ = NULL;
- for( int i = 0; i < MAX_FALLBACK; ++i )
- {
- mXFont[i] = NULL;
- mpServerFont[i] = NULL;
- }
-
- nTextPixel_ = 0;
- nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
- pBrushGC_ = NULL;
- nBrushPixel_ = 0;
- nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
- hBrush_ = None;
-
- pMonoGC_ = NULL;
- pCopyGC_ = NULL;
- pMaskGC_ = NULL;
- pInvertGC_ = NULL;
- pInvert50GC_ = NULL;
- pStippleGC_ = NULL;
- pTrackingGC_ = NULL;
-
- bWindow_ = FALSE;
- bPrinter_ = FALSE;
- bVirDev_ = FALSE;
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
- bXORMode_ = FALSE;
- bDitherBrush_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-X11SalGraphics::~X11SalGraphics()
-{
- ReleaseFonts();
- freeResources();
-}
-
-// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-void X11SalGraphics::freeResources()
-{
- Display *pDisplay = GetXDisplay();
-
- DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" );
- if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None;
-
- if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None;
- if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
- if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
- if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
- if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
- if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
- if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
- if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
- if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
- if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
- if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
- if( m_pDeleteColormap )
- delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL;
-
- if( m_aRenderPicture )
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
-
- bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false;
-}
-
-void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen )
-{
- // shortcut if nothing changed
- if( hDrawable_ == aDrawable )
- return;
-
- // free screen specific resources if needed
- if( nScreen != m_nScreen )
- {
- freeResources();
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen );
- m_nScreen = nScreen;
- }
-
- hDrawable_ = aDrawable;
- SetXRenderFormat( NULL );
- if( m_aRenderPicture )
- {
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture );
- m_aRenderPicture = 0;
- }
-
- if( hDrawable_ )
- {
- nPenPixel_ = GetPixel( nPenColor_ );
- nTextPixel_ = GetPixel( nTextColor_ );
- nBrushPixel_ = GetPixel( nBrushColor_ );
- }
-}
-
-void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen )
-{
-#if 0 // TODO: use SetDrawable() instead
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
- hDrawable_ = aTarget;
- m_nScreen = nScreen;
- SetXRenderFormat( NULL );
- if( m_aRenderPicture )
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
-
- nPenPixel_ = GetPixel( nPenColor_ );
- nTextPixel_ = GetPixel( nTextColor_ );
- nBrushPixel_ = GetPixel( nBrushColor_ );
-#else
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
- m_nScreen = nScreen;
- SetDrawable( aTarget, nScreen );
-#endif
-
- bWindow_ = TRUE;
- m_pFrame = pFrame;
- m_pVDev = NULL;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::DeInit()
-{
- SetDrawable( None, m_nScreen );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const
-{
- Display *pDisplay = GetXDisplay();
-
- int n = 0;
- XLIB_Region Regions[3];
-
- if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ )
- Regions[n++] = pClipRegion_;
-// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ )
-// Regions[n++] = pPaintRegion_;
-
- if( pXReg && !XEmptyRegion( pXReg ) )
- Regions[n++] = pXReg;
-
- if( 0 == n )
- XSetClipMask( pDisplay, pGC, None );
- else if( 1 == n )
- XSetRegion( pDisplay, pGC, Regions[0] );
- else
- {
- XLIB_Region pTmpRegion = XCreateRegion();
- XIntersectRegion( Regions[0], Regions[1], pTmpRegion );
-// if( 3 == n )
-// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion );
- XSetRegion( pDisplay, pGC, pTmpRegion );
- XDestroyRegion( pTmpRegion );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::SelectPen()
-{
- Display *pDisplay = GetXDisplay();
-
- if( !pPenGC_ )
- {
- XGCValues values;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pPenGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bPenGC_ )
- {
- if( nPenColor_ != SALCOLOR_NONE )
- XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
- XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pPenGC_ );
- bPenGC_ = TRUE;
- }
-
- return pPenGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::SelectBrush()
-{
- Display *pDisplay = GetXDisplay();
-
- DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
-
- if( !pBrushGC_ )
- {
- XGCValues values;
- // values.subwindow_mode = IncludeInferiors;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bBrushGC_ )
- {
- if( !bDitherBrush_ )
- {
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
- XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
- #if defined(_USE_PRINT_EXTENSION_)
- XSetBackground( pDisplay, pBrushGC_,
- WhitePixel(pDisplay, DefaultScreen(pDisplay)) );
- #else
- if( bPrinter_ )
- XSetTile( pDisplay, pBrushGC_, None );
- #endif
- }
- else
- {
- // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect
- // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
- if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
-
- XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
- XSetTile ( pDisplay, pBrushGC_, hBrush_ );
- }
- XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pBrushGC_ );
-
- bBrushGC_ = TRUE;
- }
-
- return pBrushGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::GetTrackingGC()
-{
- const char dash_list[2] = {2, 2};
-
- if( !pTrackingGC_ )
- {
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetBlackPixel()
- ^ m_pColormap->GetWhitePixel();
- values.function = GXxor;
- values.line_width = 1;
- values.line_style = LineOnOffDash;
-
- pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
- GCGraphicsExposures | GCForeground | GCFunction
- | GCLineWidth | GCLineStyle,
- &values );
- XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
- }
-
- if( !bTrackingGC_ )
- {
- SetClipRegion( pTrackingGC_ );
- bTrackingGC_ = TRUE;
- }
-
- return pTrackingGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::DrawLines( ULONG nPoints,
- const SalPolyLine &rPoints,
- GC pGC,
- bool bClose
- )
-{
- // errechne wie viele Linien XWindow auf einmal zeichnen kann
- ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
- / sizeof(xPoint);
- if( nMaxLines > nPoints ) nMaxLines = nPoints;
-
- // gebe alle Linien aus, die XWindows zeichnen kann.
- ULONG n;
- for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nMaxLines,
- CoordModeOrigin );
-
- if( n < nPoints )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nPoints - n,
- CoordModeOrigin );
- if( bClose )
- {
- if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
- drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// Dithern: Calculate a dither-pixmap and make a brush of it
-#define P_DELTA 51
-#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
-
-BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor )
-{
- static const short nOrdDither8Bit[ 8 ][ 8 ] =
- {
- { 0, 38, 9, 48, 2, 40, 12, 50},
- {25, 12, 35, 22, 28, 15, 37, 24},
- { 6, 44, 3, 41, 8, 47, 5, 44},
- {32, 19, 28, 16, 34, 21, 31, 18},
- { 1, 40, 11, 49, 0, 39, 10, 48},
- {27, 14, 36, 24, 26, 13, 36, 23},
- { 8, 46, 4, 43, 7, 45, 4, 42},
- {33, 20, 30, 17, 32, 20, 29, 16}
- };
-
- // test for correct depth (8bit)
- if( GetColormap().GetVisual().GetDepth() != 8 )
- return FALSE;
-
- char pBits[64];
- char *pBitsPtr = pBits;
-
- // Set the pallette-entries for the dithering tile
- UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor );
- UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor );
- UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor );
-
- for( int nY = 0; nY < 8; nY++ )
- {
- for( int nX = 0; nX < 8; nX++ )
- {
- short nMagic = nOrdDither8Bit[nY][nX];
- UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic );
- UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic );
- UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic );
-
- *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) );
- }
- }
-
- // create the tile as ximage and an according pixmap -> caching
- XImage *pImage = XCreateImage( GetXDisplay(),
- GetColormap().GetXVisual(),
- 8,
- ZPixmap,
- 0, // offset
- pBits, // data
- 8, 8, // width & height
- 8, // bitmap_pad
- 0 ); // (default) bytes_per_line
-
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile )
- {
- if (hBrush_)
- XFreePixmap (GetXDisplay(), hBrush_);
- hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
- }
- else
- if( !hBrush_ )
- hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
-
- // put the ximage to the pixmap
- XPutImage( GetXDisplay(),
- hBrush_,
- GetDisplay()->GetCopyGC( m_nScreen ),
- pImage,
- 0, 0, // Source
- 0, 0, // Destination
- 8, 8 ); // width & height
-
- // destroy image-frame but not palette-data
- pImage->data = NULL;
- XDestroyImage( pImage );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const
-{
- const SalDisplay *pDisplay = GetDisplay();
-
- rDPIX = pDisplay->GetResolution().A();
- rDPIY = pDisplay->GetResolution().B();
- if( !pDisplay->GetExactResolution() && rDPIY < 96 )
- {
- rDPIX = Divide( rDPIX * 96, rDPIY );
- rDPIY = 96;
- }
- else if ( rDPIY > 200 )
- {
- rDPIX = Divide( rDPIX * 200, rDPIY );
- rDPIY = 200;
- }
-
- // #i12705# equalize x- and y-resolution if they are close enough
- if( rDPIX != rDPIY )
- {
- // different x- and y- resolutions are usually artifacts of
- // a wrongly calculated screen size.
- //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30%
- {
-#ifdef DEBUG
- printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n",
- rDPIX,rDPIY,rDPIY,rDPIY);
-#endif
- rDPIX = rDPIY; // y-resolution is more trustworthy
- }
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-USHORT X11SalGraphics::GetBitCount() // const
-{
- return GetVisual().GetDepth();
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-long X11SalGraphics::GetGraphicsWidth() const
-{
- if( m_pFrame )
- return m_pFrame->maGeometry.nWidth;
- else if( m_pVDev )
- return m_pVDev->GetWidth();
- else
- return 0;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-long X11SalGraphics::GetGraphicsHeight() const
-{
- if( m_pFrame )
- return m_pFrame->maGeometry.nHeight;
- else if( m_pVDev )
- return m_pVDev->GetHeight();
- else
- return 0;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::ResetClipRegion()
-{
- if( pClipRegion_ )
- {
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
-
- XDestroyRegion( pClipRegion_ );
- pClipRegion_ = NULL;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::BeginSetClipRegion( ULONG )
-{
- if( pClipRegion_ )
- XDestroyRegion( pClipRegion_ );
- pClipRegion_ = XCreateRegion();
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY )
-{
- if (!nDX || !nDY)
- return TRUE;
-
- XRectangle aRect;
- aRect.x = (short)nX;
- aRect.y = (short)nY;
- aRect.width = (unsigned short)nDX;
- aRect.height = (unsigned short)nDY;
-
- XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& )
-{
- // TODO: implement and advertise OutDevSupport_B2DClip support
- return false;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::EndSetClipRegion()
-{
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
-
- if( XEmptyRegion( pClipRegion_ ) )
- {
- XDestroyRegion( pClipRegion_ );
- pClipRegion_= NULL;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetLineColor()
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetLineColor( SalColor nSalColor )
-{
- if( nPenColor_ != nSalColor )
- {
- nPenColor_ = nSalColor;
- nPenPixel_ = GetPixel( nSalColor );
- bPenGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetFillColor()
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- bDitherBrush_ = FALSE;
- nBrushColor_ = SALCOLOR_NONE;
- bBrushGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetFillColor( SalColor nSalColor )
-{
- if( nBrushColor_ != nSalColor )
- {
- bDitherBrush_ = FALSE;
- nBrushColor_ = nSalColor;
- nBrushPixel_ = GetPixel( nSalColor );
- if( TrueColor != GetColormap().GetVisual().GetClass()
- && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
- && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
- bDitherBrush_ = GetDitherPixmap(nSalColor);
- bBrushGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor )
-{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nPenPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- nPenColor_ = GetColormap().GetColor( nPenPixel_ );
- bPenGC_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor )
-{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nBrushPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- bDitherBrush_ = FALSE;
- nBrushColor_ = GetColormap().GetColor( nBrushPixel_ );
- bBrushGC_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetXORMode( bool bSet, bool )
-{
- if( !bXORMode_ == bSet )
- {
- bXORMode_ = bSet;
- bPenGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPixel( long nX, long nY )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY );
-}
-
-void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
-{
- if( nSalColor != SALCOLOR_NONE )
- {
- Display *pDisplay = GetXDisplay();
-
- if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
- {
- SetLineColor( nSalColor );
- XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY );
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = False;
- }
- else
- {
- GC pGC = SelectPen();
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) );
-
- XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY );
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, nPenPixel_ );
- }
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
- {
- GC aGC = SelectPen();
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1);
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2);
- XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
- }
- else
- XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(),
- nX1, nY1, nX2, nY2 );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY )
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- nX, nY, nDX, nDY );
- }
- // Beschreibung DrawRect verkehrt, deshalb -1
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawRectangle( GetXDisplay(),
- GetDrawable(),
- SelectPen(),
- nX, nY, nDX-1, nDY-1 );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry )
-{
- drawPolyLine( nPoints, pPtAry, false );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose )
-{
- if( nPenColor_ != 0xFFFFFFFF )
- {
- SalPolyLine Points( nPoints, pPtAry );
-
- DrawLines( nPoints, Points, SelectPen(), bClose );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry )
-{
- if( nPoints == 0 )
- return;
-
- if( nPoints < 3 )
- {
- if( !bXORMode_ )
- {
- if( 1 == nPoints )
- drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
- else
- drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
- pPtAry[1].mnX, pPtAry[1].mnY );
- }
- return;
- }
-
- SalPolyLine Points( nPoints, pPtAry );
-
- nPoints++;
-
- /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
- * do not draw the visible part of a polygon
- * if it overlaps to the left of screen 0,y.
- * This happens to be the case in the gradient drawn in the
- * menubar background. workaround for the special case of
- * of a rectangle overlapping to the left.
- */
- if( nPoints == 5 &&
- Points[ 0 ].x == Points[ 1 ].x &&
- Points[ 1 ].y == Points[ 2 ].y &&
- Points[ 2 ].x == Points[ 3 ].x &&
- Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
- )
- {
- bool bLeft = false;
- bool bRight = false;
- for(unsigned int i = 0; i < nPoints; i++ )
- {
- if( Points[i].x < 0 )
- bLeft = true;
- else
- bRight= true;
- }
- if( bLeft && ! bRight )
- return;
- if( bLeft && bRight )
- {
- for( unsigned int i = 0; i < nPoints; i++ )
- if( Points[i].x < 0 )
- Points[i].x = 0;
- }
- }
-
- if( nBrushColor_ != SALCOLOR_NONE )
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-
- if( nPenColor_ != 0xFFFFFFFF )
- DrawLines( nPoints, Points, SelectPen(), true );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
- const sal_uInt32 *pPoints,
- PCONSTSALPOINT *pPtAry )
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- ULONG i, n;
- XLIB_Region pXRegA = NULL;
-
- for( i = 0; i < nPoly; i++ ) {
- n = pPoints[i];
- SalPolyLine Points( n, pPtAry[i] );
- if( n > 2 )
- {
- XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
- if( !pXRegA )
- pXRegA = pXRegB;
- else
- {
- XXorRegion( pXRegA, pXRegB, pXRegA );
- XDestroyRegion( pXRegB );
- }
- }
- }
-
- if( pXRegA )
- {
- XRectangle aXRect;
- XClipBox( pXRegA, &aXRect );
-
- GC pGC = SelectBrush();
- SetClipRegion( pGC, pXRegA ); // ??? doppelt
- XDestroyRegion( pXRegA );
- bBrushGC_ = FALSE;
-
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- pGC,
- aXRect.x, aXRect.y, aXRect.width, aXRect.height );
- }
- }
-
- if( nPenColor_ != SALCOLOR_NONE )
- for( ULONG i = 0; i < nPoly; i++ )
- drawPolyLine( pPoints[i], pPtAry[i], true );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
- const SalPoint* const*, const BYTE* const* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-void X11SalGraphics::invert( ULONG nPoints,
- const SalPoint* pPtAry,
- SalInvert nFlags )
-{
- SalPolyLine Points ( nPoints, pPtAry );
-
- GC pGC;
- if( SAL_INVERT_50 & nFlags )
- pGC = GetInvert50GC();
- else
- if ( SAL_INVERT_TRACKFRAME & nFlags )
- pGC = GetTrackingGC();
- else
- pGC = GetInvertGC();
-
- if( SAL_INVERT_TRACKFRAME & nFlags )
- DrawLines ( nPoints, Points, pGC, true );
- else
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- pGC,
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG )
-{
- return FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-XID X11SalGraphics::GetXRenderPicture()
-{
- if( !m_aRenderPicture )
- {
- // check xrender support for matching visual
- // find a XRenderPictFormat compatible with the Drawable
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat());
- if( !pVisualFormat )
- {
- Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
- pVisualFormat = rRenderPeer.FindVisualFormat( pVisual );
- if( !pVisualFormat )
- return 0;
- // cache the XRenderPictFormat
- SetXRenderFormat( static_cast<void*>(pVisualFormat) );
- }
-
- // get the matching xrender target for drawable
- m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL );
- }
-
-#if 0
- // setup clipping so the callers don't have to do it themselves
- // TODO: avoid clipping if already set correctly
- if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
-#endif
-
- return m_aRenderPicture;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-SystemGraphicsData X11SalGraphics::GetGraphicsData() const
-{
- SystemGraphicsData aRes;
-
- aRes.nSize = sizeof(aRes);
- aRes.pDisplay = GetXDisplay();
- aRes.hDrawable = hDrawable_;
- aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
- aRes.nScreen = m_nScreen;
- aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth();
- aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
- aRes.pRenderFormat = m_pRenderFormat;
- return aRes;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-// B2DPolygon support methods
-
-namespace { // anonymous namespace to prevent export
-// the methods and structures here are used by the
-// B2DPolyPolygon->RenderTrapezoid conversion algorithm
-
-// compare two line segments
-// assumption: both segments point downward
-// assumption: they must have at least some y-overlap
-// assumption: rA.p1.y <= rB.p1.y
-bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB )
-{
- bool bAbove = (rA.p1.y <= rB.p1.y);
- const XLineFixed& rU = bAbove ? rA : rB;
- const XLineFixed& rL = bAbove ? rB : rA;
-
- const XFixed aXDiff = rU.p2.x - rU.p1.x;
- const XFixed aYDiff = rU.p2.y - rU.p1.y;
-
- if( (rU.p1.y != rL.p1.y) || (rU.p1.x != rL.p1.x) )
- {
- const sal_Int64 n1 = (sal_Int64)aXDiff * (rL.p1.y - rU.p1.y);
- const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x);
- if( n1 != n2 )
- return ((n1 < n2) == bAbove);
- }
-
- if( (rU.p2.y != rL.p2.y) || (rU.p2.x != rL.p2.x) )
- {
- const sal_Int64 n3 = (sal_Int64)aXDiff * (rL.p2.y - rU.p1.y);
- const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x);
- if( n3 != n4 )
- return ((n3 < n4) == bAbove);
- }
-
- // both segments overlap
- return false;
-}
-
-struct HalfTrapezoid
-{
- // assumptions:
- // maLine.p1.y <= mnY < maLine.p2.y
- XLineFixed maLine;
- XFixed mnY;
-};
-
-struct HalfTrapCompare
-{
- bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const
- {
- bool bIsTopLeft = false;
- if( rA.mnY != rB.mnY ) // sort top-first if possible
- bIsTopLeft = (rA.mnY < rB.mnY);
- else // else sort left-first
- bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine );
- // adjust to priority_queue sorting convention
- return !bIsTopLeft;
- }
-};
-
-typedef std::priority_queue< HalfTrapezoid, std::vector<HalfTrapezoid>, HalfTrapCompare > HTQueueBase;
-// we need a priority queue with a reserve() to prevent countless reallocations
-class HTQueue
-: public HTQueueBase
-{
-public:
- void reserve( size_t n ) { c.reserve( n ); }
- int capacity() { return c.capacity(); }
-};
-
-typedef std::vector<XTrapezoid> TrapezoidVector;
-
-class TrapezoidXCompare
-{
- const TrapezoidVector& mrVector;
-public:
- TrapezoidXCompare( const TrapezoidVector& rVector )
- : mrVector( rVector ) {}
- bool operator()( int nA, int nB ) const
- { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); }
-};
-
-typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet;
-
-class TrapezoidYCompare
-{
- const TrapezoidVector& mrVector;
-public:
- TrapezoidYCompare( const TrapezoidVector& rVector )
- : mrVector( rVector ) {}
- bool operator()( int nA, int nB ) const
- { return (mrVector[nA].bottom < mrVector[nB].bottom); }
-};
-
-typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet;
-} // end of anonymous namespace
-
-// draw a poly-polygon
-bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
-{
- // nothing to do for empty polypolygons
- const int nPolygonCount = rPolyPoly.count();
- if( nPolygonCount <= 0 )
- return TRUE;
-
- // nothing to do if everything is transparent
- if( (nBrushColor_ == SALCOLOR_NONE)
- && (nPenColor_ == SALCOLOR_NONE) )
- return TRUE;
-
- // cannot handle pencolor!=brushcolor yet
- if( (nPenColor_ != SALCOLOR_NONE)
- && (nPenColor_ != nBrushColor_) )
- return FALSE;
-
- // TODO: remove the env-variable when no longer needed
- static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
- if( pRenderEnv )
- return FALSE;
-
- // check xrender support for trapezoids
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- if( !rRenderPeer.AreTrapezoidsSupported() )
- return FALSE;
- Picture aDstPic = GetXRenderPicture();
- // check xrender support for this drawable
- if( !aDstPic )
- return FALSE;
-
- // don't bother with polygons outside of visible area
- const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
- const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly );
- const bool bNeedViewClip = !aPolyRange.isInside( aViewRange );
- if( !aPolyRange.overlaps( aViewRange ) )
- return true;
-
- // convert the polypolygon to trapezoids
-
- // first convert the B2DPolyPolygon to HalfTrapezoids
- // #i100922# try to prevent priority-queue reallocations by reservering enough
- int nHTQueueReserve = 0;
- for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
- {
- const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
- const int nPointCount = aOuterPolygon.count();
- nHTQueueReserve += aOuterPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount;
- }
- nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1;
- HTQueue aHTQueue;
- aHTQueue.reserve( nHTQueueReserve );
- for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
- {
- const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
-
- // render-trapezoids should be inside the view => clip polygon against view range
- basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon );
- if( bNeedViewClip )
- {
- aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false );
- DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" );
- if( !aClippedPolygon.count() )
- continue;
- }
-
- // render-trapezoids have linear edges => get rid of bezier segments
- if( aClippedPolygon.areControlPointsUsed() )
- aClippedPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aClippedPolygon, 0.125 );
-
- // test and remove self intersections
- // TODO: make code intersection save, then remove this test
- basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon));
- const int nInnerPolyCount = aInnerPolyPoly.count();
- for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx )
- {
- ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx );
- const int nPointCount = aInnerPolygon.count();
- if( !nPointCount )
- continue;
-
- aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount );
-
- // convert polygon point pairs to HalfTrapezoids
- // connect the polygon point with the first one if needed
- XPointFixed aOldXPF = { 0, 0 };
- XPointFixed aNewXPF;
- for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF )
- {
- const int k = (nPointIdx < nPointCount) ? nPointIdx : 0;
- const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k );
-
- // convert the B2DPoint into XRENDER units
- if(getAntiAliasB2DDraw())
- {
- aNewXPF.x = XDoubleToFixed( aPoint.getX() );
- aNewXPF.y = XDoubleToFixed( aPoint.getY() );
- }
- else
- {
- aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) );
- aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) );
- }
-
- // check if enough data is available for a new HalfTrapezoid
- if( nPointIdx == 0 )
- continue;
- // ignore vertical segments
- if( aNewXPF.y == aOldXPF.y )
- continue;
-
- // construct HalfTrapezoid as topdown segment
- HalfTrapezoid aHT;
- if( aNewXPF.y < aOldXPF.y )
- {
- aHT.maLine.p1 = aNewXPF;
- aHT.maLine.p2 = aOldXPF;
- }
- else
- {
- aHT.maLine.p2 = aNewXPF;
- aHT.maLine.p1 = aOldXPF;
- }
-
- aHT.mnY = aHT.maLine.p1.y;
-
-#if 0 // ignore clipped HalfTrapezoids
- if( aHT.mnY < 0 )
- aHT.mnY = 0;
- else if( aHT.mnY > 10000 )
- continue;
-#endif
-
- // queue up the HalfTrapezoid
- aHTQueue.push( aHT );
- }
- }
- }
-
- if( aHTQueue.empty() )
- return TRUE;
-
- // then convert the HalfTrapezoids into full Trapezoids
- TrapezoidVector aTrapVector;
- aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess
-
- TrapezoidXCompare aTrapXCompare( aTrapVector );
- ActiveTrapSet aActiveTraps( aTrapXCompare );
-
- TrapezoidYCompare aTrapYCompare( aTrapVector );
- VerticalTrapSet aVerticalTraps( aTrapYCompare );
-
- while( !aHTQueue.empty() )
- {
- XTrapezoid aTrapezoid;
-
- // convert a HalfTrapezoid pair
- const HalfTrapezoid& rLeft = aHTQueue.top();
- aTrapezoid.top = rLeft.mnY;
- aTrapezoid.bottom = rLeft.maLine.p2.y;
- aTrapezoid.left = rLeft.maLine;
-
-#if 0
- // ignore empty trapezoids
- if( aTrapezoid.bottom <= aTrapezoid.top )
- continue;
-#endif
-
- aHTQueue.pop();
- if( aHTQueue.empty() ) // TODO: assert
- break;
- const HalfTrapezoid& rRight = aHTQueue.top();
- aTrapezoid.right = rRight.maLine;
- aHTQueue.pop();
-
- aTrapezoid.bottom = aTrapezoid.left.p2.y;
- if( aTrapezoid.bottom > aTrapezoid.right.p2.y )
- aTrapezoid.bottom = aTrapezoid.right.p2.y;
-
- // keep the full Trapezoid candidate
- aTrapVector.push_back( aTrapezoid );
-
- // unless it splits an older trapezoid
- bool bSplit = false;
- for(;;)
- {
- // check if the new trapezoid overlaps with an old trapezoid
- ActiveTrapSet::iterator aActiveTrapsIt
- = aActiveTraps.upper_bound( aTrapVector.size()-1 );
- if( aActiveTrapsIt == aActiveTraps.begin() )
- break;
- --aActiveTrapsIt;
-
- XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ];
-
- // in the ActiveTrapSet there are still trapezoids where
- // a vertical overlap with new trapezoids is no longer possible
- // they could have been removed in the verticaltraps loop below
- // but this would have been expensive and is not needed as we can
- // simply ignore them now and remove them from the ActiveTrapSet
- // so they won't bother us in the future
- if( rLeftTrap.bottom <= aTrapezoid.top )
- {
- aActiveTraps.erase( aActiveTrapsIt );
- continue;
- }
-
- // check if there is horizontal overlap
- // aTrapezoid.left==rLeftTrap.right is allowed though
- if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) )
- break;
-
- // split the old trapezoid and keep its upper part
- // find the old trapezoids entry in the VerticalTrapSet and remove it
- typedef std::pair<VerticalTrapSet::iterator, VerticalTrapSet::iterator> VTSPair;
- VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt );
- VerticalTrapSet::iterator aVTSit = aVTSPair.first;
- for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ;
- if( aVTSit != aVTSPair.second )
- aVerticalTraps.erase( aVTSit );
- // then update the old trapezoid's bottom
- rLeftTrap.bottom = aTrapezoid.top;
- // enter the updated old trapzoid in VerticalTrapSet
- aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt );
- // the old trapezoid is no longer active
- aActiveTraps.erase( aActiveTrapsIt );
-
- // the trapezoid causing the split has become obsolete
- // so its both sides have to be re-queued
- HalfTrapezoid aHT;
- aHT.mnY = aTrapezoid.top;
- aHT.maLine = aTrapezoid.left;
- aHTQueue.push( aHT );
- aHT.maLine = aTrapezoid.right;
- aHTQueue.push( aHT );
-
- bSplit = true;
- break;
- }
-
- // keep or forget the resulting full Trapezoid
- if( bSplit )
- aTrapVector.pop_back();
- else
- {
- aActiveTraps.insert( aTrapVector.size()-1 );
- aVerticalTraps.insert( aTrapVector.size()-1 );
- }
-
- // mark trapezoids that can no longer be split as inactive
- // and recycle their sides which were not fully resolved
- static const XFixed nMaxTop = +0x7FFFFFFF;
- XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY;
- while( !aVerticalTraps.empty() )
- {
- const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ];
- if( nNewTop < rOldTrap.bottom )
- break;
- // the reference Trapezoid can no longer be split
- aVerticalTraps.erase( aVerticalTraps.begin() );
-
- // recycle its sides that were not fully resolved
- HalfTrapezoid aHT;
- aHT.mnY = rOldTrap.bottom;
- if( rOldTrap.left.p2.y > rOldTrap.bottom )
- {
- aHT.maLine = rOldTrap.left;
- aHTQueue.push( aHT );
- }
- if( rOldTrap.right.p2.y > rOldTrap.bottom )
- {
- aHT.maLine = rOldTrap.right;
- aHTQueue.push( aHT );
- }
- }
- }
-
- // create xrender Picture for polygon foreground
- SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ];
- if( !rEntry.m_aPicture )
- {
- Display* pXDisplay = GetXDisplay();
-
- rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 );
- XRenderPictureAttributes aAttr;
- aAttr.repeat = true;
-
- XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
- rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
- }
-
- // set polygon foreground color and opacity
- XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency );
- rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
-
- // set clipping
- // TODO: move into GetXRenderPicture?
- if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
-
- // render the trapezoids
- const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
- rRenderPeer.CompositeTrapezoids( PictOpOver,
- rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin)
-{
- const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- if( !rRenderPeer.AreTrapezoidsSupported() )
- return false;
-
- // get the area polygon for the line polygon
- basegfx::B2DPolygon aPolygon = rPolygon;
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
- {
- // prepare for createAreaGeometry() with anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() );
- aPolygon.transform( aAnisoMatrix );
- }
-
- // AW: reSegment no longer needed; new createAreaGeometry will remove exteme positions
- // and create bezier polygons
- //if( aPolygon.areControlPointsUsed() )
- // aPolygon = basegfx::tools::reSegmentPolygonEdges( aPolygon, 8, true, false );
- //const basegfx::B2DPolyPolygon aAreaPolyPoly = basegfx::tools::createAreaGeometryForSimplePolygon(
- // aPolygon, 0.5*rLineWidth.getX(), eLineJoin );
- const basegfx::B2DPolyPolygon aAreaPolyPoly(basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin));
-
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
- {
- // postprocess createAreaGeometry() for anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() );
- aPolygon.transform( aAnisoMatrix );
- }
-
- // temporarily adjust brush color to pen color
- // since the line is drawn as an area-polygon
- const SalColor aKeepBrushColor = nBrushColor_;
- nBrushColor_ = nPenColor_;
-
- // draw each area polypolygon component individually
- // to emulate the polypolygon winding rule "non-zero"
- bool bDrawOk = true;
- const int nPolyCount = aAreaPolyPoly.count();
- for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
- {
- const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
- bDrawOk = drawPolyPolygon( aOnePoly, 0.0);
- if( !bDrawOk )
- break;
- }
-
- // restore the original brush GC
- nBrushColor_ = aKeepBrushColor;
- return bDrawOk;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*************************************************************************
+ *
+ * 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
+ *
+ * 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_vcl.hxx"
+
+#include "Xproto.h"
+
+#include "salunx.h"
+#include "saldata.hxx"
+#include "saldisp.hxx"
+#include "salgdi.h"
+#include "salframe.h"
+#include "salvd.h"
+#include "xrender_peer.hxx"
+
+#include "vcl/printergfx.hxx"
+#include "vcl/jobdata.hxx"
+
+#include "tools/debug.hxx"
+
+#include "basegfx/polygon/b2dpolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygon.hxx"
+#include "basegfx/polygon/b2dpolypolygontools.hxx"
+#include "basegfx/polygon/b2dpolygontools.hxx"
+#include "basegfx/polygon/b2dpolygonclipper.hxx"
+#include "basegfx/polygon/b2dlinegeometry.hxx"
+#include "basegfx/matrix/b2dhommatrix.hxx"
+#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
+
+#include <vector>
+#include <queue>
+#include <set>
+
+// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#define STATIC_POINTS 64
+
+class SalPolyLine
+{
+ XPoint Points_[STATIC_POINTS];
+ XPoint *pFirst_;
+public:
+ inline SalPolyLine( ULONG nPoints );
+ inline SalPolyLine( ULONG nPoints, const SalPoint *p );
+ inline ~SalPolyLine();
+ inline XPoint &operator [] ( ULONG n ) const
+ { return pFirst_[n]; }
+};
+
+inline SalPolyLine::SalPolyLine( ULONG nPoints )
+ : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
+{}
+
+inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p )
+ : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
+{
+ for( ULONG i = 0; i < nPoints; i++ )
+ {
+ pFirst_[i].x = (short)p[i].mnX;
+ pFirst_[i].y = (short)p[i].mnY;
+ }
+ pFirst_[nPoints] = pFirst_[0]; // close polyline
+}
+
+inline SalPolyLine::~SalPolyLine()
+{ if( pFirst_ != Points_ ) delete [] pFirst_; }
+
+#undef STATIC_POINTS
+// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+X11SalGraphics::X11SalGraphics()
+{
+ m_pFrame = NULL;
+ m_pVDev = NULL;
+ m_pDeleteColormap = NULL;
+ hDrawable_ = None;
+ m_aRenderPicture = 0;
+ m_pRenderFormat = NULL;
+
+ pClipRegion_ = NULL;
+ pPaintRegion_ = NULL;
+
+ pPenGC_ = NULL;
+ nPenPixel_ = 0;
+ nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
+
+ pFontGC_ = NULL;
+ for( int i = 0; i < MAX_FALLBACK; ++i )
+ {
+ mXFont[i] = NULL;
+ mpServerFont[i] = NULL;
+ }
+
+ nTextPixel_ = 0;
+ nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
+
+ pBrushGC_ = NULL;
+ nBrushPixel_ = 0;
+ nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
+ hBrush_ = None;
+
+ pMonoGC_ = NULL;
+ pCopyGC_ = NULL;
+ pMaskGC_ = NULL;
+ pInvertGC_ = NULL;
+ pInvert50GC_ = NULL;
+ pStippleGC_ = NULL;
+ pTrackingGC_ = NULL;
+
+ bWindow_ = FALSE;
+ bPrinter_ = FALSE;
+ bVirDev_ = FALSE;
+ bPenGC_ = FALSE;
+ bFontGC_ = FALSE;
+ bBrushGC_ = FALSE;
+ bMonoGC_ = FALSE;
+ bCopyGC_ = FALSE;
+ bInvertGC_ = FALSE;
+ bInvert50GC_ = FALSE;
+ bStippleGC_ = FALSE;
+ bTrackingGC_ = FALSE;
+ bXORMode_ = FALSE;
+ bDitherBrush_ = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+X11SalGraphics::~X11SalGraphics()
+{
+ ReleaseFonts();
+ freeResources();
+}
+
+// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void X11SalGraphics::freeResources()
+{
+ Display *pDisplay = GetXDisplay();
+
+ DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" );
+ if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None;
+
+ if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None;
+ if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
+ if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
+ if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
+ if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
+ if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
+ if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
+ if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
+ if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
+ if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
+ if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
+ if( m_pDeleteColormap )
+ delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL;
+
+ if( m_aRenderPicture )
+ XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
+
+ bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false;
+}
+
+void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen )
+{
+ // shortcut if nothing changed
+ if( hDrawable_ == aDrawable )
+ return;
+
+ // free screen specific resources if needed
+ if( nScreen != m_nScreen )
+ {
+ freeResources();
+ m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen );
+ m_nScreen = nScreen;
+ }
+
+ hDrawable_ = aDrawable;
+ SetXRenderFormat( NULL );
+ if( m_aRenderPicture )
+ {
+ XRenderPeer::GetInstance().FreePicture( m_aRenderPicture );
+ m_aRenderPicture = 0;
+ }
+
+ if( hDrawable_ )
+ {
+ nPenPixel_ = GetPixel( nPenColor_ );
+ nTextPixel_ = GetPixel( nTextColor_ );
+ nBrushPixel_ = GetPixel( nBrushColor_ );
+ }
+}
+
+void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen )
+{
+#if 0 // TODO: use SetDrawable() instead
+ m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
+ hDrawable_ = aTarget;
+ m_nScreen = nScreen;
+ SetXRenderFormat( NULL );
+ if( m_aRenderPicture )
+ XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
+
+ nPenPixel_ = GetPixel( nPenColor_ );
+ nTextPixel_ = GetPixel( nTextColor_ );
+ nBrushPixel_ = GetPixel( nBrushColor_ );
+#else
+ m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
+ m_nScreen = nScreen;
+ SetDrawable( aTarget, nScreen );
+#endif
+
+ bWindow_ = TRUE;
+ m_pFrame = pFrame;
+ m_pVDev = NULL;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::DeInit()
+{
+ SetDrawable( None, m_nScreen );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const
+{
+ Display *pDisplay = GetXDisplay();
+
+ int n = 0;
+ XLIB_Region Regions[3];
+
+ if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ )
+ Regions[n++] = pClipRegion_;
+// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ )
+// Regions[n++] = pPaintRegion_;
+
+ if( pXReg && !XEmptyRegion( pXReg ) )
+ Regions[n++] = pXReg;
+
+ if( 0 == n )
+ XSetClipMask( pDisplay, pGC, None );
+ else if( 1 == n )
+ XSetRegion( pDisplay, pGC, Regions[0] );
+ else
+ {
+ XLIB_Region pTmpRegion = XCreateRegion();
+ XIntersectRegion( Regions[0], Regions[1], pTmpRegion );
+// if( 3 == n )
+// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion );
+ XSetRegion( pDisplay, pGC, pTmpRegion );
+ XDestroyRegion( pTmpRegion );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+GC X11SalGraphics::SelectPen()
+{
+ Display *pDisplay = GetXDisplay();
+
+ if( !pPenGC_ )
+ {
+ XGCValues values;
+ values.subwindow_mode = ClipByChildren;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = False;
+
+ pPenGC_ = XCreateGC( pDisplay, hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !bPenGC_ )
+ {
+ if( nPenColor_ != SALCOLOR_NONE )
+ XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
+ XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
+ SetClipRegion( pPenGC_ );
+ bPenGC_ = TRUE;
+ }
+
+ return pPenGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+GC X11SalGraphics::SelectBrush()
+{
+ Display *pDisplay = GetXDisplay();
+
+ DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
+
+ if( !pBrushGC_ )
+ {
+ XGCValues values;
+ // values.subwindow_mode = IncludeInferiors;
+ values.subwindow_mode = ClipByChildren;
+ values.fill_rule = EvenOddRule; // Pict import/ Gradient
+ values.graphics_exposures = False;
+
+ pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
+ GCSubwindowMode | GCFillRule | GCGraphicsExposures,
+ &values );
+ }
+
+ if( !bBrushGC_ )
+ {
+ if( !bDitherBrush_ )
+ {
+ XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+ XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
+ #if defined(_USE_PRINT_EXTENSION_)
+ XSetBackground( pDisplay, pBrushGC_,
+ WhitePixel(pDisplay, DefaultScreen(pDisplay)) );
+ #else
+ if( bPrinter_ )
+ XSetTile( pDisplay, pBrushGC_, None );
+ #endif
+ }
+ else
+ {
+ // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect
+ // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
+ if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
+ XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
+
+ XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
+ XSetTile ( pDisplay, pBrushGC_, hBrush_ );
+ }
+ XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
+ SetClipRegion( pBrushGC_ );
+
+ bBrushGC_ = TRUE;
+ }
+
+ return pBrushGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+GC X11SalGraphics::GetTrackingGC()
+{
+ const char dash_list[2] = {2, 2};
+
+ if( !pTrackingGC_ )
+ {
+ XGCValues values;
+
+ values.graphics_exposures = False;
+ values.foreground = m_pColormap->GetBlackPixel()
+ ^ m_pColormap->GetWhitePixel();
+ values.function = GXxor;
+ values.line_width = 1;
+ values.line_style = LineOnOffDash;
+
+ pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
+ GCGraphicsExposures | GCForeground | GCFunction
+ | GCLineWidth | GCLineStyle,
+ &values );
+ XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
+ }
+
+ if( !bTrackingGC_ )
+ {
+ SetClipRegion( pTrackingGC_ );
+ bTrackingGC_ = TRUE;
+ }
+
+ return pTrackingGC_;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::DrawLines( ULONG nPoints,
+ const SalPolyLine &rPoints,
+ GC pGC,
+ bool bClose
+ )
+{
+ // errechne wie viele Linien XWindow auf einmal zeichnen kann
+ ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
+ / sizeof(xPoint);
+ if( nMaxLines > nPoints ) nMaxLines = nPoints;
+
+ // gebe alle Linien aus, die XWindows zeichnen kann.
+ ULONG n;
+ for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
+ XDrawLines( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nMaxLines,
+ CoordModeOrigin );
+
+ if( n < nPoints )
+ XDrawLines( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ &rPoints[n],
+ nPoints - n,
+ CoordModeOrigin );
+ if( bClose )
+ {
+ if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
+ drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+// Dithern: Calculate a dither-pixmap and make a brush of it
+#define P_DELTA 51
+#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
+
+BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor )
+{
+ static const short nOrdDither8Bit[ 8 ][ 8 ] =
+ {
+ { 0, 38, 9, 48, 2, 40, 12, 50},
+ {25, 12, 35, 22, 28, 15, 37, 24},
+ { 6, 44, 3, 41, 8, 47, 5, 44},
+ {32, 19, 28, 16, 34, 21, 31, 18},
+ { 1, 40, 11, 49, 0, 39, 10, 48},
+ {27, 14, 36, 24, 26, 13, 36, 23},
+ { 8, 46, 4, 43, 7, 45, 4, 42},
+ {33, 20, 30, 17, 32, 20, 29, 16}
+ };
+
+ // test for correct depth (8bit)
+ if( GetColormap().GetVisual().GetDepth() != 8 )
+ return FALSE;
+
+ char pBits[64];
+ char *pBitsPtr = pBits;
+
+ // Set the pallette-entries for the dithering tile
+ UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor );
+ UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor );
+ UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor );
+
+ for( int nY = 0; nY < 8; nY++ )
+ {
+ for( int nX = 0; nX < 8; nX++ )
+ {
+ short nMagic = nOrdDither8Bit[nY][nX];
+ UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic );
+ UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic );
+ UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic );
+
+ *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) );
+ }
+ }
+
+ // create the tile as ximage and an according pixmap -> caching
+ XImage *pImage = XCreateImage( GetXDisplay(),
+ GetColormap().GetXVisual(),
+ 8,
+ ZPixmap,
+ 0, // offset
+ pBits, // data
+ 8, 8, // width & height
+ 8, // bitmap_pad
+ 0 ); // (default) bytes_per_line
+
+ if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile )
+ {
+ if (hBrush_)
+ XFreePixmap (GetXDisplay(), hBrush_);
+ hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
+ }
+ else
+ if( !hBrush_ )
+ hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
+
+ // put the ximage to the pixmap
+ XPutImage( GetXDisplay(),
+ hBrush_,
+ GetDisplay()->GetCopyGC( m_nScreen ),
+ pImage,
+ 0, 0, // Source
+ 0, 0, // Destination
+ 8, 8 ); // width & height
+
+ // destroy image-frame but not palette-data
+ pImage->data = NULL;
+ XDestroyImage( pImage );
+
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const
+{
+ const SalDisplay *pDisplay = GetDisplay();
+
+ rDPIX = pDisplay->GetResolution().A();
+ rDPIY = pDisplay->GetResolution().B();
+ if( !pDisplay->GetExactResolution() && rDPIY < 96 )
+ {
+ rDPIX = Divide( rDPIX * 96, rDPIY );
+ rDPIY = 96;
+ }
+ else if ( rDPIY > 200 )
+ {
+ rDPIX = Divide( rDPIX * 200, rDPIY );
+ rDPIY = 200;
+ }
+
+ // #i12705# equalize x- and y-resolution if they are close enough
+ if( rDPIX != rDPIY )
+ {
+ // different x- and y- resolutions are usually artifacts of
+ // a wrongly calculated screen size.
+ //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30%
+ {
+#ifdef DEBUG
+ printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n",
+ rDPIX,rDPIY,rDPIY,rDPIY);
+#endif
+ rDPIX = rDPIY; // y-resolution is more trustworthy
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+USHORT X11SalGraphics::GetBitCount() // const
+{
+ return GetVisual().GetDepth();
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long X11SalGraphics::GetGraphicsWidth() const
+{
+ if( m_pFrame )
+ return m_pFrame->maGeometry.nWidth;
+ else if( m_pVDev )
+ return m_pVDev->GetWidth();
+ else
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+long X11SalGraphics::GetGraphicsHeight() const
+{
+ if( m_pFrame )
+ return m_pFrame->maGeometry.nHeight;
+ else if( m_pVDev )
+ return m_pVDev->GetHeight();
+ else
+ return 0;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::ResetClipRegion()
+{
+ if( pClipRegion_ )
+ {
+ bPenGC_ = FALSE;
+ bFontGC_ = FALSE;
+ bBrushGC_ = FALSE;
+ bMonoGC_ = FALSE;
+ bCopyGC_ = FALSE;
+ bInvertGC_ = FALSE;
+ bInvert50GC_ = FALSE;
+ bStippleGC_ = FALSE;
+ bTrackingGC_ = FALSE;
+
+ XDestroyRegion( pClipRegion_ );
+ pClipRegion_ = NULL;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::BeginSetClipRegion( ULONG )
+{
+ if( pClipRegion_ )
+ XDestroyRegion( pClipRegion_ );
+ pClipRegion_ = XCreateRegion();
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY )
+{
+ if (!nDX || !nDY)
+ return TRUE;
+
+ XRectangle aRect;
+ aRect.x = (short)nX;
+ aRect.y = (short)nY;
+ aRect.width = (unsigned short)nDX;
+ aRect.height = (unsigned short)nDY;
+
+ XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ );
+
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& )
+{
+ // TODO: implement and advertise OutDevSupport_B2DClip support
+ return false;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::EndSetClipRegion()
+{
+ bPenGC_ = FALSE;
+ bFontGC_ = FALSE;
+ bBrushGC_ = FALSE;
+ bMonoGC_ = FALSE;
+ bCopyGC_ = FALSE;
+ bInvertGC_ = FALSE;
+ bInvert50GC_ = FALSE;
+ bStippleGC_ = FALSE;
+ bTrackingGC_ = FALSE;
+
+ if( XEmptyRegion( pClipRegion_ ) )
+ {
+ XDestroyRegion( pClipRegion_ );
+ pClipRegion_= NULL;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetLineColor()
+{
+ if( nPenColor_ != SALCOLOR_NONE )
+ {
+ nPenColor_ = SALCOLOR_NONE;
+ bPenGC_ = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetLineColor( SalColor nSalColor )
+{
+ if( nPenColor_ != nSalColor )
+ {
+ nPenColor_ = nSalColor;
+ nPenPixel_ = GetPixel( nSalColor );
+ bPenGC_ = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetFillColor()
+{
+ if( nBrushColor_ != SALCOLOR_NONE )
+ {
+ bDitherBrush_ = FALSE;
+ nBrushColor_ = SALCOLOR_NONE;
+ bBrushGC_ = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetFillColor( SalColor nSalColor )
+{
+ if( nBrushColor_ != nSalColor )
+ {
+ bDitherBrush_ = FALSE;
+ nBrushColor_ = nSalColor;
+ nBrushPixel_ = GetPixel( nSalColor );
+ if( TrueColor != GetColormap().GetVisual().GetClass()
+ && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
+ && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
+ && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
+ && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
+ && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
+ bDitherBrush_ = GetDitherPixmap(nSalColor);
+ bBrushGC_ = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ nPenPixel_ = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
+ break;
+ }
+ nPenColor_ = GetColormap().GetColor( nPenPixel_ );
+ bPenGC_ = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor )
+{
+ switch( nROPColor )
+ {
+ case SAL_ROP_0 : // 0
+ nBrushPixel_ = (Pixel)0;
+ break;
+ case SAL_ROP_1 : // 1
+ nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
+ break;
+ case SAL_ROP_INVERT : // 2
+ nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
+ break;
+ }
+ bDitherBrush_ = FALSE;
+ nBrushColor_ = GetColormap().GetColor( nBrushPixel_ );
+ bBrushGC_ = FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::SetXORMode( bool bSet, bool )
+{
+ if( !bXORMode_ == bSet )
+ {
+ bXORMode_ = bSet;
+ bPenGC_ = FALSE;
+ bBrushGC_ = FALSE;
+ bMonoGC_ = FALSE;
+ bCopyGC_ = FALSE;
+ bInvertGC_ = FALSE;
+ bInvert50GC_ = FALSE;
+ bStippleGC_ = FALSE;
+ bTrackingGC_ = FALSE;
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawPixel( long nX, long nY )
+{
+ if( nPenColor_ != SALCOLOR_NONE )
+ XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY );
+}
+
+void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
+{
+ if( nSalColor != SALCOLOR_NONE )
+ {
+ Display *pDisplay = GetXDisplay();
+
+ if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
+ {
+ SetLineColor( nSalColor );
+ XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY );
+ nPenColor_ = SALCOLOR_NONE;
+ bPenGC_ = False;
+ }
+ else
+ {
+ GC pGC = SelectPen();
+
+ if( nSalColor != nPenColor_ )
+ XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) );
+
+ XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY );
+
+ if( nSalColor != nPenColor_ )
+ XSetForeground( pDisplay, pGC, nPenPixel_ );
+ }
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( nPenColor_ != SALCOLOR_NONE )
+ {
+ if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
+ {
+ GC aGC = SelectPen();
+ XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1);
+ XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2);
+ XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
+ }
+ else
+ XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(),
+ nX1, nY1, nX2, nY2 );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY )
+{
+ if( nBrushColor_ != SALCOLOR_NONE )
+ {
+ XFillRectangle( GetXDisplay(),
+ GetDrawable(),
+ SelectBrush(),
+ nX, nY, nDX, nDY );
+ }
+ // Beschreibung DrawRect verkehrt, deshalb -1
+ if( nPenColor_ != SALCOLOR_NONE )
+ XDrawRectangle( GetXDisplay(),
+ GetDrawable(),
+ SelectPen(),
+ nX, nY, nDX-1, nDY-1 );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry )
+{
+ drawPolyLine( nPoints, pPtAry, false );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose )
+{
+ if( nPenColor_ != 0xFFFFFFFF )
+ {
+ SalPolyLine Points( nPoints, pPtAry );
+
+ DrawLines( nPoints, Points, SelectPen(), bClose );
+ }
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry )
+{
+ if( nPoints == 0 )
+ return;
+
+ if( nPoints < 3 )
+ {
+ if( !bXORMode_ )
+ {
+ if( 1 == nPoints )
+ drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ else
+ drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ }
+ return;
+ }
+
+ SalPolyLine Points( nPoints, pPtAry );
+
+ nPoints++;
+
+ /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
+ * do not draw the visible part of a polygon
+ * if it overlaps to the left of screen 0,y.
+ * This happens to be the case in the gradient drawn in the
+ * menubar background. workaround for the special case of
+ * of a rectangle overlapping to the left.
+ */
+ if( nPoints == 5 &&
+ Points[ 0 ].x == Points[ 1 ].x &&
+ Points[ 1 ].y == Points[ 2 ].y &&
+ Points[ 2 ].x == Points[ 3 ].x &&
+ Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
+ )
+ {
+ bool bLeft = false;
+ bool bRight = false;
+ for(unsigned int i = 0; i < nPoints; i++ )
+ {
+ if( Points[i].x < 0 )
+ bLeft = true;
+ else
+ bRight= true;
+ }
+ if( bLeft && ! bRight )
+ return;
+ if( bLeft && bRight )
+ {
+ for( unsigned int i = 0; i < nPoints; i++ )
+ if( Points[i].x < 0 )
+ Points[i].x = 0;
+ }
+ }
+
+ if( nBrushColor_ != SALCOLOR_NONE )
+ XFillPolygon( GetXDisplay(),
+ GetDrawable(),
+ SelectBrush(),
+ &Points[0], nPoints,
+ Complex, CoordModeOrigin );
+
+ if( nPenColor_ != 0xFFFFFFFF )
+ DrawLines( nPoints, Points, SelectPen(), true );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
+ const sal_uInt32 *pPoints,
+ PCONSTSALPOINT *pPtAry )
+{
+ if( nBrushColor_ != SALCOLOR_NONE )
+ {
+ ULONG i, n;
+ XLIB_Region pXRegA = NULL;
+
+ for( i = 0; i < nPoly; i++ ) {
+ n = pPoints[i];
+ SalPolyLine Points( n, pPtAry[i] );
+ if( n > 2 )
+ {
+ XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
+ if( !pXRegA )
+ pXRegA = pXRegB;
+ else
+ {
+ XXorRegion( pXRegA, pXRegB, pXRegA );
+ XDestroyRegion( pXRegB );
+ }
+ }
+ }
+
+ if( pXRegA )
+ {
+ XRectangle aXRect;
+ XClipBox( pXRegA, &aXRect );
+
+ GC pGC = SelectBrush();
+ SetClipRegion( pGC, pXRegA ); // ??? doppelt
+ XDestroyRegion( pXRegA );
+ bBrushGC_ = FALSE;
+
+ XFillRectangle( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ aXRect.x, aXRect.y, aXRect.width, aXRect.height );
+ }
+ }
+
+ if( nPenColor_ != SALCOLOR_NONE )
+ for( ULONG i = 0; i < nPoly; i++ )
+ drawPolyLine( pPoints[i], pPtAry[i], true );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* )
+{
+ return sal_False;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* )
+{
+ return sal_False;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
+ const SalPoint* const*, const BYTE* const* )
+{
+ return sal_False;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+void X11SalGraphics::invert( ULONG nPoints,
+ const SalPoint* pPtAry,
+ SalInvert nFlags )
+{
+ SalPolyLine Points ( nPoints, pPtAry );
+
+ GC pGC;
+ if( SAL_INVERT_50 & nFlags )
+ pGC = GetInvert50GC();
+ else
+ if ( SAL_INVERT_TRACKFRAME & nFlags )
+ pGC = GetTrackingGC();
+ else
+ pGC = GetInvertGC();
+
+ if( SAL_INVERT_TRACKFRAME & nFlags )
+ DrawLines ( nPoints, Points, pGC, true );
+ else
+ XFillPolygon( GetXDisplay(),
+ GetDrawable(),
+ pGC,
+ &Points[0], nPoints,
+ Complex, CoordModeOrigin );
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG )
+{
+ return FALSE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+XID X11SalGraphics::GetXRenderPicture()
+{
+ if( !m_aRenderPicture )
+ {
+ // check xrender support for matching visual
+ // find a XRenderPictFormat compatible with the Drawable
+ XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+ XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat());
+ if( !pVisualFormat )
+ {
+ Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
+ pVisualFormat = rRenderPeer.FindVisualFormat( pVisual );
+ if( !pVisualFormat )
+ return 0;
+ // cache the XRenderPictFormat
+ SetXRenderFormat( static_cast<void*>(pVisualFormat) );
+ }
+
+ // get the matching xrender target for drawable
+ m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL );
+ }
+
+#if 0
+ // setup clipping so the callers don't have to do it themselves
+ // TODO: avoid clipping if already set correctly
+ if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
+ rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
+#endif
+
+ return m_aRenderPicture;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+SystemGraphicsData X11SalGraphics::GetGraphicsData() const
+{
+ SystemGraphicsData aRes;
+
+ aRes.nSize = sizeof(aRes);
+ aRes.pDisplay = GetXDisplay();
+ aRes.hDrawable = hDrawable_;
+ aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
+ aRes.nScreen = m_nScreen;
+ aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth();
+ aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
+ aRes.pRenderFormat = m_pRenderFormat;
+ return aRes;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// B2DPolygon support methods
+
+namespace { // anonymous namespace to prevent export
+// the methods and structures here are used by the
+// B2DPolyPolygon->RenderTrapezoid conversion algorithm
+
+// compare two line segments
+// assumption: both segments point downward
+// assumption: they must have at least some y-overlap
+// assumption: rA.p1.y <= rB.p1.y
+bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB )
+{
+ bool bAbove = (rA.p1.y <= rB.p1.y);
+ const XLineFixed& rU = bAbove ? rA : rB;
+ const XLineFixed& rL = bAbove ? rB : rA;
+
+ const XFixed aXDiff = rU.p2.x - rU.p1.x;
+ const XFixed aYDiff = rU.p2.y - rU.p1.y;
+
+ if( (rU.p1.y != rL.p1.y) || (rU.p1.x != rL.p1.x) )
+ {
+ const sal_Int64 n1 = (sal_Int64)aXDiff * (rL.p1.y - rU.p1.y);
+ const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x);
+ if( n1 != n2 )
+ return ((n1 < n2) == bAbove);
+ }
+
+ if( (rU.p2.y != rL.p2.y) || (rU.p2.x != rL.p2.x) )
+ {
+ const sal_Int64 n3 = (sal_Int64)aXDiff * (rL.p2.y - rU.p1.y);
+ const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x);
+ if( n3 != n4 )
+ return ((n3 < n4) == bAbove);
+ }
+
+ // both segments overlap
+ return false;
+}
+
+struct HalfTrapezoid
+{
+ // assumptions:
+ // maLine.p1.y <= mnY < maLine.p2.y
+ XLineFixed maLine;
+ XFixed mnY;
+};
+
+struct HalfTrapCompare
+{
+ bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const
+ {
+ bool bIsTopLeft = false;
+ if( rA.mnY != rB.mnY ) // sort top-first if possible
+ bIsTopLeft = (rA.mnY < rB.mnY);
+ else // else sort left-first
+ bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine );
+ // adjust to priority_queue sorting convention
+ return !bIsTopLeft;
+ }
+};
+
+typedef std::priority_queue< HalfTrapezoid, std::vector<HalfTrapezoid>, HalfTrapCompare > HTQueueBase;
+// we need a priority queue with a reserve() to prevent countless reallocations
+class HTQueue
+: public HTQueueBase
+{
+public:
+ void reserve( size_t n ) { c.reserve( n ); }
+ int capacity() { return c.capacity(); }
+};
+
+typedef std::vector<XTrapezoid> TrapezoidVector;
+
+class TrapezoidXCompare
+{
+ const TrapezoidVector& mrVector;
+public:
+ TrapezoidXCompare( const TrapezoidVector& rVector )
+ : mrVector( rVector ) {}
+ bool operator()( int nA, int nB ) const
+ { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); }
+};
+
+typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet;
+
+class TrapezoidYCompare
+{
+ const TrapezoidVector& mrVector;
+public:
+ TrapezoidYCompare( const TrapezoidVector& rVector )
+ : mrVector( rVector ) {}
+ bool operator()( int nA, int nB ) const
+ { return (mrVector[nA].bottom < mrVector[nB].bottom); }
+};
+
+typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet;
+} // end of anonymous namespace
+
+// draw a poly-polygon
+bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
+{
+ // nothing to do for empty polypolygons
+ const int nPolygonCount = rPolyPoly.count();
+ if( nPolygonCount <= 0 )
+ return TRUE;
+
+ // nothing to do if everything is transparent
+ if( (nBrushColor_ == SALCOLOR_NONE)
+ && (nPenColor_ == SALCOLOR_NONE) )
+ return TRUE;
+
+ // cannot handle pencolor!=brushcolor yet
+ if( (nPenColor_ != SALCOLOR_NONE)
+ && (nPenColor_ != nBrushColor_) )
+ return FALSE;
+
+ // TODO: remove the env-variable when no longer needed
+ static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
+ if( pRenderEnv )
+ return FALSE;
+
+ // check xrender support for trapezoids
+ XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+ if( !rRenderPeer.AreTrapezoidsSupported() )
+ return FALSE;
+ Picture aDstPic = GetXRenderPicture();
+ // check xrender support for this drawable
+ if( !aDstPic )
+ return FALSE;
+
+ // don't bother with polygons outside of visible area
+ const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
+ const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly );
+ const bool bNeedViewClip = !aPolyRange.isInside( aViewRange );
+ if( !aPolyRange.overlaps( aViewRange ) )
+ return true;
+
+ // convert the polypolygon to trapezoids
+
+ // first convert the B2DPolyPolygon to HalfTrapezoids
+ // #i100922# try to prevent priority-queue reallocations by reservering enough
+ int nHTQueueReserve = 0;
+ for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
+ {
+ const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
+ const int nPointCount = aOuterPolygon.count();
+ nHTQueueReserve += aOuterPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount;
+ }
+ nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1;
+ HTQueue aHTQueue;
+ aHTQueue.reserve( nHTQueueReserve );
+ for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
+ {
+ const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
+
+ // render-trapezoids should be inside the view => clip polygon against view range
+ basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon );
+ if( bNeedViewClip )
+ {
+ aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false );
+ DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" );
+ if( !aClippedPolygon.count() )
+ continue;
+ }
+
+ // render-trapezoids have linear edges => get rid of bezier segments
+ if( aClippedPolygon.areControlPointsUsed() )
+ aClippedPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aClippedPolygon, 0.125 );
+
+ // test and remove self intersections
+ // TODO: make code intersection save, then remove this test
+ basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon));
+ const int nInnerPolyCount = aInnerPolyPoly.count();
+ for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx )
+ {
+ ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx );
+ const int nPointCount = aInnerPolygon.count();
+ if( !nPointCount )
+ continue;
+
+ aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount );
+
+ // convert polygon point pairs to HalfTrapezoids
+ // connect the polygon point with the first one if needed
+ XPointFixed aOldXPF = { 0, 0 };
+ XPointFixed aNewXPF;
+ for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF )
+ {
+ const int k = (nPointIdx < nPointCount) ? nPointIdx : 0;
+ const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k );
+
+ // convert the B2DPoint into XRENDER units
+ if(getAntiAliasB2DDraw())
+ {
+ aNewXPF.x = XDoubleToFixed( aPoint.getX() );
+ aNewXPF.y = XDoubleToFixed( aPoint.getY() );
+ }
+ else
+ {
+ aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) );
+ aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) );
+ }
+
+ // check if enough data is available for a new HalfTrapezoid
+ if( nPointIdx == 0 )
+ continue;
+ // ignore vertical segments
+ if( aNewXPF.y == aOldXPF.y )
+ continue;
+
+ // construct HalfTrapezoid as topdown segment
+ HalfTrapezoid aHT;
+ if( aNewXPF.y < aOldXPF.y )
+ {
+ aHT.maLine.p1 = aNewXPF;
+ aHT.maLine.p2 = aOldXPF;
+ }
+ else
+ {
+ aHT.maLine.p2 = aNewXPF;
+ aHT.maLine.p1 = aOldXPF;
+ }
+
+ aHT.mnY = aHT.maLine.p1.y;
+
+#if 0 // ignore clipped HalfTrapezoids
+ if( aHT.mnY < 0 )
+ aHT.mnY = 0;
+ else if( aHT.mnY > 10000 )
+ continue;
+#endif
+
+ // queue up the HalfTrapezoid
+ aHTQueue.push( aHT );
+ }
+ }
+ }
+
+ if( aHTQueue.empty() )
+ return TRUE;
+
+ // then convert the HalfTrapezoids into full Trapezoids
+ TrapezoidVector aTrapVector;
+ aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess
+
+ TrapezoidXCompare aTrapXCompare( aTrapVector );
+ ActiveTrapSet aActiveTraps( aTrapXCompare );
+
+ TrapezoidYCompare aTrapYCompare( aTrapVector );
+ VerticalTrapSet aVerticalTraps( aTrapYCompare );
+
+ while( !aHTQueue.empty() )
+ {
+ XTrapezoid aTrapezoid;
+
+ // convert a HalfTrapezoid pair
+ const HalfTrapezoid& rLeft = aHTQueue.top();
+ aTrapezoid.top = rLeft.mnY;
+ aTrapezoid.bottom = rLeft.maLine.p2.y;
+ aTrapezoid.left = rLeft.maLine;
+
+#if 0
+ // ignore empty trapezoids
+ if( aTrapezoid.bottom <= aTrapezoid.top )
+ continue;
+#endif
+
+ aHTQueue.pop();
+ if( aHTQueue.empty() ) // TODO: assert
+ break;
+ const HalfTrapezoid& rRight = aHTQueue.top();
+ aTrapezoid.right = rRight.maLine;
+ aHTQueue.pop();
+
+ aTrapezoid.bottom = aTrapezoid.left.p2.y;
+ if( aTrapezoid.bottom > aTrapezoid.right.p2.y )
+ aTrapezoid.bottom = aTrapezoid.right.p2.y;
+
+ // keep the full Trapezoid candidate
+ aTrapVector.push_back( aTrapezoid );
+
+ // unless it splits an older trapezoid
+ bool bSplit = false;
+ for(;;)
+ {
+ // check if the new trapezoid overlaps with an old trapezoid
+ ActiveTrapSet::iterator aActiveTrapsIt
+ = aActiveTraps.upper_bound( aTrapVector.size()-1 );
+ if( aActiveTrapsIt == aActiveTraps.begin() )
+ break;
+ --aActiveTrapsIt;
+
+ XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ];
+
+ // in the ActiveTrapSet there are still trapezoids where
+ // a vertical overlap with new trapezoids is no longer possible
+ // they could have been removed in the verticaltraps loop below
+ // but this would have been expensive and is not needed as we can
+ // simply ignore them now and remove them from the ActiveTrapSet
+ // so they won't bother us in the future
+ if( rLeftTrap.bottom <= aTrapezoid.top )
+ {
+ aActiveTraps.erase( aActiveTrapsIt );
+ continue;
+ }
+
+ // check if there is horizontal overlap
+ // aTrapezoid.left==rLeftTrap.right is allowed though
+ if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) )
+ break;
+
+ // split the old trapezoid and keep its upper part
+ // find the old trapezoids entry in the VerticalTrapSet and remove it
+ typedef std::pair<VerticalTrapSet::iterator, VerticalTrapSet::iterator> VTSPair;
+ VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt );
+ VerticalTrapSet::iterator aVTSit = aVTSPair.first;
+ for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ;
+ if( aVTSit != aVTSPair.second )
+ aVerticalTraps.erase( aVTSit );
+ // then update the old trapezoid's bottom
+ rLeftTrap.bottom = aTrapezoid.top;
+ // enter the updated old trapzoid in VerticalTrapSet
+ aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt );
+ // the old trapezoid is no longer active
+ aActiveTraps.erase( aActiveTrapsIt );
+
+ // the trapezoid causing the split has become obsolete
+ // so its both sides have to be re-queued
+ HalfTrapezoid aHT;
+ aHT.mnY = aTrapezoid.top;
+ aHT.maLine = aTrapezoid.left;
+ aHTQueue.push( aHT );
+ aHT.maLine = aTrapezoid.right;
+ aHTQueue.push( aHT );
+
+ bSplit = true;
+ break;
+ }
+
+ // keep or forget the resulting full Trapezoid
+ if( bSplit )
+ aTrapVector.pop_back();
+ else
+ {
+ aActiveTraps.insert( aTrapVector.size()-1 );
+ aVerticalTraps.insert( aTrapVector.size()-1 );
+ }
+
+ // mark trapezoids that can no longer be split as inactive
+ // and recycle their sides which were not fully resolved
+ static const XFixed nMaxTop = +0x7FFFFFFF;
+ XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY;
+ while( !aVerticalTraps.empty() )
+ {
+ const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ];
+ if( nNewTop < rOldTrap.bottom )
+ break;
+ // the reference Trapezoid can no longer be split
+ aVerticalTraps.erase( aVerticalTraps.begin() );
+
+ // recycle its sides that were not fully resolved
+ HalfTrapezoid aHT;
+ aHT.mnY = rOldTrap.bottom;
+ if( rOldTrap.left.p2.y > rOldTrap.bottom )
+ {
+ aHT.maLine = rOldTrap.left;
+ aHTQueue.push( aHT );
+ }
+ if( rOldTrap.right.p2.y > rOldTrap.bottom )
+ {
+ aHT.maLine = rOldTrap.right;
+ aHTQueue.push( aHT );
+ }
+ }
+ }
+
+ // create xrender Picture for polygon foreground
+ SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ];
+ if( !rEntry.m_aPicture )
+ {
+ Display* pXDisplay = GetXDisplay();
+
+ rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 );
+ XRenderPictureAttributes aAttr;
+ aAttr.repeat = true;
+
+ XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
+ rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
+ }
+
+ // set polygon foreground color and opacity
+ XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency );
+ rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
+
+ // set clipping
+ // TODO: move into GetXRenderPicture?
+ if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
+ rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
+
+ // render the trapezoids
+ const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
+ rRenderPeer.CompositeTrapezoids( PictOpOver,
+ rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
+
+ return TRUE;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin)
+{
+ // #i101491#
+ if(rPolygon.count() > 1000)
+ {
+ // the used basegfx::tools::createAreaGeometry is simply too
+ // expensive with very big polygons; fallback to caller (who
+ // should use ImplLineConverter normally)
+ return false;
+ }
+
+ const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
+ if( !rRenderPeer.AreTrapezoidsSupported() )
+ return false;
+
+ // get the area polygon for the line polygon
+ basegfx::B2DPolygon aPolygon = rPolygon;
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
+ {
+ // prepare for createAreaGeometry() with anisotropic linewidth
+ basegfx::B2DHomMatrix aAnisoMatrix;
+ aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() );
+ aPolygon.transform( aAnisoMatrix );
+ }
+
+ // AW: reSegment no longer needed; new createAreaGeometry will remove exteme positions
+ // and create bezier polygons
+ //if( aPolygon.areControlPointsUsed() )
+ // aPolygon = basegfx::tools::reSegmentPolygonEdges( aPolygon, 8, true, false );
+ //const basegfx::B2DPolyPolygon aAreaPolyPoly = basegfx::tools::createAreaGeometryForSimplePolygon(
+ // aPolygon, 0.5*rLineWidth.getX(), eLineJoin );
+ const basegfx::B2DPolyPolygon aAreaPolyPoly(basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin));
+
+ if( (rLineWidth.getX() != rLineWidth.getY())
+ && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
+ {
+ // postprocess createAreaGeometry() for anisotropic linewidth
+ basegfx::B2DHomMatrix aAnisoMatrix;
+ aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() );
+ aPolygon.transform( aAnisoMatrix );
+ }
+
+ // temporarily adjust brush color to pen color
+ // since the line is drawn as an area-polygon
+ const SalColor aKeepBrushColor = nBrushColor_;
+ nBrushColor_ = nPenColor_;
+
+ // draw each area polypolygon component individually
+ // to emulate the polypolygon winding rule "non-zero"
+ bool bDrawOk = true;
+ const int nPolyCount = aAreaPolyPoly.count();
+ for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
+ {
+ const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
+ bDrawOk = drawPolyPolygon( aOnePoly, 0.0);
+ if( !bDrawOk )
+ break;
+ }
+
+ // restore the original brush GC
+ nBrushColor_ = aKeepBrushColor;
+ return bDrawOk;
+}
+
+// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx
index 22e43999caa6..04eb9cd32771 100644
--- a/vcl/unx/source/window/salframe.cxx
+++ b/vcl/unx/source/window/salframe.cxx
@@ -72,6 +72,7 @@
#include "tools/debug.hxx"
#include "sal/alloca.h"
+#include <com/sun/star/uno/Exception.hpp>
#include <algorithm>
@@ -425,15 +426,26 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa
if( IsOverrideRedirect() )
Attributes.override_redirect = True;
// default icon
- if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 &&
- SelectAppIconPixmap( pDisplay_, m_nScreen,
- mnIconID != 1 ? mnIconID :
- (mpParent ? mpParent->mnIconID : 1), 32,
- Hints.icon_pixmap, Hints.icon_mask ))
+ if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 )
{
- Hints.flags |= IconPixmapHint;
- if( Hints.icon_mask )
- Hints.flags |= IconMaskHint;
+ bool bOk=false;
+ try
+ {
+ bOk=SelectAppIconPixmap( pDisplay_, m_nScreen,
+ mnIconID != 1 ? mnIconID :
+ (mpParent ? mpParent->mnIconID : 1), 32,
+ Hints.icon_pixmap, Hints.icon_mask );
+ }
+ catch( com::sun::star::uno::Exception& )
+ {
+ // can happen - no ucb during early startup
+ }
+ if( bOk )
+ {
+ Hints.flags |= IconPixmapHint;
+ if( Hints.icon_mask )
+ Hints.flags |= IconMaskHint;
+ }
}
// find the top level frame of the transience hierarchy
diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx
index 8709fc872540..5c00c786e22d 100644
--- a/vcl/win/source/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx
@@ -64,75 +64,79 @@
void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon)
{
- const sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
- Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
- const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- rPath.AddBezier(
- aFCurr,
- Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
- Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
- aFNext);
- }
- else
- {
- rPath.AddLine(aFCurr, aFNext);
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
- aFCurr = aFNext;
- }
- }
- }
+ const sal_uInt32 nCount(rPolygon.count());
+
+ if(nCount)
+ {
+ const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
+ const bool bControls(rPolygon.areControlPointsUsed());
+ basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
+ Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
+
+ for(sal_uInt32 a(0); a < nEdgeCount; a++)
+ {
+ const sal_uInt32 nNextIndex((a + 1) % nCount);
+ const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
+ const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
+
+ if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
+ {
+ const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
+ const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
+
+ rPath.AddBezier(
+ aFCurr,
+ Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
+ Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
+ aFNext);
+ }
+ else
+ {
+ rPath.AddLine(aFCurr, aFNext);
+ }
+
+ if(a + 1 < nEdgeCount)
+ {
+ aCurr = aNext;
+ aFCurr = aFNext;
+ }
+ }
+ }
}
bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
{
- const sal_uInt32 nCount(rPolyPolygon.count());
+ const sal_uInt32 nCount(rPolyPolygon.count());
if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
{
- Gdiplus::Graphics aGraphics(mhDC);
+ Gdiplus::Graphics aGraphics(mhDC);
const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
- Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
- Gdiplus::SolidBrush aTestBrush(aTestColor);
- Gdiplus::GraphicsPath aPath;
+ Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
+ Gdiplus::SolidBrush aTestBrush(aTestColor);
+ Gdiplus::GraphicsPath aPath;
for(sal_uInt32 a(0); a < nCount; a++)
{
- aPath.StartFigure();
+ if(0 != a)
+ {
+ aPath.StartFigure(); // #i101491# not needed for first run
+ }
+
impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolyPolygon.getB2DPolygon(a));
aPath.CloseFigure();
}
if(getAntiAliasB2DDraw())
{
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
- }
-
- aGraphics.FillPath(&aTestBrush, &aPath);
+ aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ }
+ else
+ {
+ aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
+ }
+
+ aGraphics.FillPath(&aTestBrush, &aPath);
}
return true;
@@ -140,53 +144,59 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly
bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin)
{
- const sal_uInt32 nCount(rPolygon.count());
+ const sal_uInt32 nCount(rPolygon.count());
if(mbPen && nCount)
{
- Gdiplus::Graphics aGraphics(mhDC);
- Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
- Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
- Gdiplus::GraphicsPath aPath;
-
- switch(eLineJoin)
- {
+ Gdiplus::Graphics aGraphics(mhDC);
+ Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
+ Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
+ Gdiplus::GraphicsPath aPath;
+
+ switch(eLineJoin)
+ {
default : // basegfx::B2DLINEJOIN_NONE :
{
break;
}
case basegfx::B2DLINEJOIN_BEVEL :
{
- aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
+ aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
break;
}
case basegfx::B2DLINEJOIN_MIDDLE :
case basegfx::B2DLINEJOIN_MITER :
{
const Gdiplus::REAL aMiterLimit(15.0);
- aTestPen.SetMiterLimit(aMiterLimit);
- aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
+ aTestPen.SetMiterLimit(aMiterLimit);
+ aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
break;
}
case basegfx::B2DLINEJOIN_ROUND :
{
- aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
+ aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
break;
}
- }
+ }
impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolygon);
-
- if(getAntiAliasB2DDraw())
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
- }
-
- aGraphics.DrawPath(&aTestPen, &aPath);
+
+ if(rPolygon.isClosed())
+ {
+ // #i101491# needed to create the correct line joins
+ aPath.CloseFigure();
+ }
+
+ if(getAntiAliasB2DDraw())
+ {
+ aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
+ }
+ else
+ {
+ aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
+ }
+
+ aGraphics.DrawPath(&aTestPen, &aPath);
}
return true;
diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx
index 57ad272bcf51..3ffc358bd76d 100644
--- a/vcl/win/source/window/salframe.cxx
+++ b/vcl/win/source/window/salframe.cxx
@@ -6,9 +6,6 @@
*
* OpenOffice.org - a multi-platform office productivity suite
*
- * $RCSfile: salframe.cxx,v $
- * $Revision: 1.157.20.2 $
- *
* This file is part of OpenOffice.org.
*
* OpenOffice.org is free software: you can redistribute it and/or modify
@@ -355,11 +352,9 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst,
{
OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "user32" ) );
oslModule pLib = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT );
- void *pFunc = NULL;
+ oslGenericFunction pFunc = NULL;
if( pLib )
- {
pFunc = osl_getAsciiFunctionSymbol( pLib, "SetLayeredWindowAttributes" );
- }
lpfnSetLayeredWindowAttributes = ( SetLayeredWindowAttributes_Proc_T ) pFunc;
@@ -3155,7 +3150,8 @@ void WinSalFrame::Beep( SoundType eSoundType )
MB_ICONQUESTION // SOUND_QUERY
};
- MessageBeep( aImplSoundTab[eSoundType] );
+ if( eSoundType != SOUND_DISABLE ) // don't beep on disable
+ MessageBeep( aImplSoundTab[eSoundType] );
}
// -----------------------------------------------------------------------