00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104
00105
00106
00107
00108
00109 #include "gdraw.h"
00110 #include "grndrgn.h"
00111
00112
00113
00114 DECLARE_SOURCE("$Revision: 1282 $");
00115
00116 CC_IMPLEMENT_DYNCREATE(ArrowRec, CCObject)
00117
00118
00119 #define new CAM_DEBUG_NEW
00120
00121 const INT32 ZEROWIDTH_ARROW_LINEWIDTH = (72000/64);
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 ArrowRec::ArrowRec()
00136 {
00137 ArrowShape = NULL;
00138 Centre = DocCoord(0,0);
00139
00140 LineWidth = DEFAULT_ARROW_LINEWIDTH;
00141 ArrowWidth = 3;
00142 ArrowHeight = 3;
00143
00144 StartArrow = FALSE;
00145 ScaleWithLineWidth = TRUE;
00146 ArrowID = 0;
00147
00148 m_bExtendPath = TRUE;
00149
00150 IsNull = TRUE;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 ArrowRec::ArrowRec(Path* pArrowPath, const DocCoord& ArrowCentre,
00175 INT32 ArrowLineWidth,
00176 FIXED16 ArrowWidthScale, FIXED16 ArrowHeightScale,
00177 BOOL Start)
00178 {
00179 ArrowShape = pArrowPath;
00180 Centre = ArrowCentre;
00181
00182 LineWidth = ArrowLineWidth;
00183 ArrowWidth = ArrowWidthScale;
00184 ArrowHeight = ArrowHeightScale;
00185
00186 StartArrow = Start;
00187
00188 ScaleWithLineWidth = TRUE;
00189 ArrowID = -1;
00190
00191 m_bExtendPath = TRUE;
00192
00193 IsNull = FALSE;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 ArrowRec::ArrowRec(const ArrowRec& OtherArrow)
00209 {
00210 *this = OtherArrow;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 ArrowRec::~ArrowRec()
00226 {
00227 if (ArrowShape != NULL)
00228 delete ArrowShape;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 BOOL ArrowRec::CreateStockArrow(StockArrow ArrowType)
00246 {
00247 if (ArrowShape != NULL)
00248 {
00249 delete ArrowShape;
00250 ArrowShape = NULL;
00251 }
00252
00253 BOOL ok;
00254 Path* pPath;
00255
00256 const INT32 Size = 3;
00257 const INT32 Width = (72000/2)*3;
00258
00259 if (ArrowType >= NUM_STOCK_ARROWS)
00260 ArrowType = SA_STRAIGHTARROW;
00261
00262
00263 ArrowID = ArrowType;
00264
00265 switch (ArrowType)
00266 {
00267 case SA_STRAIGHTARROW:
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 pPath = new Path();
00280 if (pPath == NULL)
00281 return FALSE;
00282
00283 ok = pPath->Initialise(4);
00284 if (ok) pPath->FindStartOfPath();
00285 if (ok) ok = pPath->InsertMoveTo(DocCoord( -9000, 54000));
00286 if (ok) ok = pPath->InsertLineTo(DocCoord( -9000, -54000));
00287 if (ok) ok = pPath->InsertLineTo(DocCoord(117000, 0));
00288 if (ok) ok = pPath->CloseSubPath();
00289
00290 if (!ok)
00291 {
00292 delete pPath;
00293 return FALSE;
00294 }
00295
00296 pPath->IsFilled = TRUE;
00297 pPath->IsStroked = FALSE;
00298
00299 ArrowShape = pPath;
00300 Centre = DocCoord(0,0);
00301 LineWidth = Width;
00302 ArrowWidth = INT32(Size);
00303 ArrowHeight = INT32(Size);
00304 IsNull = FALSE;
00305
00306 StartArrow = FALSE;
00307
00308 break;
00309
00310 case SA_ANGLEDARROW:
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 pPath = new Path();
00322 if (pPath == NULL)
00323 return FALSE;
00324
00325 ok = pPath->Initialise(5);
00326 if (ok) pPath->FindStartOfPath();
00327 if (ok) ok = pPath->InsertMoveTo(DocCoord(-27000, 54000));
00328 if (ok) ok = pPath->InsertLineTo(DocCoord( -9000, 0));
00329 if (ok) ok = pPath->InsertLineTo(DocCoord(-27000, -54000));
00330 if (ok) ok = pPath->InsertLineTo(DocCoord(135000, 0));
00331 if (ok) ok = pPath->CloseSubPath();
00332
00333 if (!ok)
00334 {
00335 delete pPath;
00336 return FALSE;
00337 }
00338
00339 pPath->IsFilled = TRUE;
00340 pPath->IsStroked = FALSE;
00341
00342 ArrowShape = pPath;
00343 Centre = DocCoord(0,0);
00344 LineWidth = Width;
00345 ArrowWidth = INT32(Size);
00346 ArrowHeight = INT32(Size);
00347 IsNull = FALSE;
00348
00349 StartArrow = FALSE;
00350
00351 break;
00352
00353
00354 case SA_ROUNDEDARROW:
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 pPath = new Path();
00370 if (pPath == NULL)
00371 return FALSE;
00372
00373 ok = pPath->Initialise(17);
00374 if (ok) pPath->FindStartOfPath();
00375 if (ok) ok = pPath->InsertMoveTo( DocCoord( -9000, 0));
00376 if (ok) ok = pPath->InsertLineTo( DocCoord( -9000, -45000));
00377 if (ok) ok = pPath->InsertCurveTo(DocCoord( -9000, -51708),
00378 DocCoord( 2808, -56580),
00379 DocCoord( 9000, -54000));
00380 if (ok) ok = pPath->InsertLineTo( DocCoord( 117000, -9000));
00381 if (ok) ok = pPath->InsertCurveTo(DocCoord( 120916, -7369),
00382 DocCoord( 126000, -4242),
00383 DocCoord( 126000, 0));
00384 if (ok) ok = pPath->InsertCurveTo(DocCoord( 126000, 4242),
00385 DocCoord( 120916, 7369),
00386 DocCoord( 117000, 9000));
00387 if (ok) ok = pPath->InsertLineTo( DocCoord( 9000, 54000));
00388 if (ok) ok = pPath->InsertCurveTo(DocCoord( 2808, 56580),
00389 DocCoord( -9000, 51708),
00390 DocCoord( -9000, 45000));
00391 if (ok) ok = pPath->CloseSubPath();
00392
00393 if (!ok)
00394 {
00395 delete pPath;
00396 return FALSE;
00397 }
00398
00399 pPath->IsFilled = TRUE;
00400 pPath->IsStroked = FALSE;
00401
00402 ArrowShape = pPath;
00403 Centre = DocCoord(0,0);
00404 LineWidth = Width;
00405 ArrowWidth = INT32(Size);
00406 ArrowHeight = INT32(Size);
00407 IsNull = FALSE;
00408
00409 StartArrow = FALSE;
00410
00411 break;
00412
00413
00414 case SA_SPOT:
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 pPath = new Path();
00426 if (pPath == NULL)
00427 return FALSE;
00428
00429 ok = pPath->Initialise(14);
00430 if (ok) pPath->FindStartOfPath();
00431 if (ok) ok = pPath->InsertMoveTo( DocCoord( -54000, 0));
00432 if (ok) ok = pPath->InsertCurveTo(DocCoord( -54000, 29807),
00433 DocCoord( -29807, 54000),
00434 DocCoord( 0, 54000));
00435 if (ok) ok = pPath->InsertCurveTo(DocCoord( 29807, 54000),
00436 DocCoord( 54000, 29807),
00437 DocCoord( 54000, 0));
00438 if (ok) ok = pPath->InsertCurveTo(DocCoord( 54000, -29807),
00439 DocCoord( 29807, -54000),
00440 DocCoord( 0, -54000));
00441 if (ok) ok = pPath->InsertCurveTo(DocCoord( -29807, -54000),
00442 DocCoord( -54000, -29807),
00443 DocCoord( -54000, 0));
00444 if (ok) ok = pPath->CloseSubPath();
00445
00446 if (!ok)
00447 {
00448 delete pPath;
00449 return FALSE;
00450 }
00451
00452 pPath->IsFilled = TRUE;
00453 pPath->IsStroked = FALSE;
00454
00455 ArrowShape = pPath;
00456 Centre = DocCoord(0,0);
00457 LineWidth = Width;
00458 ArrowWidth = INT32(Size);
00459 ArrowHeight = INT32(Size);
00460 IsNull = FALSE;
00461
00462 StartArrow = TRUE;
00463
00464 break;
00465
00466
00467 case SA_DIAMOND:
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 pPath = new Path();
00479 if (pPath == NULL)
00480 return FALSE;
00481
00482 ok = pPath->Initialise(5);
00483 if (ok) pPath->FindStartOfPath();
00484 if (ok) ok = pPath->InsertMoveTo(DocCoord(-63000, 0));
00485 if (ok) ok = pPath->InsertLineTo(DocCoord( 0, 63000));
00486 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, 0));
00487 if (ok) ok = pPath->InsertLineTo(DocCoord( 0, -63000));
00488 if (ok) ok = pPath->CloseSubPath();
00489
00490 if (!ok)
00491 {
00492 delete pPath;
00493 return FALSE;
00494 }
00495
00496 pPath->IsFilled = TRUE;
00497 pPath->IsStroked = FALSE;
00498
00499 ArrowShape = pPath;
00500 Centre = DocCoord(0,0);
00501 LineWidth = Width;
00502 ArrowWidth = INT32(Size);
00503 ArrowHeight = INT32(Size);
00504 IsNull = FALSE;
00505
00506 StartArrow = TRUE;
00507
00508 break;
00509
00510 case SA_ARROWFEATHER:
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 pPath = new Path();
00524 if (pPath == NULL)
00525 return FALSE;
00526
00527 ok = pPath->Initialise(7);
00528 if (ok) pPath->FindStartOfPath();
00529 if (ok) ok = pPath->InsertMoveTo(DocCoord( 18000, -54000));
00530 if (ok) ok = pPath->InsertLineTo(DocCoord(108000, -54000));
00531 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, 0));
00532 if (ok) ok = pPath->InsertLineTo(DocCoord(108000, 54000));
00533 if (ok) ok = pPath->InsertLineTo(DocCoord( 18000, 54000));
00534 if (ok) ok = pPath->InsertLineTo(DocCoord(-36000, 0));
00535 if (ok) ok = pPath->CloseSubPath();
00536
00537 if (!ok)
00538 {
00539 delete pPath;
00540 return FALSE;
00541 }
00542
00543 pPath->IsFilled = TRUE;
00544 pPath->IsStroked = FALSE;
00545
00546 ArrowShape = pPath;
00547 Centre = DocCoord(0,0);
00548 LineWidth = Width;
00549 ArrowWidth = INT32(Size);
00550 ArrowHeight = INT32(Size);
00551 IsNull = FALSE;
00552
00553 StartArrow = TRUE;
00554
00555 break;
00556
00557 case SA_ARROWFEATHER2:
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 pPath = new Path();
00587 if (pPath == NULL)
00588 return FALSE;
00589
00590 ok = pPath->Initialise(23);
00591 if (ok) pPath->FindStartOfPath();
00592 if (ok) ok = pPath->InsertMoveTo(DocCoord( -36000, 0));
00593 if (ok) ok = pPath->InsertLineTo(DocCoord( 18000, -54000));
00594 if (ok) ok = pPath->InsertLineTo(DocCoord( 54000, -54000));
00595 if (ok) ok = pPath->InsertLineTo(DocCoord( 18000, -18000));
00596 if (ok) ok = pPath->InsertLineTo(DocCoord( 27000, -18000));
00597 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, -54000));
00598 if (ok) ok = pPath->InsertLineTo(DocCoord( 99000, -54000));
00599 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, -18000));
00600 if (ok) ok = pPath->InsertLineTo(DocCoord( 72000, -18000));
00601 if (ok) ok = pPath->InsertLineTo(DocCoord( 108000, -54000));
00602 if (ok) ok = pPath->InsertLineTo(DocCoord( 144000, -54000));
00603 if (ok) ok = pPath->InsertLineTo(DocCoord( 90000, 0));
00604 if (ok) ok = pPath->InsertLineTo(DocCoord( 144000, 54000));
00605 if (ok) ok = pPath->InsertLineTo(DocCoord( 108000, 54000));
00606 if (ok) ok = pPath->InsertLineTo(DocCoord( 72000, 18000));
00607 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, 18000));
00608 if (ok) ok = pPath->InsertLineTo(DocCoord( 99000, 54000));
00609 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, 54000));
00610 if (ok) ok = pPath->InsertLineTo(DocCoord( 27000, 18000));
00611 if (ok) ok = pPath->InsertLineTo(DocCoord( 18000, 18000));
00612 if (ok) ok = pPath->InsertLineTo(DocCoord( 54000, 54000));
00613 if (ok) ok = pPath->InsertLineTo(DocCoord( 18000, 54000));
00614 if (ok) ok = pPath->CloseSubPath();
00615
00616 if (!ok)
00617 {
00618 delete pPath;
00619 return FALSE;
00620 }
00621
00622 pPath->IsFilled = TRUE;
00623 pPath->IsStroked = FALSE;
00624
00625 ArrowShape = pPath;
00626 Centre = DocCoord(0,0);
00627 LineWidth = Width;
00628 ArrowWidth = INT32(Size);
00629 ArrowHeight = INT32(Size);
00630 IsNull = FALSE;
00631
00632 StartArrow = TRUE;
00633
00634 break;
00635
00636 case SA_HOLLOWDIAMOND:
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 pPath = new Path();
00653 if (pPath == NULL)
00654 return FALSE;
00655
00656 ok = pPath->Initialise(10);
00657 if (ok) pPath->FindStartOfPath();
00658 if (ok) ok = pPath->InsertMoveTo(DocCoord( 0, 45000));
00659 if (ok) ok = pPath->InsertLineTo(DocCoord(-45000, 0));
00660 if (ok) ok = pPath->InsertLineTo(DocCoord( 0, -45000));
00661 if (ok) ok = pPath->InsertLineTo(DocCoord( 45000, 0));
00662 if (ok) ok = pPath->CloseSubPath();
00663 if (ok) ok = pPath->InsertMoveTo(DocCoord( 0, 63000));
00664 if (ok) ok = pPath->InsertLineTo(DocCoord(-63000, 0));
00665 if (ok) ok = pPath->InsertLineTo(DocCoord( 0, -63000));
00666 if (ok) ok = pPath->InsertLineTo(DocCoord( 63000, 0));
00667 if (ok) ok = pPath->CloseSubPath();
00668
00669 if (!ok)
00670 {
00671 delete pPath;
00672 return FALSE;
00673 }
00674
00675 pPath->IsFilled = TRUE;
00676 pPath->IsStroked = FALSE;
00677
00678 ArrowShape = pPath;
00679 Centre = DocCoord(-45000,0);
00680 LineWidth = Width;
00681 ArrowWidth = INT32(Size);
00682 ArrowHeight = INT32(Size);
00683 IsNull = FALSE;
00684
00685 StartArrow = TRUE;
00686
00687 break;
00688
00689 default:
00690 ArrowShape = NULL;
00691 Centre = DocCoord(0,0);
00692
00693 LineWidth = DEFAULT_ARROW_LINEWIDTH;
00694 ArrowWidth = 3;
00695 ArrowHeight = 3;
00696
00697 StartArrow = FALSE;
00698 ScaleWithLineWidth = TRUE;
00699 ArrowID = SA_NULLARROW;
00700 IsNull = TRUE;
00701 break;
00702 }
00703
00704 return TRUE;
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 String_256 ArrowRec::GetStockArrowName(StockArrow ArrowType)
00721 {
00722 String_256 ArrowName = String_256(_R(IDS_K_ARROWS_DEFAULTARROW));
00723
00724 switch (ArrowType)
00725 {
00726 case SA_STRAIGHTARROW:
00727 ArrowName.Load(_R(IDS_K_ARROWS_STRAIGHTARROW));
00728 break;
00729
00730 case SA_ANGLEDARROW:
00731 ArrowName.Load(_R(IDS_K_ARROWS_ANGLEDARROW));
00732 break;
00733
00734 case SA_ROUNDEDARROW:
00735 ArrowName.Load(_R(IDS_K_ARROWS_ROUNDEDARROW));
00736 break;
00737
00738 case SA_SPOT:
00739 ArrowName.Load(_R(IDS_K_ARROWS_SPOT));
00740 break;
00741
00742 case SA_DIAMOND:
00743 ArrowName.Load(_R(IDS_K_ARROWS_DIAMOND));
00744 break;
00745
00746 case SA_ARROWFEATHER:
00747 ArrowName.Load(_R(IDS_K_ARROWS_ARROWFEATHER));
00748 break;
00749
00750 case SA_ARROWFEATHER2:
00751 ArrowName.Load(_R(IDS_K_ARROWS_ARROWFEATHER2));
00752 break;
00753
00754 case SA_HOLLOWDIAMOND:
00755 ArrowName.Load(_R(IDS_K_ARROWS_HOLLOWDIAMOND));
00756 break;
00757
00758 default:
00759 ArrowName = "";
00760 break;
00761 }
00762
00763 return ArrowName;
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 void ArrowRec::SetArrowSize(FIXED16 Width, FIXED16 Height)
00780 {
00781 ArrowWidth = Width;
00782 ArrowHeight = (Height > 0) ? Height : Width;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 ArrowRec& ArrowRec::operator=(const ArrowRec& OtherArrow)
00799 {
00800 if (ArrowShape != NULL)
00801 {
00802 delete ArrowShape;
00803 ArrowShape = NULL;
00804 }
00805
00806 if (OtherArrow.ArrowShape != NULL)
00807 {
00808
00809 ArrowShape = new Path();
00810 if (ArrowShape == NULL)
00811 return (*this);
00812
00813
00814 BOOL ok = ArrowShape->Initialise(OtherArrow.ArrowShape->GetNumCoords());
00815 if (ok) ok = ArrowShape->CopyPathDataFrom(OtherArrow.ArrowShape);
00816
00817 if (!ok)
00818 {
00819
00820 delete ArrowShape;
00821 ArrowShape = NULL;
00822 }
00823 }
00824
00825 Centre = OtherArrow.Centre;
00826
00827 LineWidth = OtherArrow.LineWidth;
00828 ArrowWidth = OtherArrow.ArrowWidth;
00829 ArrowHeight = OtherArrow.ArrowHeight;
00830
00831 StartArrow = OtherArrow.StartArrow;
00832 ArrowID = OtherArrow.ArrowID;
00833
00834 ScaleWithLineWidth = OtherArrow.ScaleWithLineWidth;
00835
00836 m_bExtendPath = OtherArrow.m_bExtendPath;
00837
00838 IsNull = OtherArrow.IsNull;
00839
00840 return (*this);
00841 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 ArrowRec& ArrowRec::operator=(StockArrow ArrowType)
00859 {
00860
00861 CreateStockArrow(ArrowType);
00862
00863 return (*this);
00864 }
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 INT32 ArrowRec::operator==(const ArrowRec& OtherArrow)
00881 {
00882 if (ArrowShape == NULL && OtherArrow.ArrowShape == NULL)
00883 return TRUE;
00884
00885 if (ArrowShape == NULL || OtherArrow.ArrowShape == NULL)
00886 return FALSE;
00887
00888 INT32 NumCoords = ArrowShape->GetNumCoords();
00889 INT32 OtherNumCoords = OtherArrow.ArrowShape->GetNumCoords();
00890
00891 if (NumCoords != OtherNumCoords)
00892 return FALSE;
00893
00894 DocCoord* Coords = ArrowShape->GetCoordArray();
00895 PathVerb* Verbs = ArrowShape->GetVerbArray();
00896
00897 DocCoord* OtherCoords = OtherArrow.ArrowShape->GetCoordArray();
00898 PathVerb* OtherVerbs = OtherArrow.ArrowShape->GetVerbArray();
00899
00900 for (INT32 i=0; i<NumCoords; i++)
00901 {
00902 if (Coords[i] != OtherCoords[i] || Verbs[i] != OtherVerbs[i])
00903 return FALSE;
00904 }
00905
00906 TRACEUSER( "DavidM", wxT("ArrowRec::operator == %d %d\n"),
00907 m_bExtendPath, OtherArrow.m_bExtendPath);
00908
00909 return (Centre == OtherArrow.Centre &&
00910 LineWidth == OtherArrow.LineWidth &&
00911 ArrowWidth == OtherArrow.ArrowWidth &&
00912 ArrowHeight == OtherArrow.ArrowHeight &&
00913 StartArrow == OtherArrow.StartArrow &&
00914 m_bExtendPath == OtherArrow.m_bExtendPath);
00915 }
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 INT32 ArrowRec::operator==(StockArrow ArrowType)
00932 {
00933 ArrowRec TempArrow;
00934 TempArrow.CreateStockArrow(ArrowType);
00935 TempArrow.m_bExtendPath = m_bExtendPath;
00936
00937 return (*this == TempArrow);
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 Path* ArrowRec::GetArrowPath()
00953 {
00954 return ArrowShape;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969 DocCoord ArrowRec::GetArrowCentre()
00970 {
00971 return Centre;
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 INT32 ArrowRec::GetArrowLineWidth()
00987 {
00988 return LineWidth;
00989 }
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 FIXED16 ArrowRec::GetArrowWidth()
01005 {
01006 return ArrowWidth;
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 FIXED16 ArrowRec::GetArrowHeight()
01023 {
01024 return ArrowHeight;
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039 BOOL ArrowRec::IsStartArrow()
01040 {
01041 return StartArrow;
01042 }
01043
01044 BOOL ArrowRec::ShouldScaleWithLineWidth()
01045 {
01046 return ScaleWithLineWidth;
01047 }
01048
01049 INT32 ArrowRec::GetArrowID()
01050 {
01051 return ArrowID;
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 DocRect ArrowRec::GetArrowBoundingRect(Path* pParent, INT32 ParentLineWidth, BOOL StartArrow)
01074 {
01075 if (IsNullArrow())
01076 return DocRect(0,0,0,0);
01077
01078
01079
01080
01081
01082
01083
01084 DocRect Bounds(0,0,0,0);
01085
01086 INT32 PathIndex = 0;
01087 DocCoord ArrowCentre;
01088 DocCoord ArrowDirection;
01089
01090 DocCoord* Coords = pParent->GetCoordArray();
01091 PathVerb* Verbs = pParent->GetVerbArray();
01092 INT32 NumCoords = pParent->GetNumCoords();
01093
01094
01095
01096 BOOL GotPos = GetFirstArrowPos(StartArrow,
01097 Coords, Verbs, NumCoords,
01098 &PathIndex, &ArrowCentre, &ArrowDirection);
01099 while (GotPos)
01100 {
01101
01102 Bounds = Bounds.Union(FindBoundsAt(ArrowCentre, ArrowDirection, ParentLineWidth));
01103
01104
01105 GotPos = GetNextArrowPos(StartArrow,
01106 Coords, Verbs, NumCoords,
01107 &PathIndex, &ArrowCentre, &ArrowDirection);
01108 }
01109
01110
01111 return Bounds;
01112 }
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132 DocRect ArrowRec::FindBoundsAt(const DocCoord& ArrowCentre, const DocCoord& Direction,
01133 INT32 ParentLineWidth)
01134 {
01135 DocRect Bounds(0,0,0,0);
01136
01137
01138 Trans2DMatrix Trans;
01139 GetArrowMatrix(ArrowCentre, Direction, ParentLineWidth, &Trans);
01140
01141
01142
01143
01144
01145
01146
01147
01148 Path* TransPath = new Path();
01149 if (TransPath == NULL)
01150 return Bounds;
01151
01152
01153 BOOL ok = TransPath->Initialise(ArrowShape->GetNumCoords());
01154 if (ok) ok = TransPath->CopyPathDataFrom(ArrowShape);
01155
01156 if (!ok)
01157 {
01158
01159 delete TransPath;
01160 return Bounds;
01161 }
01162
01163
01164 Trans.Transform(TransPath->GetCoordArray(),
01165 TransPath->GetNumCoords() );
01166
01167 BOOL GDrawResult = FALSE;
01168
01169
01170
01171
01172 GDrawContext *GD = GRenderRegion::GetStaticDrawContext();
01173
01174 if (GD != NULL)
01175 GDrawResult = GD->CalcStrokeBBox((POINT*)TransPath->GetCoordArray(),
01176 TransPath->GetVerbArray(), TransPath->GetNumCoords(),
01177 (RECT *)(&Bounds),
01178 TRUE, 0, CAPS_ROUND, JOIN_ROUND, NULL) == 0;
01179
01180
01181 if (!GDrawResult)
01182 Bounds = TransPath->GetBoundingRect();
01183
01184
01185 delete TransPath;
01186
01187 return Bounds;
01188 }
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 BOOL ArrowRec::GetArrowMatrix(const DocCoord& ArrowCentre, const DocCoord& Direction,
01207 INT32 ParentLineWidth, Trans2DMatrix* pMatrix)
01208 {
01209 if (IsNullArrow())
01210 return FALSE;
01211
01212 TRACEUSER( "DavidM", wxT("ArrowRec::GetArrowMatrix %d\n"), m_bExtendPath );
01213
01214 ANGLE RotateAngle = CalcAngle(ArrowCentre, Direction);
01215
01216
01217 DocRect ArrowBounds = ArrowShape->GetBoundingRect();
01218
01219 double TempLineWidth = ParentLineWidth;
01220
01221 if (TempLineWidth == 0)
01222 TempLineWidth = ZEROWIDTH_ARROW_LINEWIDTH;
01223
01224 BOOL DoScale = ScaleWithLineWidth;
01225
01226 FIXED16 xscale = DoScale ? ((ArrowWidth.MakeDouble() * TempLineWidth) / LineWidth)
01227 : (ArrowWidth);
01228 FIXED16 yscale = DoScale ? ((ArrowHeight.MakeDouble() * TempLineWidth) / LineWidth)
01229 : (ArrowWidth);
01230
01231
01232 DocRect ArrowRect = ArrowShape->GetBoundingRect();
01233
01234 DocCoord centre;
01235
01236 if (!m_bExtendPath)
01237 {
01238 centre.x = ArrowRect.hi.x;
01239 centre.y = (ArrowRect.lo.y + ArrowRect.hi.y) / 2;
01240 }
01241 else
01242 {
01243 centre = Centre;
01244 }
01245
01246 Matrix Mat = Matrix(-centre.x,
01247 -centre.y);
01248 Mat *= Matrix(xscale, yscale);
01249 Mat *= Matrix(RotateAngle);
01250
01251 Mat *= Matrix(ArrowCentre);
01252
01253 Trans2DMatrix Trans(Mat);
01254
01255 *pMatrix = Trans;
01256
01257 return TRUE;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276 BOOL ArrowRec::DoesPathNeedArrowHeads(DocCoord* Coords, PathVerb* Verbs, INT32 NumCoords)
01277 {
01278
01279 BOOL FoundCloseFigure = TRUE;
01280
01281 for (INT32 coord=0; coord<NumCoords; coord++)
01282 {
01283 if (Verbs[coord] == PT_MOVETO)
01284 {
01285 if (!FoundCloseFigure)
01286 return TRUE;
01287
01288
01289 FoundCloseFigure = FALSE;
01290 }
01291
01292 if (Verbs[coord] & PT_CLOSEFIGURE)
01293 {
01294 FoundCloseFigure = TRUE;
01295 }
01296 }
01297
01298 if (!FoundCloseFigure)
01299 return TRUE;
01300
01301 return FALSE;
01302 }
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320 BOOL ArrowRec::GetFirstArrowPos(BOOL StartArrow,
01321 DocCoord* Coords, PathVerb* Verbs, INT32 NumCoords,
01322 INT32* Index, DocCoord* Centre, DocCoord* Direction)
01323 {
01324 *Index = 0;
01325
01326
01327 return GetNextArrowPos(StartArrow, Coords, Verbs, NumCoords, Index, Centre, Direction);
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 BOOL ArrowRec::GetNextArrowPos(BOOL StartArrow,
01347 DocCoord* Coords, PathVerb* Verbs, INT32 NumCoords,
01348 INT32* Index, DocCoord* Centre, DocCoord* Direction)
01349 {
01350 INT32 coord = *Index;
01351 INT32 StartPos = -1;
01352
01353 while (coord<NumCoords)
01354 {
01355 if (Verbs[coord] == PT_MOVETO)
01356 {
01357 if (StartPos != -1)
01358 break;
01359
01360 StartPos = coord;
01361 }
01362
01363 if (Verbs[coord] & PT_CLOSEFIGURE)
01364 {
01365 StartPos = -1;
01366 }
01367
01368 coord++;
01369 }
01370
01371 if (StartPos != -1)
01372 {
01373
01374 if (StartArrow)
01375 {
01376 *Centre = Coords[StartPos];
01377 *Direction = Coords[StartPos+1];
01378
01379
01380
01381 }
01382 else
01383 {
01384 *Centre = Coords[coord-1];
01385 *Direction = Coords[coord-2];
01386 }
01387
01388 *Index = coord;
01389
01390 return TRUE;
01391 }
01392
01393
01394 return FALSE;
01395 }
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 ANGLE ArrowRec::CalcAngle(const DocCoord& ArrowCentre, const DocCoord& Direction)
01414 {
01415 ANGLE Angle;
01416
01417
01418 const INT32 dx = Direction.x - ArrowCentre.x;
01419 const INT32 dy = Direction.y - ArrowCentre.y;
01420
01421 if ( (dy==0) && (dx==0) )
01422 {
01423 return FALSE;
01424 }
01425
01426 double LineAngle;
01427
01428 if ( (dx>=0) && (dy>=0) )
01429 LineAngle = -PI + atan2( (double)dy, (double)dx );
01430 else if ( (dx<0) && (dy>=0) )
01431 LineAngle = -atan2( (double)dy, (double)-dx );
01432 else if ( (dx<0) && (dy<0) )
01433 LineAngle = atan2( (double)-dy, (double)-dx );
01434 else if ( (dx>=0) && (dy<0) )
01435 LineAngle = PI - atan2( (double)-dy, (double)dx );
01436
01437 else
01438 {
01439 TRACE( wxT("invalid angle in CalcAngle\n") );
01440 return FALSE;
01441 }
01442
01443 Angle = 360 * (LineAngle / (2*PI));
01444
01445 return Angle;
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464 void ArrowRec::GetArrowBase(DocCoord * pPoint)
01465 {
01466 if (!pPoint)
01467 return;
01468
01469 DocRect ArrowRect = ArrowShape->GetBoundingRect();
01470
01471 switch (ArrowID)
01472 {
01473 case SA_STRAIGHTARROW:
01474 pPoint->x = -9000;
01475 pPoint->y = 0;
01476 break;
01477 case SA_ANGLEDARROW:
01478 pPoint->x = -9000;
01479 pPoint->y = 0;
01480 break;
01481 case SA_ROUNDEDARROW:
01482 pPoint->x = -9000;
01483 pPoint->y = 0;
01484 break;
01485 case SA_SPOT:
01486 pPoint->x = -30000;
01487 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01488 break;
01489 case SA_DIAMOND:
01490 pPoint->x = -54000;
01491 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01492 break;
01493 case SA_ARROWFEATHER:
01494 pPoint->x = -30000;
01495 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01496 break;
01497 case SA_ARROWFEATHER2:
01498 pPoint->x = -30000;
01499 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01500 break;
01501 case SA_HOLLOWDIAMOND:
01502 pPoint->x = -54000;
01503 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01504 break;
01505 default:
01506 pPoint->x = ArrowRect.lo.x;
01507 pPoint->y = (ArrowRect.hi.y + ArrowRect.lo.y) / 2;
01508 break;
01509 }
01510 }
01511