doccoord.cpp

Go to the documentation of this file.
00001 // $Id: doccoord.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 
00100 #include "camtypes.h"
00101 //#include "doccoord.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00102 
00103 #if !defined(EXCLUDE_FROM_XARLIB)
00104 #include "usercord.h"
00105 //#include "node.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 //#include "paper.h"
00107 //#include "xmatrix.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "chapter.h"
00110 //#include "oilcoord.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 
00114 
00115 /********************************************************************************************
00116 
00117 >   Matrix ComposeDocToOilMat(  DocCoord& ChapterPos,
00118                                 XLONG& ChapterLogHiY,
00119                                 FIXED16& ViewScale,
00120                                 WorkCoord& Scroll,
00121                             )
00122     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00123     Created:    5/8/93
00124     Inputs:     Chapter physical position
00125                 Accumulated depth of previous chapters
00126                 View scale factor (always 1:1 aspect ratio) 
00127                 Individual millipoint to pixel scale factors
00128                 Scroll offsets
00129                 Final device-dependant mapping matrix
00130     Outputs:    None.
00131     Returns:    Document to Oil matrix for a specific chapter.
00132     Purpose:    Creates a Document to Oil matrix for a specific chapter.
00133     Errors:     None.
00134 
00135 ********************************************************************************************/
00136 /*
00137 Technical notes:
00138     Assumes that the top corner of logical space is at 0,0 and y gets more negative downwards
00139     Assumes that the top corner of workarea space is at 0,0...
00140     Assumes that scroll.x is positive and that scroll.y is negative.
00141     Assumes that Document space can never be rotated with respect to OS space!
00142 
00143 ********************************************************************************************/
00144 
00145 Matrix ComposeDocToOilMat( const DocCoord& ChapterPos,  // Top left coord of chapter
00146                           const XLONG& ChapterDepth,        // Accumulated height of previous chaps
00147                           const FIXED16& ViewScale,     // User viewing scale
00148                           const WorkCoord& ScrollOffset // Scroll offsets
00149                         )
00150 {
00151 // Scale ChapterDepth into device units so that it can be combined with the scroll offset
00152 // BEFORE we build the scroll translation matrix. In this way we avoid storing 64-bit
00153 // translation values in our final matrix...
00154 //
00155 // If we COULD store 64-bit E and F values temporarilly during this composition then
00156 // we would not need to perform this trick at all. This would have the knock-on advantage
00157 // that the OSMapping matrix supplied by the OIL layer could contain the scroll offsets!
00158 //
00159 // NOTE: This adjustment can be removed when testing the system!
00160 
00161     Matrix DocToOil;
00162 
00163 //**********************************************************************
00164 // Is it just me or is there gunna be a problem with this ?
00165 // If ChapterDepth is big (atfer all it is an XLONG) and ViewScale
00166 // is big too (Say we are zoomed to 1000%) won't this go VERY wrong ?
00167 //
00168 // - Will.
00169 
00170     Matrix Scroll(  -ScrollOffset.x,
00171                     -(ScrollOffset.y + (ChapterDepth * (ViewScale)))
00172                  );
00173 
00174 //**********************************************************************
00175 
00176     Matrix ScaleMat(ViewScale,ViewScale);
00177     Matrix Translate(-((Coord)ChapterPos));
00178 
00179 // The following matrix compositions MUST be performed in this order. If you are tempted
00180 // to optimise this code MAKE SURE THAT THEY ARE STILL IN THIS ORDER WHEN YOU'VE FINISHED!
00181 //
00182 // Apply translation to get coordinates into logical column...
00183     DocToOil *= Translate;
00184 
00185 // Apply scale factors to convert from millipoint distances to pixel distances...
00186     DocToOil *= ScaleMat;
00187 
00188 // Apply scroll-offset translation to move origin to viewing position...
00189     DocToOil *= Scroll;
00190 
00191     return DocToOil;
00192 }
00193 
00194 
00195 /********************************************************************************************
00196 
00197 >   Matrix ComposeDocToWorkXMat(DocCoord ChapterPos,
00198                                 XLONG ChapterDepth,
00199                                 FIXED16 ViewScale
00200                             )
00201     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
00202     Created:    30/5/93
00203     Inputs:     Chapter physical position
00204                 Accumulated depth of previous chapters
00205                 View scale factor (always 1:1 aspect ratio) 
00206                 Individual millipoint to pixel scale factors
00207     Outputs:    None.
00208     Returns:    Document to WorkArea matrix for a specific chapter.
00209     Purpose:    Creates a Document to WorkArea matrix for a specific chapter. 
00210     Errors:     None.
00211 
00212 ********************************************************************************************/
00213 /*
00214 Technical notes:
00215     Assumes that the top corner of logical space is at 0,0 and y gets more negative downwards
00216     Assumes that the top corner of workarea space is at 0,0...
00217     Assumes that scroll.x is positive and that scroll.y is negative.
00218 
00219 ********************************************************************************************/
00220 
00221 XMatrix ComposeDocToWorkXMat(const DocCoord ChapterPos, // Top left coord of chapter
00222                           const XLONG ChapterDepth,     // Accumulated height of previous chaps
00223                           const FIXED16 ViewScale       // User viewing scale
00224                         )
00225 {
00226 
00227     XMatrix ScaleMat(ViewScale,ViewScale);
00228 
00229 // Conversion of chapter position from DocCoords to WorkCoords
00230 //    WorkCoord WrkChapPos(MakeXLong(ChapterPos.x), MakeXLong(ChapterPos.y));
00231     WorkCoord WrkChapPos(MakeXLong(ChapterPos.x), MakeXLong(ChapterPos.y)+ChapterDepth);
00232 
00233 // DocToOS matrix is initialised as the Translate matrix: saving space and performance
00234 // by the exclusion of an extra multiplication.
00235     XMatrix DocToWork(-(WrkChapPos));
00236     
00237 // The following matrix compositions MUST be performed in this order. If you are tempted
00238 // to optimise this code MAKE SURE THAT THEY ARE STILL IN THIS ORDER WHEN YOU'VE FINISHED!
00239 //
00240 
00241 // Apply scale factors to convert from millipoint distances to pixel distances...
00242     DocToWork *= ScaleMat;
00243 
00244     return DocToWork;
00245 }
00246 
00247 /********************************************************************************************
00248 
00249 >   WorkCoord   DocCoord::ToWork(Document *pDocument, View *pView)
00250 
00251     Author:     Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com> (with modifications by Phil (and Tim))
00252     Created:    26/5/93
00253     Inputs:     The document we are converting within.
00254                 The view we are converting within.
00255     Outputs:    None.
00256     Returns:    Returns a Workarea coordinate.
00257     Purpose:    Converts a document coordinate to a work area coordnate - slowly!
00258                 Note that if you are performing this conversion often and you want to do it
00259                 fast then you should use the approriate "Compose" function to build a matrix
00260                 which does the job and repeatedly apply that matrix.
00261     Errors:     None.
00262 
00263 ********************************************************************************************/
00264 /*
00265 Technical notes:
00266 
00267 ********************************************************************************************/
00268 
00269 WorkCoord DocCoord::ToWork(Document *pDocument, View *pView)
00270 {
00271     WorkCoord   WrkPoint(MakeXLong(this->x), MakeXLong(this->y));
00272     DocCoord    ChapterPos;             // To hold the top-left of the found chapter
00273     XLONG       ChapterDepth;           // To hold the accumulated depth of the chapter
00274     XMatrix     ConvertToWorkMat;       // Transformation matrix
00275     
00276     // Find chapter and its log depth
00277     this->FindEnclosingChapter(pDocument, &ChapterPos, &ChapterDepth, pView);
00278     
00279     // This builds the 64-bit conversion matrix needed for Document To WorkArea 
00280     // coordinate mappings.
00281     ConvertToWorkMat = ComposeDocToWorkXMat(ChapterPos, 
00282                                             ChapterDepth,
00283                                             pView->GetViewScale());
00284     
00285     // Apply the matrix to the DocCoord...
00286     ConvertToWorkMat.transform(&WrkPoint, 1);
00287 
00288     return (WrkPoint);
00289 }
00290 
00291 /********************************************************************************************
00292 
00293 >   WorkCoord DocCoord::ToWork( Spread *pSpread, const FIXED16 ViewScale)
00294 
00295     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00296     Created:    15/12/93
00297     Inputs:     -
00298     Outputs:    -
00299     Returns:    -
00300     Purpose:    Convert a document coordinate to a Work Coordinate, given the spread
00301                 that the coordinate is on.
00302     Errors:     -
00303     SeeAlso:    -
00304 
00305 ********************************************************************************************/
00306 
00307 WorkCoord DocCoord::ToWork( Spread *pSpread, View *pView)
00308 {
00309     WorkCoord   WrkPoint(MakeXLong(this->x), MakeXLong(this->y));
00310     DocCoord    ChapterPos;             // To hold the top-left of the found chapter
00311     XLONG       ChapterDepth;           // To hold the accumulated depth of the chapter
00312     XMatrix     ConvertToWorkMat;       // Transformation matrix
00313     
00314     Chapter *pChapter = (Chapter *) pSpread->FindParent();
00315     ENSURE(pChapter->IsKindOf(CC_RUNTIME_CLASS(Chapter)), "Spread's parent is not a chapter");
00316 
00317 
00318     // Find top left of chapter pasteboard
00319     DocRect ChapterRect = pChapter->GetPasteboardRect(TRUE, pView);
00320     ChapterPos.x = ChapterRect.lo.x;
00321     ChapterPos.y = ChapterRect.hi.y;
00322 
00323     // Find chapter depth
00324     ChapterDepth = pChapter->GetChapterDepth();
00325     
00326     // This builds the 64-bit conversion matrix needed for Document To WorkArea 
00327     // coordinate mappings.
00328 
00329     ConvertToWorkMat = ComposeDocToWorkXMat(ChapterPos, 
00330                                             ChapterDepth,
00331                                             pView->GetViewScale());
00332     
00333     // Apply the matrix to the DocCoord...
00334     ConvertToWorkMat.transform(&WrkPoint, 1);
00335 
00336     return (WrkPoint);
00337 }
00338 
00339 
00340 WorkCoord DocCoord::ToLogical(Spread* pSpread, View *pView)
00341 {
00342     // Check that we have not been fed garbage
00343     ENSURE( pSpread!=NULL, "DocCoord::ToLogical was passed a NULL spread" );
00344 
00345     // Find the chapter
00346     Chapter* pChapter = (Chapter*) pSpread->FindParent();
00347     ENSURE( pChapter!=NULL, "DocCoord::ToLogical. Spread did not have a parent chapter" );
00348     ENSURE( pChapter->IsKindOf(CC_RUNTIME_CLASS(Chapter)), "DocCoord::ToLogical. Chapter is not a chapter" );
00349 
00350     // Find out about the chapter
00351     DocRect ChapterRect = pChapter->GetPasteboardRect(TRUE, pView);
00352     XLONG   ChapterDepth = pChapter->GetChapterDepth();
00353 
00354     // Build the logical coord from the doccoord
00355     WorkCoord Result( MakeXLong(x), MakeXLong(y) );
00356     Result.x = Result.x - ChapterRect.lo.x;
00357     Result.y = Result.y - ChapterRect.hi.y;
00358     Result.y = Result.y - ChapterDepth;
00359 
00360     // return the coord
00361     return Result;
00362 }
00363 
00364 
00365 /***********************************************************************************************
00366 >   DocCoord DocCoord::ToSpread(Spread* pSpread, View* pView)
00367 
00368     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00369     Created:    5/9/95
00370     Inputs:     pSpread  - 
00371                 pView - 
00372     Returns:    SpreadCoord
00373     Purpose:    Convert DocCoord to a SpreadCoord
00374 
00375     SeeAlso:    Spread::SpreadCoordToDocCoord
00376 *********************************************************************************************/
00377 
00378 DocCoord DocCoord::ToSpread(Spread* pSpread, View* pView)
00379 {
00380     ERROR3IF((pSpread==NULL || pView==NULL), "DocCoord::ToSpread() - pSpread==NULL || pView==NULL");
00381 
00382     DocCoord temp(x, y);
00383 
00384     if (pSpread != NULL)
00385         pSpread->DocCoordToSpreadCoord(&temp);
00386 
00387     return(temp);
00388 }
00389  
00390 
00391 /***********************************************************************************************
00392 >   DocCoord DocCoord::ToDoc(Spread* pSpread, View* pView)
00393 
00394     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00395     Created:    5/9/95
00396     Inputs:     pSpread  - 
00397                 pView - 
00398     Returns:    SpreadCoord
00399     Purpose:    Convert SpreadCoord to a DocCoord
00400 
00401     SeeAlso:    Spread::SpreadCoordToDocCoord
00402 *********************************************************************************************/
00403 
00404 DocCoord DocCoord::ToDoc(Spread* pSpread, View* pView)
00405 {
00406     ERROR3IF(pSpread == NULL || pView == NULL, "DocCoord::ToDoc() - pSpread==NULL || pView==NULL");
00407 
00408     DocCoord temp(x, y);
00409 
00410     if (pSpread != NULL)
00411         pSpread->SpreadCoordToDocCoord(&temp);
00412 
00413     return(temp);
00414 }
00415  
00416 
00417 /***********************************************************************************************
00418 >   UserCoord DocCoord::ToUser(Spread* pSpread)
00419 
00420     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00421     Created:    11/9/95
00422     Inputs:     pSpread  - 
00423     Returns:    UserCoord
00424     Purpose:    Convert SpreadCoord to a UserCoord
00425 *********************************************************************************************/
00426 
00427 UserCoord DocCoord::ToUser(Spread* pSpread)
00428 {
00429     DocCoord UserOrigin(0,0);
00430     if (pSpread!=NULL)
00431         UserOrigin=pSpread->GetUserOrigin();
00432     else
00433         ERROR3("DocCoord::ToUser() - pSpread==NULL");
00434 
00435     return UserCoord(this->x-UserOrigin.x, this->y-UserOrigin.y);
00436 }
00437  
00438 
00439 /***********************************************************************************************
00440 >   OilCoord DocCoord::ToOil(Spread* pSpread, View* pView)
00441 
00442     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00443     Created:    11/9/95
00444     Inputs:     pSpread  - 
00445                 pView - 
00446     Returns:    OilCoord
00447     Purpose:    Convert SpreadCoord (AKA DocCoord) to an OilCoord
00448 *********************************************************************************************/
00449 
00450 OilCoord DocCoord::ToOil(Spread* pSpread, View* pView)
00451 {
00452     WorkCoord ScrollOffsets(0,0);
00453     if (pView!=NULL)
00454         ScrollOffsets=pView->GetScrollOffsets();
00455     else
00456         ERROR3("DocCoord::ToOil() - pView==NULL");
00457 
00458     return ToDoc(pSpread,pView).ToWork(pSpread,pView).ToOil(ScrollOffsets);
00459 }
00460  
00461 
00462 /***********************************************************************************************
00463 
00464 >   Chapter* DocCoord::FindEnclosingChapter(Document *pDocument, 
00465                                             DocCoord* ChapterPos, 
00466                                             XLONG* ChapterDepth);  
00467 
00468     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
00469     Created:    30/4/93
00470     Inputs:     pDocument - the document we are converting in.
00471                 pView - the View to use for pixelising.
00472     Outputs:    ChapterPos:   The top left hand corner of the chapters pasteboard rectangle 
00473                 ChapterDepth: The Sum of the lengths of all preceding chapters   
00474                 
00475     Returns:    If this coord is enclosed within a chapter then the chapter is returned               
00476                 else NULL is returned (In the non DEBUG version). 
00477                  
00478     Purpose:    For finding the enclosing chapter of a DocCoord, the position of the start 
00479                 of the enclosing chapter, and the chapters depth.
00480 
00481     Scope:      Private
00482 
00483     Errors:     An ERROR3 will occur if the DocCoord is not in any chapter
00484                 NOTE: The Spread Coordinate Origin for a spread MAY NOT reside INSIDE a
00485                 Chapter's Pasteboard bounds! See Spread::GetSpreadCoordOrigin for full
00486                 details of this.
00487 
00488     SeeAlso:    -
00489 
00490 *********************************************************************************************/
00491  
00492 Chapter* DocCoord::FindEnclosingChapter(Document *pDocument, 
00493                                         DocCoord* ChapterPos, 
00494                                         XLONG* ChapterDepth,
00495                                         View *pView)
00496 {
00497     Chapter* CurrentChapter = Node::FindFirstChapter(pDocument);
00498     // Search all chapters
00499     *ChapterDepth = 0;
00500     DocRect CurrentChaptersPasteboardRect;
00501 
00502     while (CurrentChapter != NULL)
00503     {
00504         CurrentChaptersPasteboardRect = CurrentChapter->GetPasteboardRect(TRUE, pView);
00505 
00506         if (CurrentChaptersPasteboardRect.ContainsRectCoord(*this))
00507         {
00508             // Chapter position is the top left hand corner of the chapters pasteboard
00509             ChapterPos->x = CurrentChaptersPasteboardRect.LowCorner().x;
00510             ChapterPos->y = CurrentChaptersPasteboardRect.HighCorner().y;
00511             return (CurrentChapter);
00512         }
00513 
00514         (*ChapterDepth) += CurrentChaptersPasteboardRect.Height();
00515         CurrentChapter = CurrentChapter->FindNextChapter();
00516     }
00517 
00518     // The DocCoord was not found in any chapter
00519     ERROR3("DocCoord::FindEnclosingChapter: Coord wasn't in any chapter. See the function help for debugging tips");
00520     return(NULL);
00521 }
00522 
00523 
00524 
00525 
00526 
00527 
00528 /*********************************************************************************************
00529 >   BOOL DocCoord::Pixelise(View* pView)
00530 
00531     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00532     Created:    21/11/94
00533     Inputs:     The view we are pixelising for.
00534     Purpose:    Modifies this DocCoord to lie on an exact pixel boundary.
00535     Scope:      Public
00536     SeeAlso:    DocCoord::SetScaledPixelSize()
00537 
00538 **********************************************************************************************/
00539 /*
00540     Technical notes:
00541     This routine ensures that the coordinate is aligned to a whole pixel boundary at all times
00542     by dividing and re-multiplying by the pixel size (YUK).
00543 
00544     Note that when a negative value is divided in C++ it is done so without regard for the
00545     sign of the value.
00546     E.g.
00547         21 / 4 =  5 Result has been truncated towards 0, moving Y coordinates down
00548         -21/ 4 = -5 Result has been truncated towards 0 again, moving Y coordinates UP!!!
00549     In other words when the values are coordinates the division truncates them in different
00550     directions depending which side of the origin they are on!
00551     This is obviously not required and so any negative values are adjusted before the division
00552     to ensure the end result is movement in the same direction as positive values.
00553 
00554     Range of scaled pixel width/height:
00555         Min:    ScaledPixelsize = 1(millipoint) / 40 (4000%) = 0.025
00556         Max:    ScaledPixelSize = 2000 (1/36th of an inch) / 0.05 (5%) = 40,000
00557     These values fit nicely into a Fixed16 so they should be correct on the way into the
00558     pixelising maths. However, Fixed16s cannot be combined with INT32s easily and they would not
00559     be accuarate enough to hold the possible pixel values. So, the pixelising maths is all done
00560     using floating point doubles.
00561 
00562 ********************************************************************************************/
00563 
00564 BOOL DocCoord::Pixelise(View* pView)
00565 {
00566     // See if the view is ok
00567     if (pView==NULL)
00568         return FALSE;
00569 
00570     FIXED16 pw,ph;
00571     pView->GetScaledPixelSize(&pw,&ph);
00572     x = (INT32) ( (floor(0.5 + (double)x / pw.MakeDouble())) * pw.MakeDouble() );
00573     y = (INT32) ( (floor(0.5 + (double)y / ph.MakeDouble())) * ph.MakeDouble() );
00574 
00575     return TRUE;
00576 }
00577 
00578 
00579 /*********************************************************************************************
00580 >   BOOL DocCoord::IsPixelised(View* pView)
00581 
00582     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00583     Created:    21/11/94
00584     Inputs:     The view we are pixelising for.
00585     Outputs:    -
00586     Returns:    TRUE if this DocCoord is already pixelised
00587                 FALSE otherwise
00588     Purpose:    Modifies this DocCoord to lie on an exact pixel boundary.
00589     Scope:      Public
00590 
00591 **********************************************************************************************/
00592 
00593 BOOL DocCoord::IsPixelised(View* pView)
00594 {
00595     // See if the view is ok
00596     if (pView==NULL)
00597         return FALSE;
00598 
00599     // Now pixelise a temp copy of this coord and see if it changed at all...
00600     DocCoord temp(x,y);
00601     temp.Pixelise(pView);
00602     return (x==temp.x && y==temp.y);
00603 }
00604 
00605 
00606 /*********************************************************************************************
00607 
00608 >   static BOOL DocCoord::Pixelise()
00609 
00610     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00611     Created:    21/11/94
00612     Inputs:     -
00613     Outputs:    -
00614     Returns:    -
00615     Purpose:    Modifies this DocCoord to lie on an exact pixel boundary.
00616     Errors:     -
00617     Scope:      Public
00618     SeeAlso:    DocCoord::SetScaledPixelSize()
00619 
00620 **********************************************************************************************/
00621 
00622 // NB. This is a bodge until I fix all the callers of Pixelise to pass in the View (Tim).
00623 
00624 BOOL DocCoord::Pixelise()
00625 {
00626     // BODGE: ...until I can be bothered to get callers to pass view in...  (Tim)
00627     return Pixelise(View::GetCurrent());
00628 }
00629 
00630 #endif  // EXCLUDE_FROM_XARLIB
00631 
00632 /********************************************************************************************
00633 
00634 >   DocCoord operator + (const DocCoord& One, const DocCoord& Two)
00635 
00636     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00637     Created:    15/12/94
00638     Inputs:     One - The first DocCoord
00639                 Two - The second DocCoord
00640     Returns:    The result of adding the two DocCoords together.
00641     Purpose:    Adds two DocCoords together. ie One.x+Two.x, One.y+Two.y
00642 
00643 ********************************************************************************************/
00644 
00645 DocCoord operator + (const DocCoord& One, const DocCoord& Two)
00646 {
00647     DocCoord Result;
00648 
00649     // Add the two DocCoords together
00650     Result.x = One.x + Two.x;
00651     Result.y = One.y + Two.y;
00652 
00653     // return the result
00654     return Result;
00655 }
00656 
00657 
00658 /********************************************************************************************
00659 
00660 >   DocCoord operator - (const DocCoord& One, const DocCoord& Two)
00661 
00662     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00663     Created:    15/12/94
00664     Inputs:     One - The first DocCoord
00665                 Two - The second DocCoord
00666     Returns:    the DocCoord that is the first DocCoord minus the second DocCoord
00667     Purpose:    Subtracts the two DocCoords.  ie One.x-Two.x, One.y-Two.y
00668 
00669 ********************************************************************************************/
00670 
00671 DocCoord operator - (const DocCoord& One, const DocCoord& Two)
00672 {
00673     DocCoord Result;
00674 
00675     // Subtract the two DocCoords from each other
00676     Result.x = One.x - Two.x;
00677     Result.y = One.y - Two.y;
00678 
00679     // return the result
00680     return Result;
00681 }
00682 
00683 /********************************************************************************************
00684 
00685 >   const DocCoord& DocCoord::operator += ( const DocCoord &Other )
00686 
00687     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
00688     Created:    29/4/00
00689     Inputs:     Other   - The other DocCoord value, that's being added to the original.
00690     Returns:    A reference to the current object, for concatentation
00691     Purpose:    Adds a DocCoord value onto the current object.
00692 
00693 ********************************************************************************************/
00694 
00695 const DocCoord& DocCoord::operator += ( const DocCoord &Other )
00696 {
00697     // Add the other DocCoord's values onto this object's.
00698     x += Other.x;
00699     y += Other.y;
00700 
00701     return *this;
00702 }
00703 
00704 /********************************************************************************************
00705 
00706 >   const DocCoord& DocCoord::operator -= ( const DocCoord &Other )
00707 
00708     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
00709     Created:    29/4/00
00710     Inputs:     Other   - The other DocCoord value, that's being subtracted from this one.
00711     Returns:    A reference to the current object, for concatentation
00712     Purpose:    Subtracts a DocCoord value from the current object.
00713 
00714 ********************************************************************************************/
00715 
00716 const DocCoord& DocCoord::operator -= ( const DocCoord &Other )
00717 {
00718     // Add the other DocCoord's values onto this object's.
00719     x -= Other.x;
00720     y -= Other.y;
00721 
00722     return *this;
00723 }
00724 
00725 /*******************************************************************************************
00726 >   static DocCoord DocCoord::PositionPointFromRatio(const DocCoord& StartPoint, const DocCoord& EndPoint, const double Ratio)
00727 
00728     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00729     Created:    12/12/95
00730     Inputs:     StartPoint and EndPoint define the start and end of a line
00731                 Ratio is the ratio of the distance from start to end that you want the coordinate of
00732     Outputs:    -
00733     Returns:    The coordinate of the position of the ratio (err, does that make sense?)
00734     Purpose:    Gives the coordinate of a point specified by a ratio along a line defined by
00735                 two other points.  A ratio of zero gives the same point as the start of the
00736                 line, 0.5 gives the mid point of the line, etc.  Negative ratio give a point
00737                 before the start, ratios greater than 1 give points beyond the end
00738 ********************************************************************************************/
00739 DocCoord DocCoord::PositionPointFromRatio(const DocCoord& StartPoint, const DocCoord& EndPoint, const double Ratio)
00740 {
00741     DocCoord result;
00742     
00743     result.x = StartPoint.x + (INT32)((EndPoint.x - StartPoint.x)*Ratio) ;
00744     result.y = StartPoint.y + (INT32)((EndPoint.y - StartPoint.y)*Ratio) ;
00745 
00746     return result;
00747 } 
00748 
00749 
00750 /*******************************************************************************************
00751 >   static double DocCoord::DistanceFromLine(const DocCoord& Line1, const DocCoord& Line2, const DocCoord& Point)
00752 
00753     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00754     Created:    12/12/95
00755     Inputs:     Line1 and Line2 are two points defining a line that passes through those points
00756                 Point is another point
00757     Outputs:    -
00758     Returns:    The perpendicular distance from the line to the point. 
00759     Purpose:    Gets the shortest distance from the line to the point.
00760     Errors:     Will return -1 if a division by zero case was detected
00761 ********************************************************************************************/
00762 double DocCoord::DistanceFromLine(const DocCoord& Line1, const DocCoord& Line2, const DocCoord& Point)
00763 {
00764     // Obtain perpendicular distance from the axes line (see A-Level maths page 24)
00765     const double X1 = Line1.x;
00766     const double Y1 = Line1.y;
00767     const double X2 = Line2.x;
00768     const double Y2 = Line2.y;
00769 
00770     const double a = -Y2+Y1;
00771     const double b =  X2-X1;
00772     const double c = -(Y1*X2) + (Y1*X1) + (X1*Y2) - (X1*Y1);
00773 
00774     const double divisor = sqrt( a*a + b*b );
00775     
00776     // We don't want any nasty floating point div 0, thank you
00777     double Distance = -1.0;
00778     if (divisor >= 0.0001)
00779         Distance = fabs(( a*Point.x + b*Point.y + c )/divisor);    
00780 
00781     return Distance;
00782 }
00783 
00784 
00785 
00786 /*******************************************************************************************
00787 >   static DocCoord DocCoord::OneThird(const DocCoord& Start, const DocCoord& End)
00788 
00789     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00790     Created:    12/12/95
00791     Inputs:     Start and End are two coordinates
00792     Outputs:    -
00793     Returns:    The point one third of the way from Start to End
00794     Purpose:    For getting a point one third of the way between two other points
00795 ********************************************************************************************/
00796 DocCoord DocCoord::OneThird(const DocCoord& Start, const DocCoord& End)
00797 {
00798     DocCoord result;
00799 
00800     result.x = Start.x + (INT32)((End.x - Start.x)/3) ;
00801     result.y = Start.y + (INT32)((End.y - Start.y)/3) ;
00802 
00803     return result;
00804 }
00805 
00806 
00807 
00808 /*******************************************************************************************
00809 >   static DocCoord DocCoord::TwoThirds(const DocCoord& Start, const DocCoord& End)
00810 
00811     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00812     Created:    12/12/95
00813     Inputs:     Start and End are two coordinates
00814     Outputs:    -
00815     Returns:    The point two thirds of the way from Start to End
00816     Purpose:    For getting a point two thirds of the way between two other points
00817 ********************************************************************************************/
00818 DocCoord DocCoord::TwoThirds(const DocCoord& Start, const DocCoord& End)
00819 {
00820     DocCoord result;
00821 
00822     result.x = Start.x + (INT32)((End.x - Start.x)*(2.0/3.0)) ;
00823     result.y = Start.y + (INT32)((End.y - Start.y)*(2.0/3.0)) ;
00824 
00825     return result;
00826 }
00827 
00828 
00829 
00830 /*******************************************************************************************
00831 >   static DocCoord DocCoord::OneHalf(const DocCoord& Start, const DocCoord& End)
00832 
00833     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00834     Created:    12/12/95
00835     Inputs:     Start and End are two coordinates
00836     Outputs:    -
00837     Returns:    The point one half of the way from Start to End
00838     Purpose:    For getting a point midway between two other points
00839 ********************************************************************************************/
00840 DocCoord DocCoord::OneHalf(const DocCoord& Start, const DocCoord& End)
00841 {
00842     DocCoord result;
00843 
00844     result.x = Start.x + (INT32)((End.x - Start.x)/2) ;
00845     result.y = Start.y + (INT32)((End.y - Start.y)/2) ;
00846 
00847     return result;
00848 }
00849 
00850 
00851 
00852 /********************************************************************************************
00853 >   BOOL DocCoord::IsJoinAcute(const DocCoord* pJoin, const DocCoord* pOtherEndOfJoin, const DocCoord* pOtherPoint)
00854 
00855     Author:     Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
00856     Created:    13/12/95
00857     Inputs:     pJoin - the coordinate where two lines join
00858                 pOtherEndOfJoin - another point that with pJoin defines a line
00859                 pOtherPoint - another point that with pJoin defines another line
00860     Outputs:    -
00861     Returns:    TRUE if the angle between the two lines is an acute angle
00862     Purpose:    For seeing the perpendicual distance from pOtherPoint to the line
00863                 pJoin-pOtherEndOfJoin end on the line or before pJoin.  Used when dragging
00864                 along a line to see if the drag point has gon back beyond the start of the
00865                 line.
00866 ********************************************************************************************/
00867 BOOL DocCoord::IsJoinAcute(const DocCoord* pJoin, const DocCoord* pOtherEndOfJoin, const DocCoord* pOtherPoint)
00868 {
00869     // Translate the points so the join is on the origin and the other points are relative to that
00870     DocCoord OriginLine = *pOtherEndOfJoin - *pJoin;
00871     DocCoord OriginOther = *pOtherPoint - *pJoin;
00872     double LineAngle = atan2((double)OriginLine.y, (double)OriginLine.x);
00873     double OtherAngle = atan2((double)OriginOther.y, (double)OriginOther.x);
00874 
00875     double diff = OtherAngle - LineAngle;
00876     if (diff < -PI)
00877         diff += 2*PI;
00878     if (diff > PI)
00879         diff -= 2*PI;
00880 
00881     if ( (diff < -(PI/2)) || (diff > (PI/2)) )
00882         return FALSE;
00883     else
00884         return TRUE;
00885 }
00886 
00887 /********************************************************************************************
00888 
00889  >  void DocCoord::Scale(const DocCoord dcOrigin, const double dDPI=96.0)
00890                                            
00891     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
00892     Created:    16/4/97
00893     Inputs:     dDPI        The DPI by which to scale the coord
00894                 dcOrigin    The origin by which to scale the coord
00895   
00896   Purpose:      Scales the DocCoord by the specified DPI and origin.
00897 
00898                 That is, this function does the following to this DocCoord:
00899 
00900                 a. Subtracts the origin dcOrigin
00901                 b. Inverts the y-axis
00902                 c. Multiplies the coordinate to convert them to the number
00903                    of DPI specified.
00904 
00905                 Used in imagemaps.
00906 
00907                 Note that, technically, what this function produces should be
00908                 a WorkCoord. But that causes problems, because this
00909                 function is called to scale paths to bitmap coordinates - and
00910                 you can't specify a path in terms of WorkCoords.
00911             
00912 SeeAlso:        Path::Scale(), Imagemap::AddPolygon()
00913     
00914 ********************************************************************************************/
00915 
00916 void DocCoord::Scale(const DocCoord dcOrigin, const double dDPI)
00917 {
00918     //Subtract the origin from this coord
00919     x-=dcOrigin.x;
00920     y-=dcOrigin.y;
00921 
00922     //And scale by the appropriate DPI, inverting the y-axis
00923     //and rounding to the nearest pixel
00924     x=INT32(x*(dDPI/72000.0)+0.5);
00925     y=INT32(-y*(dDPI/72000.0)+0.5);
00926     
00927 }
00928 
00929 

Generated on Sat Nov 10 03:45:02 2007 for Camelot by  doxygen 1.4.4