/************************************************************************* * * 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: svdtouch.cxx,v $ * $Revision: 1.11 $ * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svx.hxx" #include "svdtouch.hxx" #include #include #include #include #include //////////////////////////////////////////////////////////////////////////////////////////////////// class ImpPolyHitCalc { public: long x1,x2,y1,y2; // Koordinaten des Rect, muessen sortiert sein! FASTBOOL bEdge; // ein Punkt lag genau auf einer Kante FASTBOOL bIntersect; // mind. 2 Punkte auf verschiedenen Seiten einer Kante FASTBOOL bPntInRect; // mind. 1 Punkt war vollstaendig im Rect USHORT nOCnt; // wenn Counter ungerade, dann getroffen USHORT nUCnt; // wenn Counter ungerade, dann getroffen USHORT nLCnt; // wenn Counter ungerade, dann getroffen USHORT nRCnt; // wenn Counter ungerade, dann getroffen FASTBOOL bLine; // TRUE=PolyLine, kein Polygon public: ImpPolyHitCalc(const Rectangle& aR, FASTBOOL bIsLine=FALSE) { bLine=bIsLine; bEdge=FALSE; bIntersect=FALSE; bPntInRect=FALSE; x1=aR.Left(); x2=aR.Right(); y1=aR.Top(); y2=aR.Bottom(); nOCnt=0; nUCnt=0; nLCnt=0; nRCnt=0; } FASTBOOL IsDecided() { return bEdge || bIntersect || bPntInRect; } void CheckPntInRect(const Point& rP) { if (!bPntInRect) { bPntInRect=rP.X()>=x1 && rP.X()<=x2 && rP.Y()>=y1 && rP.Y()<=y2; } } bool IsHit() { return (!bLine && (nOCnt & 1)==1) || IsDecided(); } }; #define CAREFUL_MULDIV(Res,Val,Mul,Div) { \ if (Abs(Val)>0xB504 || Abs(Mul)>0xB504) { \ BigInt aBigTemp(Val); \ aBigTemp*=Mul; \ aBigTemp/=Div; \ Res=long(aBigTemp); \ } else { \ Res=Val*Mul/Div; \ } \ } void ImpCheckIt(ImpPolyHitCalc& rH, long lx1, long ly1, long lx2, long ly2, long rx1, long ry1, long rx2, long ry2, USHORT& nOCnt, USHORT& nUCnt) { if ((ly1>ly2) || ((ly1==ly2) && (lx1>lx2))) { long nTmp; // die 2 Punkte nach Y sortieren nTmp=lx1; lx1=lx2; lx2=nTmp; nTmp=ly1; ly1=ly2; ly2=nTmp; } FASTBOOL b1=FALSE,b2=FALSE,b3=FALSE,b4=FALSE; // je 1 Flag fuer jeden der 4 Punkte LO,RO,LU,RU FASTBOOL bx1,bx2; FASTBOOL by1=ly1<=ry1 && ly2>ry1; FASTBOOL by2=ly1<=ry2 && ly2>ry2; long dx(0),dy(0),a(0); if (by1 || by2) { dx=lx2-lx1; dy=ly2-ly1; } if (by1) { // Nur wer die Scanline schneidet bx1=lx1Schnittpunkt } else { // ansonsten Ober- und Unterkante des Rects getrennt betrachten if (by1) { // Linie durch Oberkante if (b1 && b2) nOCnt++; // Oberkante komplett rechts neben der Linie else if (b1 || b2) rH.bIntersect=TRUE; // Nur zum Teil->Schnittpunkt } if (by2) { // Linie durch Unterkante if (b3 && b4) nUCnt++; // Unterkante komplett rechts neben der Linie else if (b3 || b4) rH.bIntersect=TRUE; // Nur zum Teil->Schnittpunkt } } } } void CheckPolyHit(const Polygon& rPoly, ImpPolyHitCalc& rH) { USHORT nAnz=rPoly.GetSize(); if (nAnz==0) return; if (nAnz==1) { rH.CheckPntInRect(rPoly[0]); return; } Point aPt0=rPoly[USHORT(nAnz-1)]; rH.CheckPntInRect(aPt0); USHORT i=0; if (rH.bLine) { aPt0=rPoly[0]; i++; } for (; iaP2.Y()) || ((aP1.Y()==aP2.Y()) && (aP1.X()>aP2.X()))) { Point aTmp(aP1); aP1=aP2; aP2=aTmp; } bEdge=((aP1.X()==aP2.X()) && (rHit.X()==aP1.X()) && (rHit.Y()>=aP1.Y()) && (rHit.Y()<=aP2.Y())) || ((aP1.Y()==aP2.Y()) && (rHit.Y()==aP1.Y()) && (rHit.X()>=aP1.X()) && (rHit.X()<=aP2.X())) || (rHit.X()==aP1.X()) && (rHit.Y()==aP1.Y()); if (!bEdge && aP1.Y()<=rHit.Y() && aP2.Y()>rHit.Y()) { // Nur wer die Scanline schneidet FASTBOOL bx1=aP1.X()0xB504 || Abs(yTemp)>0xB504) { // gegen Integerueberlaeufe BigInt aBigTemp(dx); aBigTemp*=yTemp; aBigTemp/=dy; xTemp=long(aBigTemp); } else { xTemp=dx*yTemp /dy; } xTemp+=aP1.X(); bEdge=(xTemp==rHit.X()); if (xTemp