summaryrefslogtreecommitdiff
path: root/svx/source/svdraw/svdoedge.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/svdraw/svdoedge.cxx')
-rw-r--r--svx/source/svdraw/svdoedge.cxx512
1 files changed, 278 insertions, 234 deletions
diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx
index 3d0fc70dad0c..1e47375d254c 100644
--- a/svx/source/svdraw/svdoedge.cxx
+++ b/svx/source/svdraw/svdoedge.cxx
@@ -43,7 +43,7 @@
#include <svx/svdtrans.hxx>
#include <svx/svdetc.hxx>
#include "svx/svdglob.hxx" // StringCache
-#include "svx/svdstr.hrc" // Objektname
+#include "svx/svdstr.hrc" // the object's name
#include <svl/style.hxx>
#include <svl/smplhint.hxx>
#include <editeng/eeitem.hxx>
@@ -77,7 +77,7 @@ void SdrObjConnection::ResetVars()
bool SdrObjConnection::TakeGluePoint(SdrGluePoint& rGP, bool bSetAbsPos) const
{
bool bRet = false;
- if (pObj!=NULL) { // Ein Obj muss schon angedockt sein!
+ if (pObj!=NULL) { // one object has to be docked already!
if (bAutoVertex) {
rGP=pObj->GetVertexGluePoint(nConId);
bRet = true;
@@ -450,12 +450,12 @@ SdrGluePoint SdrEdgeObj::GetCornerGluePoint(sal_uInt16 nNum) const
const SdrGluePointList* SdrEdgeObj::GetGluePointList() const
{
- return NULL; // Keine benutzerdefinierten Klebepunkte fuer Verbinder
+ return NULL; // no user defined glue points for connectors
}
SdrGluePointList* SdrEdgeObj::ForceGluePointList()
{
- return NULL; // Keine benutzerdefinierten Klebepunkte fuer Verbinder
+ return NULL; // no user defined glue points for connectors
}
bool SdrEdgeObj::IsEdge() const
@@ -552,7 +552,7 @@ void SdrEdgeObj::ImpRecalcEdgeTrack()
if(IsBoundRectCalculationRunning())
{
- // this object is involved into another ImpRecalcEdgeTrack() call
+ // This object is involved into another ImpRecalcEdgeTrack() call
// from another SdrEdgeObj. Do not calculate again to avoid loop.
// Also, do not change bEdgeTrackDirty so that it gets recalculated
// later at the first non-looping call.
@@ -561,7 +561,7 @@ void SdrEdgeObj::ImpRecalcEdgeTrack()
else if(GetModel() && GetModel()->isLocked())
{
// avoid re-layout during imports/API call sequences
- // #i45294# but calc EdgeTrack and secure properties there
+ // #i45294# but calculate EdgeTrack and secure properties there
((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_True;
*pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
ImpSetAttrToEdgeInfo();
@@ -570,14 +570,14 @@ void SdrEdgeObj::ImpRecalcEdgeTrack()
}
else
{
- // To not run in a depth loop, use a coloring algorythm on
+ // To not run in a depth loop, use a coloring algorithm on
// SdrEdgeObj BoundRect calculations
((SdrEdgeObj*)this)->mbBoundRectCalculationRunning = sal_True;
Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
SetRectsDirty();
*pEdgeTrack=ImpCalcEdgeTrack(*pEdgeTrack,aCon1,aCon2,&aEdgeInfo);
- ImpSetEdgeInfoToAttr(); // Die Werte aus aEdgeInfo in den Pool kopieren
+ ImpSetEdgeInfoToAttr(); // copy values from aEdgeInfo into the pool
bEdgeTrackDirty=sal_False;
// Only redraw here, no object change
@@ -602,25 +602,25 @@ sal_uInt16 SdrEdgeObj::ImpCalcEscAngle(SdrObject* pObj, const Point& rPt) const
long dx=Min(dxl,dxr);
long dy=Min(dyo,dyu);
bool bDiag=Abs(dx-dy)<2;
- if (bxMitt && byMitt) return SDRESC_ALL; // In der Mitte
- if (bDiag) { // diagonal
+ if (bxMitt && byMitt) return SDRESC_ALL; // in the center
+ if (bDiag) { // diagonally
sal_uInt16 nRet=0;
if (byMitt) nRet|=SDRESC_VERT;
if (bxMitt) nRet|=SDRESC_HORZ;
- if (dxl<dxr) { // Links
+ if (dxl<dxr) { // left
if (dyo<dyu) nRet|=SDRESC_LEFT | SDRESC_TOP;
else nRet|=SDRESC_LEFT | SDRESC_BOTTOM;
- } else { // Rechts
+ } else { // right
if (dyo<dyu) nRet|=SDRESC_RIGHT | SDRESC_TOP;
else nRet|=SDRESC_RIGHT | SDRESC_BOTTOM;
}
return nRet;
}
- if (dx<dy) { // waagerecht
+ if (dx<dy) { // horizontal
if (bxMitt) return SDRESC_HORZ;
if (dxl<dxr) return SDRESC_LEFT;
else return SDRESC_RIGHT;
- } else { // senkrecht
+ } else { // vertical
if (byMitt) return SDRESC_VERT;
if (dyo<dyu) return SDRESC_TOP;
else return SDRESC_BOTTOM;
@@ -636,13 +636,13 @@ XPolygon SdrEdgeObj::ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, cons
bool bLks=nEscAngle==18000;
bool bUnt=nEscAngle==27000;
- Point aP1(rStPt); // erstmal den Pflichtabstand
+ Point aP1(rStPt); // mandatory difference first,...
if (bLks) aP1.X()=rRect.Left();
if (bRts) aP1.X()=rRect.Right();
if (bObn) aP1.Y()=rRect.Top();
if (bUnt) aP1.Y()=rRect.Bottom();
- Point aP2(aP1); // Und nun den Pflichtabstand ggf. bis auf Meetinghoehe erweitern
+ Point aP2(aP1); // ...now increase to Meeting height, if necessary
if (bLks && rMeeting.X()<=aP2.X()) aP2.X()=rMeeting.X();
if (bRts && rMeeting.X()>=aP2.X()) aP2.X()=rMeeting.X();
if (bObn && rMeeting.Y()<=aP2.Y()) aP2.Y()=rMeeting.Y();
@@ -650,7 +650,7 @@ XPolygon SdrEdgeObj::ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, cons
aXP.Insert(XPOLY_APPEND,aP2,XPOLY_NORMAL);
Point aP3(aP2);
- if ((bLks && rMeeting.X()>aP2.X()) || (bRts && rMeeting.X()<aP2.X())) { // Aussenrum
+ if ((bLks && rMeeting.X()>aP2.X()) || (bRts && rMeeting.X()<aP2.X())) { // around
if (rMeeting.Y()<aP2.Y()) {
aP3.Y()=rRect.Top();
if (rMeeting.Y()<aP3.Y()) aP3.Y()=rMeeting.Y();
@@ -664,7 +664,7 @@ XPolygon SdrEdgeObj::ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, cons
aXP.Insert(XPOLY_APPEND,aP3,XPOLY_NORMAL);
}
}
- if ((bObn && rMeeting.Y()>aP2.Y()) || (bUnt && rMeeting.Y()<aP2.Y())) { // Aussenrum
+ if ((bObn && rMeeting.Y()>aP2.Y()) || (bUnt && rMeeting.Y()<aP2.Y())) { // around
if (rMeeting.X()<aP2.X()) {
aP3.X()=rRect.Left();
if (rMeeting.X()<aP3.X()) aP3.X()=rMeeting.X();
@@ -680,7 +680,7 @@ XPolygon SdrEdgeObj::ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, cons
}
#ifdef DBG_UTIL
if (aXP.GetPointCount()>4) {
- OSL_FAIL("SdrEdgeObj::ImpCalcObjToCenter(): Polygon hat mehr als 4 Punkte!");
+ OSL_FAIL("SdrEdgeObj::ImpCalcObjToCenter(): Polygon has more than 4 points!");
}
#endif
return aXP;
@@ -695,7 +695,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection&
Rectangle aBoundRect2;
Rectangle aBewareRect1;
Rectangle aBewareRect2;
- // Erstmal die alten Endpunkte wiederholen
+ // first, get the old corner points
if (rTrack0.GetPointCount()!=0) {
aPt1=rTrack0[0];
sal_uInt16 nSiz=rTrack0.GetPointCount();
@@ -714,7 +714,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection&
if (bCon1) {
if (rCon1.pObj==(SdrObject*)this)
{
- // sicherheitshalber Abfragen
+ // check, just in case
aBoundRect1=aOutRect;
}
else
@@ -737,7 +737,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection&
aBewareRect1=aBoundRect1;
}
if (bCon2) {
- if (rCon2.pObj==(SdrObject*)this) { // sicherheitshalber Abfragen
+ if (rCon2.pObj==(SdrObject*)this) { // check, just in case
aBoundRect2=aOutRect;
}
else
@@ -893,12 +893,12 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
Point aC1(aBewareRect1.Center());
Point aC2(aBewareRect2.Center());
if (aBewareRect1.Left()<=aBewareRect2.Right() && aBewareRect1.Right()>=aBewareRect2.Left()) {
- // Ueberschneidung auf der X-Achse
+ // overlapping on the x axis
long n1=Max(aBewareRect1.Left(),aBewareRect2.Left());
long n2=Min(aBewareRect1.Right(),aBewareRect2.Right());
aMeeting.X()=(n1+n2+1)/2;
} else {
- // Ansonsten den Mittelpunkt des Freiraums
+ // otherwise the center point of the empty space
if (aC1.X()<aC2.X()) {
aMeeting.X()=(aBewareRect1.Right()+aBewareRect2.Left()+1)/2;
} else {
@@ -906,22 +906,22 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
}
if (aBewareRect1.Top()<=aBewareRect2.Bottom() && aBewareRect1.Bottom()>=aBewareRect2.Top()) {
- // Ueberschneidung auf der Y-Achse
+ // overlapping on the x axis
long n1=Max(aBewareRect1.Top(),aBewareRect2.Top());
long n2=Min(aBewareRect1.Bottom(),aBewareRect2.Bottom());
aMeeting.Y()=(n1+n2+1)/2;
} else {
- // Ansonsten den Mittelpunkt des Freiraums
+ // otherwise the center point of the empty space
if (aC1.Y()<aC2.Y()) {
aMeeting.Y()=(aBewareRect1.Bottom()+aBewareRect2.Top()+1)/2;
} else {
aMeeting.Y()=(aBewareRect1.Top()+aBewareRect2.Bottom()+1)/2;
}
}
- // Im Prinzip gibt es 3 zu unterscheidene Faelle:
- // 1. Beide in die selbe Richtung
- // 2. Beide in genau entgegengesetzte Richtungen
- // 3. Einer waagerecht und der andere senkrecht
+ // Here, there are three cases:
+ // 1. both go into the same direction
+ // 2. both go into opposite directions
+ // 3. one is vertical, the other is horizontal
long nXMin=Min(aBewareRect1.Left(),aBewareRect2.Left());
long nXMax=Max(aBewareRect1.Right(),aBewareRect2.Right());
long nYMin=Min(aBewareRect1.Top(),aBewareRect2.Top());
@@ -931,10 +931,10 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
unsigned nMainCase=3;
if (nAngle1==nAngle2) nMainCase=1;
else if ((bHor1 && bHor2) || (bVer1 && bVer2)) nMainCase=2;
- if (nMainCase==1) { // Fall 1: Beide in eine Richtung moeglich.
- if (bVer1) aMeeting.X()=(aPt1.X()+aPt2.X()+1)/2; // ist hier besser, als der
- if (bHor1) aMeeting.Y()=(aPt1.Y()+aPt2.Y()+1)/2; // Mittelpunkt des Freiraums
- // bX1Ok bedeutet, dass die Vertikale, die aus Obj1 austritt, keinen Konflikt mit Obj2 bildet, ...
+ if (nMainCase==1) { // case 1 (both go in one direction) is possible
+ if (bVer1) aMeeting.X()=(aPt1.X()+aPt2.X()+1)/2; // Here, this is better than
+ if (bHor1) aMeeting.Y()=(aPt1.Y()+aPt2.Y()+1)/2; // using center point of empty space
+ // bX1Ok means that the vertical exiting Obj1 doesn't conflict with Obj2, ...
bool bX1Ok=aPt1.X()<=aBewareRect2.Left() || aPt1.X()>=aBewareRect2.Right();
bool bX2Ok=aPt2.X()<=aBewareRect1.Left() || aPt2.X()>=aBewareRect1.Right();
bool bY1Ok=aPt1.Y()<=aBewareRect2.Top() || aPt1.Y()>=aBewareRect2.Bottom();
@@ -952,49 +952,69 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
aMeeting.Y()=nYMax;
}
} else if (nMainCase==2) {
- // Fall 2:
- if (bHor1) { // beide waagerecht
- /* 9 Moeglichkeiten: � � � */
- /* 2.1 Gegenueber, Ueberschneidung � � � */
- /* nur auf der Y-Achse � � � */
- /* 2.2, 2.3 Gegenueber, vertikal versetzt. � � � � � � */
- /* Ueberschneidung weder auf der � � � � � � */
- /* X- noch auf der Y-Achse � � � � � � */
- /* 2.4, 2.5 Untereinander, � � � � � � */
- /* Ueberschneidung � � � � � � */
- /* nur auf X-Achse � � � � � � */
- /* 2.6, 2.7 Gegeneinander, vertikal versetzt. � � � � � � */
- /* Ueberschneidung weder auf der � � � � � � */
- /* X- noch auf der Y-Achse. � � � � � � */
- /* 2.8 Gegeneinander. � � � */
- /* Ueberschneidung nur � � � */
- /* auf der Y-Achse. � � � */
- /* 2.9 Die BewareRects der Objekte ueberschneiden */
- /* sich auf X- und Y-Achse. */
- /* Die Faelle gelten entsprechend umgesetzt auch fuer */
- /* senkrechte Linienaustritte. */
- /* Die Faelle 2.1-2.7 werden mit dem Default-Meeting ausreichend*/
- /* gut behandelt. Spezielle MeetingPoints werden hier also nur */
- /* fuer 2.8 und 2.9 bestimmt. */
-
- // Normalisierung. aR1 soll der nach rechts und
- // aR2 der nach links austretende sein.
+ // case 2:
+ if (bHor1) { // both horizontal
+ /* 9 sub-cases:
+ (legend: line exits to the left (-|), right (|-))
+
+ 2.1: Facing; overlap only on y axis
+ * * *
+ |--| *
+ * * *
+
+ 2.2, 2.3: Facing, offset vertically; no overlap on either
+ axis
+ |- * * * * *
+ * -| * * -| *
+ * * * , * * *
+
+ 2.4, 2.5: One below the other; overlap only on y axis
+ * |- * * * *
+ * -| * * -| *
+ * * * , * |- *
+
+ 2.6, 2.7: Not facing, offset vertically; no overlap on either
+ axis
+ * * |- * * *
+ * -| * * -| *
+ * * * , * * |-
+
+ 2.8: Not facing; overlap only on y axis
+ * * *
+ * -| |-
+ * * *
+
+ 2.9: The objects's BewareRects overlap on x and y axis
+
+ These cases, with some modifications are also valid for
+ horizontal line exits.
+ Cases 2.1 through 2.7 are covered well enough with the
+ default meetings. Only for cases 2.8 and 2.9 do we determine
+ special meeting points here.
+ */
+
+ // normalization; be aR1 the one exiting to the right,
+ // be aR2 the one exiting to the left
Rectangle aBewR1(bRts1 ? aBewareRect1 : aBewareRect2);
Rectangle aBewR2(bRts1 ? aBewareRect2 : aBewareRect1);
Rectangle aBndR1(bRts1 ? aBoundRect1 : aBoundRect2);
Rectangle aBndR2(bRts1 ? aBoundRect2 : aBoundRect1);
if (aBewR1.Bottom()>aBewR2.Top() && aBewR1.Top()<aBewR2.Bottom()) {
- // Ueberschneidung auf der Y-Achse. Faelle 2.1, 2.8, 2.9
+ // overlap on y axis; cases 2.1, 2.8, 2.9
if (aBewR1.Right()>aBewR2.Left()) {
- // Faelle 2.8, 2.9
- // Fall 2.8 ist immer Aussenrumlauf (bDirect=sal_False).
- // Fall 2.9 kann auch Direktverbindung sein (bei geringer
- // Ueberschneidung der BewareRects ohne Ueberschneidung der
- // Boundrects wenn die Linienaustritte sonst das BewareRect
- // des jeweils anderen Objekts verletzen wuerden.
+ /* Cases 2.8, 2.9:
+ Case 2.8: always going around on the outside
+ (bDirect=sal_False).
+
+ Case 2.9 could also be a direct connection (in the
+ case that the BewareRects overlap only slightly and
+ the BoundRects don't overlap at all and if the
+ line exits would otherwise violate the respective
+ other object's BewareRect).
+ */
bool bCase29Direct = false;
bool bCase29=aBewR1.Right()>aBewR2.Left();
- if (aBndR1.Right()<=aBndR2.Left()) { // Fall 2.9 und keine Boundrectueberschneidung
+ if (aBndR1.Right()<=aBndR2.Left()) { // case 2.9 without BoundRect overlap
if ((aPt1.Y()>aBewareRect2.Top() && aPt1.Y()<aBewareRect2.Bottom()) ||
(aPt2.Y()>aBewareRect1.Top() && aPt2.Y()<aBewareRect1.Bottom())) {
bCase29Direct = true;
@@ -1008,8 +1028,8 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
aMeeting.Y()=nYMax;
}
if (bCase29) {
- // und nun noch dafuer sorgen, dass das
- // umzingelte Obj nicht durchquert wird
+ // now make sure that the surrounded object
+ // isn't traversed
if ((aBewR1.Center().Y()<aBewR2.Center().Y()) != bObenLang) {
aMeeting.X()=aBewR2.Right();
} else {
@@ -1017,42 +1037,45 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
}
} else {
- // Direkte Verbindung (3-Linien Z-Verbindung), da
- // Verletzung der BewareRects unvermeidlich ist.
- // Via Dreisatz werden die BewareRects nun verkleinert.
- long nWant1=aBewR1.Right()-aBndR1.Right(); // Abstand bei Obj1
- long nWant2=aBndR2.Left()-aBewR2.Left(); // Abstand bei Obj2
- long nSpace=aBndR2.Left()-aBndR1.Right(); // verfuegbarer Platz
+ // We need a direct connection (3-line Z connection),
+ // because we have to violate the BewareRects.
+ // Use rule of three to scale down the BewareRects.
+ long nWant1=aBewR1.Right()-aBndR1.Right(); // distance at Obj1
+ long nWant2=aBndR2.Left()-aBewR2.Left(); // distance at Obj2
+ long nSpace=aBndR2.Left()-aBndR1.Right(); // available space
long nGet1=BigMulDiv(nWant1,nSpace,nWant1+nWant2);
long nGet2=nSpace-nGet1;
- if (bRts1) { // Normalisierung zurueckwandeln
+ if (bRts1) { // revert normalization
aBewareRect1.Right()+=nGet1-nWant1;
aBewareRect2.Left()-=nGet2-nWant2;
} else {
aBewareRect2.Right()+=nGet1-nWant1;
aBewareRect1.Left()-=nGet2-nWant2;
}
- nIntersections++; // Qualitaet herabsetzen
+ nIntersections++; // lower quality
}
}
}
- } else if (bVer1) { // beide senkrecht
+ } else if (bVer1) { // both horizontal
Rectangle aBewR1(bUnt1 ? aBewareRect1 : aBewareRect2);
Rectangle aBewR2(bUnt1 ? aBewareRect2 : aBewareRect1);
Rectangle aBndR1(bUnt1 ? aBoundRect1 : aBoundRect2);
Rectangle aBndR2(bUnt1 ? aBoundRect2 : aBoundRect1);
if (aBewR1.Right()>aBewR2.Left() && aBewR1.Left()<aBewR2.Right()) {
- // Ueberschneidung auf der Y-Achse. Faelle 2.1, 2.8, 2.9
+ // overlap on y axis; cases 2.1, 2.8, 2.9
if (aBewR1.Bottom()>aBewR2.Top()) {
- // Faelle 2.8, 2.9
- // Fall 2.8 ist immer Aussenrumlauf (bDirect=sal_False).
- // Fall 2.9 kann auch Direktverbindung sein (bei geringer
- // Ueberschneidung der BewareRects ohne Ueberschneidung der
- // Boundrects wenn die Linienaustritte sonst das BewareRect
- // des jeweils anderen Objekts verletzen wuerden.
+ /* Cases 2.8, 2.9
+ Case 2.8 always going around on the outside (bDirect=sal_False).
+
+ Case 2.9 could also be a direct connection (in the
+ case that the BewareRects overlap only slightly and
+ the BoundRects don't overlap at all and if the
+ line exits would otherwise violate the respective
+ other object's BewareRect).
+ */
bool bCase29Direct = false;
bool bCase29=aBewR1.Bottom()>aBewR2.Top();
- if (aBndR1.Bottom()<=aBndR2.Top()) { // Fall 2.9 und keine Boundrectueberschneidung
+ if (aBndR1.Bottom()<=aBndR2.Top()) { // case 2.9 without BoundRect overlap
if ((aPt1.X()>aBewareRect2.Left() && aPt1.X()<aBewareRect2.Right()) ||
(aPt2.X()>aBewareRect1.Left() && aPt2.X()<aBewareRect1.Right())) {
bCase29Direct = true;
@@ -1066,8 +1089,8 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
aMeeting.X()=nXMax;
}
if (bCase29) {
- // und nun noch dafuer sorgen, dass das
- // umzingelte Obj nicht durchquert wird
+ // now make sure that the surrounded object
+ // isn't traversed
if ((aBewR1.Center().X()<aBewR2.Center().X()) != bLinksLang) {
aMeeting.Y()=aBewR2.Bottom();
} else {
@@ -1075,66 +1098,80 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
}
} else {
- // Direkte Verbindung (3-Linien Z-Verbindung), da
- // Verletzung der BewareRects unvermeidlich ist.
- // Via Dreisatz werden die BewareRects nun verkleinert.
- long nWant1=aBewR1.Bottom()-aBndR1.Bottom(); // Abstand bei Obj1
- long nWant2=aBndR2.Top()-aBewR2.Top(); // Abstand bei Obj2
- long nSpace=aBndR2.Top()-aBndR1.Bottom(); // verfuegbarer Platz
+ // We need a direct connection (3-line Z connection),
+ // because we have to violate the BewareRects.
+ // Use rule of three to scale down the BewareRects.
+ long nWant1=aBewR1.Bottom()-aBndR1.Bottom(); // difference at Obj1
+ long nWant2=aBndR2.Top()-aBewR2.Top(); // difference at Obj2
+ long nSpace=aBndR2.Top()-aBndR1.Bottom(); // available space
long nGet1=BigMulDiv(nWant1,nSpace,nWant1+nWant2);
long nGet2=nSpace-nGet1;
- if (bUnt1) { // Normalisierung zurueckwandeln
+ if (bUnt1) { // revert normalization
aBewareRect1.Bottom()+=nGet1-nWant1;
aBewareRect2.Top()-=nGet2-nWant2;
} else {
aBewareRect2.Bottom()+=nGet1-nWant1;
aBewareRect1.Top()-=nGet2-nWant2;
}
- nIntersections++; // Qualitaet herabsetzen
+ nIntersections++; // lower quality
}
}
}
}
- } else if (nMainCase==3) { // Fall 3: Einer waagerecht und der andere senkrecht. Sehr viele Fallunterscheidungen
- /* Kleine Legende: � � � � � -> Ohne Ueberschneidung, maximal Beruehrung. */
- /* � � � � � -> Ueberschneidung */
- /* � � � � � -> Selbe Hoehe */
- /* � � � � � -> Ueberschneidung */
- /* � � � � � -> Ohne Ueberschneidung, maximal Beruehrung. */
- /* Linienaustritte links �, rechts �, oben � und unten �. */
- /* Insgesamt sind 96 Konstellationen moeglich, wobei einige nicht einmal */
- /* eindeutig einem Fall und damit einer Behandlungsmethode zugeordnet werden */
- /* koennen. */
- /* 3.1: Hierzu moegen alle Konstellationen zaehlen, die durch den */
- /* Default-MeetingPoint zufriedenstellend abgedeckt sind (20+12). */
- /* � � � � � � � � � � Diese 12 � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � Konstel. � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � jedoch � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � nur zum � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � Teil: � � � � � � � � � � � � � � � � � � � � */
- /* Letztere 16 Faelle scheiden aus, sobald sich die Objekte offen */
- /* gegenueberstehen (siehe Fall 3.2). */
- /* 3.2: Die Objekte stehen sich offen gegenueber und somit ist eine */
- /* Verbindung mit lediglich 2 Linien moeglich (4+20). */
- /* Dieser Fall hat 1. Prioritaet. */
- /* � � � � � � � � � � Diese 20 � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � Konstel. � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � jedoch � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � nur zum � � � � � � � � � � � � � � � � � � � � */
- /* � � � � � � � � � � Teil: � � � � � � � � � � � � � � � � � � � � */
- /* 3.3: Die Linienaustritte zeigen vom anderen Objekt weg bzw. hinter */
- /* dessen Ruecken vorbei (52+4). */
- /* � � � � � � � � � � � � � � � � � � � � Diese 4 � � � � � � � � � � */
- /* � � � � � � � � � � � � � � � � � � � � Konstel. � � � � � � � � � � */
- /* � � � � � � � � � � � � � � � � � � � � jedoch � � � � � � � � � � */
- /* � � � � � � � � � � � � � � � � � � � � nur zum � � � � � � � � � � */
- /* � � � � � � � � � � � � � � � � � � � � Teil: � � � � � � � � � � */
-
- // Fall 3.2
+ } else if (nMainCase==3) { // case 3: one horizontal, the other vertical
+ /* legend:
+ The line exits to the:
+ -| left
+
+ |- right
+
+ _|_ top
+
+ T bottom
+
+ * . * . * -- no overlap, at most might touch
+ . . . . . -- overlap
+ * . |- . * -- same height
+ . . . . . -- overlap
+ * . * . * -- no overlap, at most might touch
+
+ Overall, there are 96 possible constellations, some of these can't even
+ be unambiguously assigned to a certain case/method of handling.
+
+
+ 3.1: All those constellations that are covered reasonably well
+ by the default MeetingPoint (20+12).
+
+ T T T . _|_ _|_ . T T T these 12 * . * T * * . * . * * T * . * * . * . *
+ . . . . _|_ _|_ . . . . constellations . . . . . . . . . T . . . . . T . . . .
+ * . |- . * * . -| . * are covered * . |- . _|_ * . |- . T _|_ . -| . * T . -| . *
+ . . . . T T . . . . only in . . . . _|_ . . . . . _|_ . . . . . . . . .
+ _|__|__|_ . T T . _|__|__|_ part: * . * _|_ * * . * . * * _|_ * . * * . * . *
+
+ The last 16 of these cases can be excluded, if the objects face each other openly.
+
+
+ 3.2: The objects face each other openly, thus a connection using only two lines is possible (4+20);
+ This case is priority #1.
+ * . * . T T . * . * these 20 * . * T * * T * . * * . * . * * . * . *
+ . . . . . . . . . . constellations . . . T T T T . . . . . . . . . . . . .
+ * . |- . * * . -| . * are covered * . |-_|__|_ _|__|_-| . * * . |- T T T T -| . *
+ . . . . . . . . . . only in . . . _|__|_ _|__|_ . . . . . . . . . . . . .
+ * . * . _|_ _|_ . * . * part: * . * _|_ * * _|_ * . * * . * . * * . * . *
+
+ 3.3: The line exits point away from the other object or or miss its back (52+4).
+ _|__|__|__|_ * * _|__|__|__|_ * . . . * * . * . * these 4 * . * . * * . * . *
+ _|__|__|__|_ . . _|__|__|__|_ T T T . . . . T T T constellations . . . T . . T . . .
+ _|__|_ |- . * * . -| _|__|_ T T |- . * * . -| T T are covered * . |- . * * . -| . *
+ _|__|__|_ . . . . _|__|__|_ T T T T . . T T T T only in . . . _|_ . . _|_ . . .
+ * . * . * * . * . * T T T T * * T T T T part: * . * . * * . * . *
+ */
+
+ // case 3.2
Rectangle aTmpR1(aBewareRect1);
Rectangle aTmpR2(aBewareRect2);
if (bBewareOverlap) {
- // Ueberschneidung der BewareRects: BoundRects fuer Check auf Fall 3.2 verwenden.
+ // overlapping BewareRects: use BoundRects for checking for case 3.2
aTmpR1=aBoundRect1;
aTmpR2=aBoundRect2;
}
@@ -1142,7 +1179,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
((bUnt2 && aTmpR2.Bottom()<=aPt1.Y()) || (bObn2 && aTmpR2.Top ()>=aPt1.Y()))) ||
(((bRts2 && aTmpR2.Right ()<=aPt1.X()) || (bLks2 && aTmpR2.Left()>=aPt1.X())) &&
((bUnt1 && aTmpR1.Bottom()<=aPt2.Y()) || (bObn1 && aTmpR1.Top ()>=aPt2.Y())))) {
- // Fall 3.2 trifft zu: Verbindung mit lediglich 2 Linien
+ // case 3.2 applies: connector with only 2 lines
if (bHor1) {
aMeeting.X()=aPt2.X();
aMeeting.Y()=aPt1.Y();
@@ -1150,7 +1187,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
aMeeting.X()=aPt1.X();
aMeeting.Y()=aPt2.Y();
}
- // Falls Ueberschneidung der BewareRects:
+ // in the case of overlapping BewareRects:
aBewareRect1=aTmpR1;
aBewareRect2=aTmpR2;
} else if ((((bRts1 && aBewareRect1.Right ()>aBewareRect2.Left ()) ||
@@ -1161,7 +1198,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
(bLks2 && aBewareRect2.Left ()<aBewareRect1.Right ())) &&
((bUnt1 && aBewareRect1.Bottom()>aBewareRect2.Top ()) ||
(bObn1 && aBewareRect1.Top ()<aBewareRect2.Bottom())))) {
- // Fall 3.3
+ // case 3.3
if (bRts1 || bRts2) { aMeeting.X()=nXMax; }
if (bLks1 || bLks2) { aMeeting.X()=nXMin; }
if (bUnt1 || bUnt2) { aMeeting.Y()=nYMax; }
@@ -1181,18 +1218,18 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
Point aEP1(aXP1[nXP1Anz-1]);
Point aEP2(aXP2[nXP2Anz-1]);
bool bInsMeetingPoint=aEP1.X()!=aEP2.X() && aEP1.Y()!=aEP2.Y();
- bool bHorzE1=aEP1.Y()==aXP1[nXP1Anz-2].Y(); // letzte Linie von XP1 horizontal?
- bool bHorzE2=aEP2.Y()==aXP2[nXP2Anz-2].Y(); // letzte Linie von XP2 horizontal?
+ bool bHorzE1=aEP1.Y()==aXP1[nXP1Anz-2].Y(); // is last line of XP1 horizontal?
+ bool bHorzE2=aEP2.Y()==aXP2[nXP2Anz-2].Y(); // is last line of XP2 horizontal?
if (aEP1==aEP2 && ((bHorzE1 && bHorzE2 && aEP1.Y()==aEP2.Y()) || (!bHorzE1 && !bHorzE2 && aEP1.X()==aEP2.X()))) {
- // Sonderbehandlung fuer 'I'-Verbinder
+ // special casing 'I' connectors
nXP1Anz--; aXP1.Remove(nXP1Anz,1);
nXP2Anz--; aXP2.Remove(nXP2Anz,1);
}
if (bInsMeetingPoint) {
aXP1.Insert(XPOLY_APPEND,aMeeting,XPOLY_NORMAL);
if (bInfo) {
- // Durch einfuegen des MeetingPoints kommen 2 weitere Linie hinzu.
- // Evtl. wird eine von diesen die Mittellinie.
+ // Inserting a MeetingPoint adds 2 new lines,
+ // either might become the center line.
if (pInfo->nObj1Lines==pInfo->nObj2Lines) {
pInfo->nObj1Lines++;
pInfo->nObj2Lines++;
@@ -1207,8 +1244,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
}
} else if (bInfo && aEP1!=aEP2 && nXP1Anz+nXP2Anz>=4) {
- // Durch Verbinden der beiden Enden kommt eine weitere Linie hinzu.
- // Dies wird die Mittellinie.
+ // By connecting both ends, another line is added, this becomes the center line.
pInfo->nMiddleLine=nXP1Anz-1;
}
sal_uInt16 nNum=aXP2.GetPointCount();
@@ -1223,27 +1259,27 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
cForm='?';
if (nPntAnz==2) cForm='I';
else if (nPntAnz==3) cForm='L';
- else if (nPntAnz==4) { // Z oder U
+ else if (nPntAnz==4) { // Z or U
if (nAngle1==nAngle2) cForm='U';
else cForm='Z';
- } else if (nPntAnz==6) { // S oder C oder ...
+ } else if (nPntAnz==6) { // S or C or ...
if (nAngle1!=nAngle2) {
- // Fuer Typ S hat Linie2 dieselbe Richtung wie Linie4.
- // Bei Typ C sind die beiden genau entgegengesetzt.
+ // For type S, line 2 has the same direction as line 4.
+ // For type C, the opposite is true.
Point aP1(aXP1[1]);
Point aP2(aXP1[2]);
Point aP3(aXP1[3]);
Point aP4(aXP1[4]);
- if (aP1.Y()==aP2.Y()) { // beide Linien Horz
+ if (aP1.Y()==aP2.Y()) { // else both lines are horizontal
if ((aP1.X()<aP2.X())==(aP3.X()<aP4.X())) cForm='S';
else cForm='C';
- } else { // sonst beide Linien Vert
+ } else { // else both lines are vertical
if ((aP1.Y()<aP2.Y())==(aP3.Y()<aP4.Y())) cForm='S';
else cForm='C';
}
- } else cForm='4'; // sonst der 3. Fall mit 5 Linien
+ } else cForm='4'; // else is case 3 with 5 lines
} else cForm='?'; //
- // Weitere Formen:
+ // more shapes:
if (bInfo) {
pInfo->cOrthoForm=cForm;
if (cForm=='I' || cForm=='L' || cForm=='Z' || cForm=='U') {
@@ -1263,7 +1299,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
if (pnQuality!=NULL) {
sal_uIntPtr nQual=0;
- sal_uIntPtr nQual0=nQual; // Ueberlaeufe vorbeugen
+ sal_uIntPtr nQual0=nQual; // prevent overruns
bool bOverflow = false;
Point aPt0(aXP1[0]);
for (sal_uInt16 nPntNum=1; nPntNum<nPntAnz; nPntNum++) {
@@ -1276,18 +1312,18 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
sal_uInt16 nTmp=nPntAnz;
if (cForm=='Z') {
- nTmp=2; // Z-Form hat gute Qualitaet (nTmp=2 statt 4)
+ nTmp=2; // Z shape with good quality (nTmp=2 instead of 4)
sal_uIntPtr n1=Abs(aXP1[1].X()-aXP1[0].X())+Abs(aXP1[1].Y()-aXP1[0].Y());
sal_uIntPtr n2=Abs(aXP1[2].X()-aXP1[1].X())+Abs(aXP1[2].Y()-aXP1[1].Y());
sal_uIntPtr n3=Abs(aXP1[3].X()-aXP1[2].X())+Abs(aXP1[3].Y()-aXP1[2].Y());
- // fuer moeglichst gleichlange Linien sorgen
+ // try to make lines lengths similar
sal_uIntPtr nBesser=0;
n1+=n3;
n3=n2/4;
if (n1>=n2) nBesser=6;
else if (n1>=3*n3) nBesser=4;
else if (n1>=2*n3) nBesser=2;
- if (aXP1[0].Y()!=aXP1[1].Y()) nBesser++; // Senkrechte Startlinie kriegt auch noch einen Pluspunkt (fuer H/V-Prio)
+ if (aXP1[0].Y()!=aXP1[1].Y()) nBesser++; // vertical starting line gets a plus (for H/V-Prio)
if (nQual>nBesser) nQual-=nBesser; else nQual=0;
}
if (nTmp>=3) {
@@ -1295,20 +1331,20 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
nQual+=(sal_uIntPtr)nTmp*0x01000000;
if (nQual<nQual0 || nTmp>15) bOverflow = true;
}
- if (nPntAnz>=2) { // Austrittswinkel nochmal pruefen
+ if (nPntAnz>=2) { // check exit angle again
Point aP1(aXP1[1]); aP1-=aXP1[0];
Point aP2(aXP1[nPntAnz-2]); aP2-=aXP1[nPntAnz-1];
long nAng1=0; if (aP1.X()<0) nAng1=18000; if (aP1.Y()>0) nAng1=27000;
- if (aP1.Y()<0) nAng1=9000; if (aP1.X()!=0 && aP1.Y()!=0) nAng1=1; // Schraeg!?!
+ if (aP1.Y()<0) nAng1=9000; if (aP1.X()!=0 && aP1.Y()!=0) nAng1=1; // slant?!
long nAng2=0; if (aP2.X()<0) nAng2=18000; if (aP2.Y()>0) nAng2=27000;
- if (aP2.Y()<0) nAng2=9000; if (aP2.X()!=0 && aP2.Y()!=0) nAng2=1; // Schraeg!?!
+ if (aP2.Y()<0) nAng2=9000; if (aP2.X()!=0 && aP2.Y()!=0) nAng2=1; // slant?!
if (nAng1!=nAngle1) nIntersections++;
if (nAng2!=nAngle2) nIntersections++;
}
- // Fuer den Qualitaetscheck wieder die Original-Rects verwenden und
- // gleichzeitig checken, ob eins fuer die Edge-Berechnung verkleinert
- // wurde (z.B. Fall 2.9)
+ // For the quality check, use the original Rects and at the same time
+ // check whether one them was scaled down for the calculation of the
+ // Edges (e. g. case 2.9)
aBewareRect1=rBewareRect1;
aBewareRect2=rBewareRect2;
@@ -1325,16 +1361,16 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
if (b1) nIntersections++;
if (b2) nIntersections++;
}
- // und nun noch auf Ueberschneidungen checken
+ // check for overlaps
if (i>0 && nInt0==nIntersections) {
- if (aPt0.Y()==aPt1b.Y()) { // Horizontale Linie
+ if (aPt0.Y()==aPt1b.Y()) { // horizontal line
if (aPt0.Y()>aBewareRect1.Top() && aPt0.Y()<aBewareRect1.Bottom() &&
((aPt0.X()<=aBewareRect1.Left() && aPt1b.X()>=aBewareRect1.Right()) ||
(aPt1b.X()<=aBewareRect1.Left() && aPt0.X()>=aBewareRect1.Right()))) nIntersections++;
if (aPt0.Y()>aBewareRect2.Top() && aPt0.Y()<aBewareRect2.Bottom() &&
((aPt0.X()<=aBewareRect2.Left() && aPt1b.X()>=aBewareRect2.Right()) ||
(aPt1b.X()<=aBewareRect2.Left() && aPt0.X()>=aBewareRect2.Right()))) nIntersections++;
- } else { // Vertikale Linie
+ } else { // vertical line
if (aPt0.X()>aBewareRect1.Left() && aPt0.X()<aBewareRect1.Right() &&
((aPt0.Y()<=aBewareRect1.Top() && aPt1b.Y()>=aBewareRect1.Bottom()) ||
(aPt1b.Y()<=aBewareRect1.Top() && aPt0.Y()>=aBewareRect1.Bottom()))) nIntersections++;
@@ -1353,7 +1389,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
if (bOverflow || nQual==0xFFFFFFFF) nQual=0xFFFFFFFE;
*pnQuality=nQual;
}
- if (bInfo) { // nun die Linienversaetze auf aXP1 anwenden
+ if (bInfo) { // now apply line offsets to aXP1
if (pInfo->nMiddleLine!=0xFFFF) {
sal_uInt16 nIdx=pInfo->ImpGetPolyIdx(MIDDLELINE,aXP1);
if (pInfo->ImpIsHorzLine(MIDDLELINE,aXP1)) {
@@ -1405,7 +1441,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
}
}
- // Nun mache ich ggf. aus dem Verbinder eine Bezierkurve
+ // make the connector a bezier curve, if appropriate
if (eKind==SDREDGE_BEZIER && nPntAnz>2) {
Point* pPt1=&aXP1[0];
Point* pPt2=&aXP1[1];
@@ -1428,20 +1464,18 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
pPt2->Y()-=dy1/3;
pPt3->X()-=dx2/3;
pPt3->Y()-=dy2/3;
- } else if (nPntAnz>=4 && nPntAnz<=6) { // Z oder U oder ...
- // fuer Alle Anderen werden die Endpunkte der Ausgangslinien
- // erstmal zu Kontrollpunkten. Bei nPntAnz>4 ist also noch
- // Nacharbeit erforderlich!
+ } else if (nPntAnz>=4 && nPntAnz<=6) { // Z or U or ...
+ // To all others, the end points of the original lines become control
+ // points for now. Thus, we need to do some more work for nPntAnz>4!
aXP1.SetFlags(1,XPOLY_CONTROL);
aXP1.SetFlags(nPntAnz-2,XPOLY_CONTROL);
- // Distanz x1.5
+ // distance x1.5
pPt2->X()+=dx1/2;
pPt2->Y()+=dy1/2;
pPt3->X()+=dx2/2;
pPt3->Y()+=dy2/2;
if (nPntAnz==5) {
- // Vor und hinter dem Mittelpunkt jeweils
- // noch einen Kontrollpunkt einfuegen
+ // add a control point before and after center
Point aCenter(aXP1[2]);
long dx1b=aCenter.X()-aXP1[1].X();
long dy1b=aCenter.Y()-aXP1[1].Y();
@@ -1469,7 +1503,7 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
aXP1.SetFlags(3,XPOLY_SYMMTR);
//aXP1[4].X()+=dx/2;
//aXP1[4].Y()+=dy/2;
- aXP1.Remove(4,1); // weil identisch mit aXP1[3]
+ aXP1.Remove(4,1); // because it's identical with aXP1[3]
}
}
}
@@ -1477,37 +1511,48 @@ XPolygon SdrEdgeObj::ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rec
}
/*
-Nach einer einfachen Rechnung koennte es max. 64 unterschiedliche Verlaeufe mit
-5 Linien, 32 mit 4 Linien, 16 mit 3, 8 mit 2 Linien und 4 mit 1 Linie geben=124.
-Normalisiert auf 1. Austrittswinkel nach rechts bleiben dann noch 31.
-Dann noch eine vertikale Spiegelung wegnormalisiert bleiben noch 16
-characteristische Verlaufszuege mit 1-5 Linien:
-Mit 1 Linie (Typ 'I'): --
-Mit 2 Linien (Typ 'L'): -�
-Mit 3 Linien (Typ 'U'): -� (Typ 'Z'): �-
- -� -�
-Mit 4 Linien: 1 ist nicht plausibel, 3 ist=2 (90deg Drehung). Verbleibt 2,4
- �-� ڿ � ڿ ڿ �-�
- -� -� -� -� -� -�
-Mit 5 Linien: nicht plausibel sind 1,2,4,5. 7 ist identisch mit 3 (Richtungsumkehr)
- Bleibt also 3,6 und 8. '4' 'S' 'C'
- � � -� �- �-� �-
- �-� �-� �-� �-� � � -� � �-� �-� � �-�
- -� -� -� � -� �- -� -� --� � � -� � -� � �
-Insgesamt sind also 9 Grundtypen zu unterscheiden die den 400 Konstellationen
-aus Objektposition und Austrittswinkeln zuzuordnen sind.
-4 der 9 Grundtypen haben eine 'Mittellinie'. Die Anzahl der zu Objektabstaende
-je Objekt variiert von 0-3:
- Mi O1 O2 Anmerkung
-'I': n 0 0
-'L': n 0 0
-'U': n 0-1 0-1
-'Z': j 0 0
-4.1: j 0 1 = U+1 bzw. 1+U
-4.2: n 0-2 0-2 = Z+1
-'4': j 0 2 = Z+2
-'S': j 1 1 = 1+Z+1
-'C': n 0-3 0-3 = 1+U+1
+There could be a maximum of 64 different developments with with 5 lines, a
+maximum of 32 developments with 4 lines, a maximum of 16 developments with
+3 lines, a maximum of 8 developments with 2 lines.
+This gives us a total of 124 possibilities.
+Normalized for the 1st exit angle to the right, there remain 31 possibilities.
+Now, normalizing away the vertical mirroring, we get to a total of 16
+characteristic developments with 1 through 5 lines:
+
+1 line (type "I") --
+
+2 lines (type "L") __|
+
+3 lines (type "U") __ (type "Z") _
+ __| _|
+ _ _
+4 lines #1 _| #2 | | #3 |_ #4 | |
+ _| _| _| _|
+ Of these, #1 is implausible, #2 is a rotated version of #3. This leaves
+ #2 (from now on referred to as 4.1) and #4 (from now on referred to as 4.2).
+ _ _
+5 lines #1 _| #2 _| #3 ___ #4 _
+ _| _| _| _| _| |_
+ _ _ _
+ #5 |_ #6 |_ #7 _| | #8 ____
+ _| _| _| |_ _|
+ Of these, 5.1, 5.2, 5.4 and 5.5 are implausible, 5.7 is a reversed version
+ of 5.3. This leaves 5.3 (type "4"), 5.6 (type "S") and 5.8 (type "C").
+
+We now have discerned the 9 basic types to cover all 400 possible constellations
+of object positions and exit angles. 4 of the 9 types have got a center
+line (CL). The number of object margins per object varies between 0 and 3:
+
+ CL O1 O2 Note
+"I": n 0 0
+"L": n 0 0
+"U": n 0-1 0-1
+"Z": y 0 0
+4.2: y 0 1 = U+1, respectively 1+U
+4.4: n 0-2 0-2 = Z+1
+"4": y 0 2 = Z+2
+"S": y 1 1 = 1+Z+1
+"C": n 0-3 0-3 = 1+U+1
*/
void SdrEdgeObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
@@ -1519,33 +1564,33 @@ void SdrEdgeObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
bool bObj1=aCon1.pObj!=NULL && aCon1.pObj->GetBroadcaster()==&rBC;
bool bObj2=aCon2.pObj!=NULL && aCon2.pObj->GetBroadcaster()==&rBC;
if (bDying && (bObj1 || bObj2)) {
- // Dying vorher abfangen, damit AttrObj nicht
- // wg. vermeintlicher Vorlagenaenderung rumbroadcastet
+ // catch Dying, so AttrObj doesn't start broadcasting
+ // about an alleged change of template
if (bObj1) aCon1.pObj=NULL;
if (bObj2) aCon2.pObj=NULL;
- return; // Und mehr braucht hier nicht getan werden.
+ return;
}
if ( bObj1 || bObj2 )
{
bEdgeTrackUserDefined = sal_False;
}
SdrTextObj::Notify(rBC,rHint);
- if (nNotifyingCount==0) { // Hier nun auch ein VerriegelungsFlag
+ if (nNotifyingCount==0) { // a locking flag
((SdrEdgeObj*)this)->nNotifyingCount++;
SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
- if (bDataChg) { // StyleSheet geaendert
- ImpSetAttrToEdgeInfo(); // Werte bei Vorlagenaenderung vom Pool nach aEdgeInfo kopieren
+ if (bDataChg) { // StyleSheet changed
+ ImpSetAttrToEdgeInfo(); // when changing templates, copy values from Pool to aEdgeInfo
}
if (bDataChg ||
(bObj1 && aCon1.pObj->GetPage()==pPage) ||
(bObj2 && aCon2.pObj->GetPage()==pPage) ||
(pSdrHint && pSdrHint->GetKind()==HINT_OBJREMOVED))
{
- // Broadcasting nur, wenn auf der selben Page
+ // broadcasting only, if on the same page
Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
ImpDirtyEdgeTrack();
- // only redraw here, no objectchange
+ // only redraw here, object hasn't actually changed
ActionChanged();
SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
@@ -1555,7 +1600,7 @@ void SdrEdgeObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
}
/** updates edges that are connected to the edges of this object
- as if the connected objects send a repaint broadcast
+ as if the connected objects sent a repaint broadcast
*/
void SdrEdgeObj::Reformat()
{
@@ -1641,7 +1686,7 @@ void SdrEdgeObj::SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly )
bEdgeTrackDirty = sal_False;
bEdgeTrackUserDefined = sal_True;
- // #i110629# also set aRect and maSnapeRect dependent from pEdgeTrack
+ // #i110629# also set aRect and maSnapeRect depending on pEdgeTrack
const Rectangle aPolygonBounds(pEdgeTrack->GetBoundRect());
aRect = aPolygonBounds;
maSnapRect = aPolygonBounds;
@@ -1868,7 +1913,7 @@ bool SdrEdgeObj::applySpecialDrag(SdrDragStat& rDragStat)
aEdgeInfo.ImpSetLineVersatz(eLineCode, *pEdgeTrack, nDist);
}
- // force recalc EdgeTrack
+ // force recalculation of EdgeTrack
*pEdgeTrack = ImpCalcEdgeTrack(*pEdgeTrack, aCon1, aCon2, &aEdgeInfo);
bEdgeTrackDirty=sal_False;
@@ -2007,7 +2052,7 @@ bool SdrEdgeObj::EndCreate(SdrDragStat& rDragStat, SdrCreateCmd eCmd)
if (rDragStat.GetView()!=NULL) {
rDragStat.GetView()->HideConnectMarker();
}
- ImpSetEdgeInfoToAttr(); // Die Werte aus aEdgeInfo in den Pool kopieren
+ ImpSetEdgeInfoToAttr(); // copy values from aEdgeInfo into the pool
}
SetRectsDirty();
return bOk;
@@ -2047,7 +2092,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
if (pOut==NULL) return sal_False;
SdrObjList* pOL=rPV.GetObjList();
const SetOfByte& rVisLayer=rPV.GetVisibleLayers();
- // Sensitiver Bereich der Konnektoren ist doppelt so gross wie die Handles:
+ // sensitive area of connectors is twice as large as the one of the handles
sal_uInt16 nMarkHdSiz=rPV.GetView().GetMarkHdlSizePixel();
Size aHalfConSiz(nMarkHdSiz,nMarkHdSiz);
aHalfConSiz=pOut->PixelToLogic(aHalfConSiz);
@@ -2064,20 +2109,20 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
SdrObjConnection aBestCon;
while (no>0 && !bFnd) {
- // Problem: Gruppenobjekt mit verschiedenen Layern liefert LayerID 0 !!!!
+ // issue: group objects on different layers return LayerID=0!
no--;
SdrObject* pObj=pOL->GetObj(no);
if (rVisLayer.IsSet(pObj->GetLayer()) && pObj->IsVisible() && // only visible objects
- (pThis==NULL || pObj!=(SdrObject*)pThis) && // nicht an mich selbst connecten
+ (pThis==NULL || pObj!=(SdrObject*)pThis) && // don't connect it to itself
pObj->IsNode())
{
Rectangle aObjBound(pObj->GetCurrentBoundRect());
if (aObjBound.IsOver(aMouseRect)) {
aTestCon.ResetVars();
- bool bEdge=HAS_BASE(SdrEdgeObj,pObj); // kein BestCon fuer Edge
- // Die Userdefined Konnektoren haben absolute Prioritaet.
- // Danach kommt Vertex, Corner und Mitte(Best) gleich priorisiert.
- // Zum Schluss kommt noch ein HitTest aufs Obj.
+ bool bEdge=HAS_BASE(SdrEdgeObj,pObj); // no BestCon for Edge
+ // User-defined connectors have absolute priority.
+ // After those come Vertex, Corner and center (Best), all prioritized equally.
+ // Finally, a HitTest for the object.
const SdrGluePointList* pGPL=pObj->GetGluePointList();
sal_uInt16 nConAnz=pGPL==NULL ? 0 : pGPL->GetCount();
sal_uInt16 nGesAnz=nConAnz+9;
@@ -2117,7 +2162,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
// Suppress default connect at object center
if(!pThis || !pThis->GetSuppressDefaultConnect())
{
- // Edges nicht!
+ // not the edges!
nConNum=0;
aConPos=aObjBound.Center();
bOk = true;
@@ -2138,8 +2183,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO
}
}
}
- // Falls kein Konnektor getroffen wird nochmal
- // HitTest versucht fuer BestConnector (=bCenter)
+ // if no connector is hit, try HitTest again, for BestConnector (=bCenter)
if(!bFnd &&
!bEdge &&
SdrObjectPrimitiveHit(*pObj, rPt, nBoundHitTol, rPV, &rVisLayer, false))
@@ -2264,7 +2308,7 @@ Point SdrEdgeObj::GetPoint(sal_uInt32 i) const
void SdrEdgeObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
{
- // ToDo: Umconnekten fehlt noch
+ // TODO: Need an implementation to connect differently.
ImpUndirtyEdgeTrack();
sal_uInt16 nAnz=pEdgeTrack->GetPointCount();
if (0L == i)
@@ -2354,9 +2398,9 @@ void SdrEdgeObj::SetTailPoint( sal_Bool bTail, const Point& rPt )
}
/** this method is used by the api to set a glue point for a connection
- nId == -1 : The best default point is automaticly choosen
- 0 <= nId <= 3 : One of the default points is choosen
- nId >= 4 : A user defined glue point is choosen
+ nId == -1 : The best default point is automatically chosen
+ 0 <= nId <= 3 : One of the default points is chosen
+ nId >= 4 : A user defined glue point is chosen
*/
void SdrEdgeObj::setGluePointIndex( sal_Bool bTail, sal_Int32 nIndex /* = -1 */ )
{
@@ -2424,7 +2468,7 @@ sal_Bool SdrEdgeObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::
void SdrEdgeObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon)
{
- // evtl. take care for existing connections. For now, just use the
+ // where appropriate take care for existing connections. For now, just use the
// implementation from SdrObject.
SdrObject::TRSetBaseGeometry(rMatrix, rPolyPolygon);
}