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 #include "cdrfiltr.h"
00105 #include "nodepath.h"
00106
00107
00108 #include "impcol.h"
00109
00110 DECLARE_SOURCE("$Revision: 1282 $");
00111
00112 #define new CAM_DEBUG_NEW
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 #define MAX_LINE_WIDTH (4*72000)
00128
00129 BOOL CDRFilter::SetLineAttr(cdrfOffsetHeader *Object)
00130 {
00131 if(Version == CDRVERSION_3)
00132 {
00133 return SetLineAttr3(Object);
00134 }
00135
00136
00137 DWORD *pReference = (DWORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_LINE);
00138
00139
00140
00141 if(pReference == 0)
00142 {
00143
00144 WORD *pStyleReference = (WORD *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_STYLE);
00145
00146 if(pStyleReference != 0)
00147 {
00148
00149 cdrfStyle *pStyle;
00150 INT32 StyleSize;
00151
00152 if((pStyle = (cdrfStyle *)Styles.Find(*pStyleReference, &StyleSize)) != 0)
00153 {
00154
00155 pReference = (DWORD *)FindDataInObject(&pStyle->Header, cdrfSTYLEOFFSETTYPE_OUTLINE);
00156 }
00157 }
00158 }
00159
00160 cdrfOutline *Out;
00161 INT32 OutSize;
00162
00163 if(pReference == 0 || (Out = (cdrfOutline *)Outlines.Find(*pReference, &OutSize)) == 0
00164 || OutSize < sizeof(cdrfOutline))
00165 {
00166
00167
00168 if(!SetLineWidth(cdrfOUTLINE_DEFAULT_WIDTH))
00169 return FALSE;
00170
00171 PColourCMYK cmyk;
00172 cmyk.Cyan = cmyk.Magenta = cmyk.Yellow = 0;
00173 cmyk.Key = 255;
00174
00175 DocColour Col;
00176 Col.SetCMYKValue(&cmyk);
00177
00178 if(!SetLineColour(Col))
00179 return FALSE;
00180
00181 return TRUE;
00182 }
00183
00184
00185 if((CDRDATA_WORD(Out->Flags) & cdrfOUTLINEFLAGS_NOOUTLINE) != 0)
00186 {
00187 if (!SetLineColour(DocColour(COLOUR_TRANS)))
00188 return FALSE;
00189
00190 return TRUE;
00191 }
00192
00193
00194 DocColour Col;
00195 ConvertColour(&Out->Colour, &Col);
00196
00197
00198 INT32 LineWidth = CDRDATA_WORD(Out->LineThickness) * CDRCOORDS_TO_MILLIPOINTS;
00199
00200 if(LineWidth > MAX_LINE_WIDTH)
00201 LineWidth = MAX_LINE_WIDTH;
00202
00203
00204 JointType JType;
00205 switch(CDRDATA_WORD(Out->JoinStyle))
00206 {
00207 case cdrfJOINSTYLE_SQUARE: JType = MitreJoin; break;
00208 case cdrfJOINSTYLE_ROUNDED: JType = RoundJoin; break;
00209 default:
00210 case cdrfJOINSTYLE_BEVEL: JType = BevelledJoin; break;
00211 }
00212
00213
00214 LineCapType CType;
00215 switch(CDRDATA_WORD(Out->EndStyle))
00216 {
00217 case cdrfENDSTYLE_BUTT: CType = LineCapButt; break;
00218 case cdrfENDSTYLE_ROUNDED: CType = LineCapRound; break;
00219 default:
00220 case cdrfENDSTYLE_SQUARE: CType = LineCapSquare; break;
00221
00222 }
00223
00224
00225 DashRec Dash;
00226 DashElement DashArray[cdrfMAX_DASH_ELEMENTS];
00227 if(CDRDATA_WORD(Out->NDashSegments) > 0 && (CDRDATA_WORD(Out->Flags) & cdrfOUTLINEFLAGS_NODASH) == 0)
00228 {
00229
00230 INT32 NSeg = CDRDATA_WORD(Out->NDashSegments);
00231 if(NSeg > cdrfMAX_DASH_ELEMENTS)
00232 NSeg = cdrfMAX_DASH_ELEMENTS;
00233
00234 INT32 l;
00235 for(l = 0; l < NSeg; l++)
00236 {
00237 DashArray[l] = CDRDATA_WORD(Out->DashSegments[l]) * LineWidth;
00238 }
00239
00240 Dash.Elements = NSeg;
00241 Dash.DashStart = 0;
00242 Dash.ElementData = DashArray;
00243
00244 Dash.LineWidth = LineWidth;
00245 Dash.ScaleWithLineWidth = TRUE;
00246 Dash.DashID = -1;
00247 }
00248 else
00249 {
00250
00251 Dash = SD_SOLID;
00252 }
00253
00254
00255 if(!SetLineWidth(LineWidth) || !SetLineColour(Col) || !SetJoinType(JType)
00256 || !SetLineCap(CType) || !SetDashPattern(Dash))
00257 return FALSE;
00258
00259
00260 if(CDRDATA_DWORD(Out->StartArrowReference) != 0 || CDRDATA_DWORD(Out->EndArrowReference) != 0)
00261 {
00262
00263
00264 if (ObjFilled == FALSE)
00265 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
00266
00267
00268 AttributeManager::ApplyBasedOnDefaults(pMadeNode, CurrentAttrs);
00269
00270
00271
00272
00273
00274 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00275
00276
00277 AttrsAlreadyApplied = TRUE;
00278
00279
00280 AddArrowheadsToPath(CDRDATA_DWORD(Out->StartArrowReference), CDRDATA_DWORD(Out->EndArrowReference),
00281 &Col, LineWidth, CType, JType);
00282 }
00283
00284 return TRUE;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301 #define MAX_LINE_WIDTH (4*72000)
00302
00303 BOOL CDRFilter::SetLineAttr3(cdrfOffsetHeader *Object)
00304 {
00305 cdrfOutlineV3 *Out = (cdrfOutlineV3 *)FindDataInObject(Object, cdrfOBJOFFSETTYPE_LINE);
00306
00307 if(Out == 0)
00308 {
00309
00310
00311 if(!SetLineWidth(cdrfOUTLINE_DEFAULT_WIDTH))
00312 return FALSE;
00313
00314 PColourCMYK cmyk;
00315 cmyk.Cyan = cmyk.Magenta = cmyk.Yellow = 0;
00316 cmyk.Key = 255;
00317
00318 DocColour Col;
00319 Col.SetCMYKValue(&cmyk);
00320
00321 if(!SetLineColour(Col))
00322 return FALSE;
00323
00324 return TRUE;
00325 }
00326
00327
00328 if((Out->Flags & cdrfOUTLINEFLAGSV3_STROKED) == 0)
00329 {
00330 if (!SetLineColour(DocColour(COLOUR_TRANS)))
00331 return FALSE;
00332
00333 return TRUE;
00334 }
00335
00336
00337 DocColour Col;
00338 ConvertColour((cdrfColour *)&Out->Colour, &Col);
00339
00340
00341 INT32 LineWidth = CDRDATA_WORD(Out->LineThickness) * CDRCOORDS_TO_MILLIPOINTS;
00342
00343 if(LineWidth > MAX_LINE_WIDTH)
00344 LineWidth = MAX_LINE_WIDTH;
00345
00346
00347 JointType JType;
00348 switch(CDRDATA_WORD(Out->JoinStyle))
00349 {
00350 case cdrfJOINSTYLE_SQUARE: JType = MitreJoin; break;
00351 case cdrfJOINSTYLE_ROUNDED: JType = RoundJoin; break;
00352 default:
00353 case cdrfJOINSTYLE_BEVEL: JType = BevelledJoin; break;
00354 }
00355
00356
00357 LineCapType CType;
00358 switch(Out->EndStyle)
00359 {
00360 case cdrfENDSTYLE_BUTT: CType = LineCapButt; break;
00361 case cdrfENDSTYLE_ROUNDED: CType = LineCapRound; break;
00362 default:
00363 case cdrfENDSTYLE_SQUARE: CType = LineCapSquare; break;
00364
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 if(!SetLineWidth(LineWidth) || !SetLineColour(Col) || !SetJoinType(JType)
00399 || !SetLineCap(CType))
00400 return FALSE;
00401
00402
00403 if(CDRDATA_DWORD(Out->StartArrowReference) != 0 || CDRDATA_DWORD(Out->EndArrowReference) != 0)
00404 {
00405
00406
00407 if (ObjFilled == FALSE)
00408 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = TRUE;
00409
00410
00411 AttributeManager::ApplyBasedOnDefaults(pMadeNode, CurrentAttrs);
00412
00413
00414 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00415
00416
00417 AttrsAlreadyApplied = TRUE;
00418
00419
00420 AddArrowheadsToPath(CDRDATA_DWORD(Out->StartArrowReference), CDRDATA_DWORD(Out->EndArrowReference),
00421 &Col, LineWidth, CType, JType);
00422 }
00423
00424 return TRUE;
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 BOOL CDRFilter::AddAttributesToArrowheadNode(NodeRenderableBounded *N, DocColour *Col, INT32 LineWidth,
00443 LineCapType Cap, JointType Join)
00444 {
00445 if(IS_A(N, NodeGroup))
00446 {
00447
00448 Node *pNode;
00449
00450 pNode = N->FindFirstChild();
00451
00452 while(pNode != 0)
00453 {
00454 if(IS_A(pNode, NodePath))
00455 AddAttributesToArrowheadPath((NodePath *)pNode, Col, LineWidth, Cap, Join);
00456
00457 pNode = pNode->FindNext();
00458 }
00459 } else if(IS_A(N, NodePath))
00460 {
00461
00462 AddAttributesToArrowheadPath((NodePath *)N, Col, LineWidth, Cap, Join);
00463 } else {
00464 ERROR3("Something unexpected passed to AddAttributesToArrowheadNode");
00465 }
00466
00467 return TRUE;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 BOOL CDRFilter::AddAttributesToArrowheadPath(NodePath *P, DocColour *Col, INT32 LineWidth,
00486 LineCapType Cap, JointType Join)
00487 {
00488 if(P->InkPath.IsFilled)
00489 {
00490
00491
00492 SetPathFilled(TRUE);
00493 if(!SetLineColour(DocColour(COLOUR_TRANS)) || !SetFillColour(*Col))
00494 return FALSE;
00495 } else {
00496
00497 if(!SetLineColour(*Col) || !SetLineWidth(LineWidth) || !SetLineCap(Cap) || !SetJoinType(Join))
00498 return FALSE;
00499 }
00500
00501
00502
00503
00504
00505
00506 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00507
00508
00509 BOOL Result = AttributeManager::ApplyBasedOnDefaults(P, CurrentAttrs);
00510
00511
00512
00513
00514
00515 CurrentAttrs[ATTR_FILLGEOMETRY].Ignore = FALSE;
00516
00517 return Result;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 BOOL CDRFilter::DoesPathNeedArrowheads(NodePath *P)
00534 {
00535
00536 if(P->InkPath.GetNumEndPoints() > 0)
00537 return TRUE;
00538
00539 return FALSE;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 BOOL CDRFilter::TransformArrowhead(NodeRenderableBounded *N, DocCoord *Point, DocCoord *Other, BOOL Start,
00560 INT32 LineWidth, INT32 Distance)
00561 {
00562
00563 double Scale = (double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH;
00564
00565
00566 double Adj = (double)Point->x - (double)Other->x;
00567 double Opp = (double)Point->y - (double)Other->y;
00568
00569
00570 double Hyp = sqrt((Adj * Adj) + (Opp * Opp));
00571
00572
00573 double Move = Scale * (double)Distance;
00574
00575
00576 double a, b, c, d, e, f;
00577 if(Hyp == 0)
00578 {
00579
00580 a = Scale;
00581 b = 0;
00582 c = 0;
00583 d = Scale;
00584 e = Point->x + Move;
00585 f = Point->y;
00586 } else {
00587 double cosTheta = (Adj / Hyp);
00588 double sinTheta = (Opp / Hyp);
00589
00590 a = Scale * cosTheta;
00591 b = Scale * sinTheta;
00592 c = 0 - (Scale * sinTheta);
00593 d = Scale * cosTheta;
00594 e = Point->x + (Move * cosTheta);
00595 f = Point->y + (Move * sinTheta);
00596 }
00597
00598
00599 Matrix M = Matrix(a, b, c, d, (INT32)e, (INT32)f);
00600
00601
00602 if(Start)
00603 {
00604 Matrix F = Matrix(1, 0, 0, -1, 0, 0);
00605
00606 M = F * M;
00607 }
00608
00609
00610 Trans2DMatrix Trans(M);
00611
00612 N->Transform(Trans);
00613
00614 return TRUE;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 BOOL CDRFilter::AddArrowheadsToPath(DWORD StartArrow, DWORD EndArrow, DocColour *Col, INT32 LineWidth,
00633 LineCapType Cap, JointType Join)
00634 {
00635 if(!IS_A(pMadeNode, NodePath))
00636 return TRUE;
00637
00638 NodePath *pPath = (NodePath *)pMadeNode;
00639
00640
00641 if(!DoesPathNeedArrowheads(pPath) || (StartArrow == 0 && EndArrow == 0))
00642 return TRUE;
00643
00644
00645 NodeRenderableBounded *StartA = 0;
00646 NodeRenderableBounded *EndA = 0;
00647 INT32 StartDistance;
00648 INT32 EndDistance;
00649 if(StartArrow != 0)
00650 {
00651 BOOL NotPresent;
00652 StartA = Arrowheads.GetConvertedNode(StartArrow, &StartDistance, &NotPresent);
00653
00654 if(StartA == 0 && NotPresent == FALSE)
00655 return FALSE;
00656 }
00657 if(EndArrow != 0)
00658 {
00659 BOOL NotPresent;
00660 EndA = Arrowheads.GetConvertedNode(EndArrow, &EndDistance, &NotPresent);
00661
00662 if(EndA == 0 && NotPresent == FALSE)
00663 return FALSE;
00664 }
00665
00666
00667 if(StartA == 0 && EndA == 0)
00668 return TRUE;
00669
00670
00671 DashRec NoDash;
00672 NoDash = SD_SOLID;
00673 SetDashPattern(NoDash);
00674
00675
00676 DocCoord *Coords = pPath->InkPath.GetCoordArray();
00677 PathVerb *Verbs = pPath->InkPath.GetVerbArray();
00678 INT32 NCoords = pPath->InkPath.GetNumCoords();
00679 INT32 SubPathStart = -1;
00680 INT32 SubPathEnd = -1;
00681
00682
00683
00684
00685 NodeRenderableBounded *ThisNode = pPath;
00686
00687
00688 double StartTrimDistance;
00689 double EndTrimDistance;
00690 if(StartA != 0)
00691 StartTrimDistance = ((double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH) * (double)StartDistance;
00692 if(EndA != 0)
00693 EndTrimDistance = ((double)LineWidth / (double)cdrfARROWHEAD_LINEWIDTH) * (double)EndDistance;
00694
00695
00696 INT32 c;
00697 for(c = 0; c < NCoords; c++)
00698 {
00699 UINT32 Verb = Verbs[c] & ~PT_CLOSEFIGURE;
00700 BOOL CloseHere = ((Verbs[c] & PT_CLOSEFIGURE) != 0)?TRUE:FALSE;
00701
00702
00703
00704 if(CloseHere)
00705 SubPathStart = -1;
00706
00707
00708
00709 if((Verb == PT_MOVETO || ((c == (NCoords - 1)) && !CloseHere)) && c != 0)
00710 {
00711
00712 if(Verb == PT_MOVETO)
00713 {
00714
00715 SubPathEnd = c - 1;
00716 } else {
00717
00718 SubPathEnd = c;
00719 }
00720 }
00721
00722
00723
00724 if(SubPathStart != -1 && SubPathEnd != -1)
00725 {
00726
00727 if(StartA != 0)
00728 {
00729
00730 if((Verbs[SubPathStart + 1] & ~PT_CLOSEFIGURE) == PT_LINETO)
00731 {
00732 double dx, dy;
00733 dx = Coords[SubPathStart + 1].x - Coords[SubPathStart].x;
00734 dy = Coords[SubPathStart + 1].y - Coords[SubPathStart].y;
00735 double len = sqrt((dx * dx) + (dy * dy));
00736
00737 if((len - StartTrimDistance) >= 32.0)
00738 {
00739 double factor = StartTrimDistance / len;
00740 dx *= factor;
00741 Coords[SubPathStart].x += (INT32)dx;
00742 dy *= factor;
00743 Coords[SubPathStart].y += (INT32)dy;
00744 }
00745 }
00746
00747
00748
00749
00750 if(!StartA->CopyNode(ThisNode, NEXT))
00751 return FALSE;
00752
00753 ThisNode = (NodeRenderableBounded *)ThisNode->FindNext();
00754 ERROR3IF(ThisNode == 0, "CopyNode returned a zero path but didn't complain");
00755 ERROR3IF(ThisNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)) == FALSE, "copied thing isn't a renderable bounded node");
00756
00757
00758 if(!TransformArrowhead(ThisNode, &Coords[SubPathStart], &Coords[SubPathStart + 1],
00759 TRUE, LineWidth, StartDistance))
00760 return FALSE;
00761
00762
00763 if(!AddAttributesToArrowheadNode(ThisNode, Col, LineWidth, Cap, Join))
00764 return FALSE;
00765 }
00766
00767
00768 if(EndA != 0)
00769 {
00770 if((Verbs[SubPathEnd] & ~PT_CLOSEFIGURE) == PT_LINETO)
00771 {
00772 double dx, dy;
00773 dx = Coords[SubPathEnd].x - Coords[SubPathEnd - 1].x;
00774 dy = Coords[SubPathEnd].y - Coords[SubPathEnd - 1].y;
00775 double len = sqrt((dx * dx) + (dy * dy));
00776
00777 if((len - EndTrimDistance) >= 32.0)
00778 {
00779 double factor = EndTrimDistance / len;
00780 dx *= factor;
00781 Coords[SubPathEnd].x += (INT32)dx;
00782 dy *= factor;
00783 Coords[SubPathEnd].y += (INT32)dy;
00784 }
00785 }
00786
00787
00788
00789
00790 if(!EndA->CopyNode(ThisNode, NEXT))
00791 return FALSE;
00792
00793 ThisNode = (NodeRenderableBounded *)ThisNode->FindNext();
00794 ERROR3IF(ThisNode == 0, "CopyNode returned a zero path but didn't complain");
00795 ERROR3IF(ThisNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)) == FALSE, "copied thing isn't a renderable bounded node");
00796
00797
00798 if(!TransformArrowhead(ThisNode, &Coords[SubPathEnd], &Coords[SubPathEnd - 1],
00799 FALSE, LineWidth, EndDistance))
00800 return FALSE;
00801
00802
00803 if(!AddAttributesToArrowheadNode(ThisNode, Col, LineWidth, Cap, Join))
00804 return FALSE;
00805 }
00806
00807 }
00808
00809
00810 if(Verb == PT_MOVETO)
00811 {
00812 SubPathStart = c;
00813 SubPathEnd = -1;
00814 }
00815 }
00816
00817
00818
00819 pPath->InvalidateBoundingRect();
00820
00821
00822 NodeGroup *pGroup = new NodeGroup;
00823 if(pGroup == 0)
00824 return FALSE;
00825
00826
00827 pMadeNode->InsertChainSimple(pGroup, FIRSTCHILD);
00828
00829
00830 pMadeNode = pGroup;
00831
00832 return TRUE;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 BOOL CDRArrowheadStore::AddChunkToStore(RIFFFile *RIFF)
00850 {
00851 if(RIFF->GetObjType() != RIFFOBJECTTYPE_CHUNK)
00852 {
00853 ERROR2(FALSE, "CDRAttributeStore::AddChunkToStore called without a chunk in the RIFFFile");
00854 }
00855
00856
00857 CDRArrowheadStoredItem *Item = new CDRArrowheadStoredItem;
00858
00859 if(Item == 0)
00860 return FALSE;
00861
00862
00863 if(!Item->Aquire(RIFF))
00864 {
00865 delete Item;
00866 return FALSE;
00867 }
00868
00869 Item->Size = RIFF->GetObjSize();
00870
00871
00872 AddTail(Item);
00873
00874 return TRUE;
00875 }
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 #define GCN_LASTSUB_NONE 0
00894 #define GCN_LASTSUB_CLOSED 1
00895 #define GCN_LASTSUB_OPEN 2
00896
00897 NodeRenderableBounded *CDRArrowheadStore::GetConvertedNode(DWORD Reference, INT32 *Distance, BOOL *NotPresent)
00898 {
00899
00900 *NotPresent = FALSE;
00901
00902
00903 CDRArrowheadStoredItem *Item;
00904 INT32 Size;
00905
00906 if(IsEmpty())
00907 return 0;
00908
00909 Item = (CDRArrowheadStoredItem *)GetHead();
00910
00911
00912 while(Item != 0)
00913 {
00914 if(CDRDATA_DWORD(*((DWORD *)(Item->Block))) == Reference)
00915 {
00916 Size = Item->Size;
00917 break;
00918 }
00919
00920 Item = (CDRArrowheadStoredItem *)GetNext(Item);
00921 }
00922
00923
00924 if(Item == 0)
00925 {
00926 *NotPresent = TRUE;
00927 return 0;
00928 }
00929
00930
00931 cdrfArrowhead *Arrow = (cdrfArrowhead *)Item->Block;
00932 cdrfCoord *Coords = (cdrfCoord *)(Item->Block + CDRDATA_WORD(Arrow->CoordsOffset) + cdrfARROWHEAD_COORDOFF_CORRECT);
00933
00934
00935 *Distance = CDRDATA_SWORD(Arrow->Distance);
00936
00937
00938 if(Item->pNode != 0)
00939 return Item->pNode;
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 INT32 ThisType = GCN_LASTSUB_NONE;
00950 INT32 LastType = GCN_LASTSUB_NONE;
00951
00952 NodePath *FirstPath = 0;
00953 NodePath *LastPath = 0;
00954 NodePath *ThisPath = 0;
00955
00956
00957 if((Arrow->NodeTypes[0] & cdrfPATHCOORDTYPE_MASK) != cdrfPATHCOORDTYPE_MOVE)
00958 {
00959
00960 *NotPresent = TRUE;
00961 return 0;
00962 }
00963
00964 INT32 CoordType;
00965
00966 INT32 l;
00967
00968 UINT32 Control1 = 0;
00969 UINT32 Control2 = 0;
00970 DocCoord co, cn1, cn2;
00971 PathFlags Flags;
00972
00973 INT32 NNodes = CDRDATA_WORD(Arrow->NNodes);
00974 BOOL NeedMoveTo = TRUE;
00975
00976
00977 for(l = 0; l < NNodes; l++)
00978 {
00979 CoordType = Arrow->NodeTypes[l] & cdrfPATHCOORDTYPE_MASK;
00980
00981 if(CoordType == cdrfPATHCOORDTYPE_MOVE || l == 0)
00982 {
00983
00984 LastType = ThisType;
00985
00986
00987 if((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_CLOSE) != 0)
00988 ThisType = GCN_LASTSUB_CLOSED;
00989 else
00990 ThisType = GCN_LASTSUB_OPEN;
00991
00992
00993 if(ThisType != LastType)
00994 {
00995
00996 if(ThisPath != 0)
00997 {
00998
00999 if(!ThisPath->InkPath.EnsureValid())
01000 {
01001
01002 delete ThisPath;
01003 ThisPath = 0;
01004 } else {
01005
01006 ThisPath->InvalidateBoundingRect();
01007
01008 if(FirstPath == 0)
01009 FirstPath = ThisPath;
01010
01011 if(LastPath != 0)
01012 ThisPath->AttachNode(LastPath, NEXT);
01013
01014 LastPath = ThisPath;
01015
01016 ThisPath = 0;
01017 }
01018 }
01019
01020
01021 ThisPath = new NodePath;
01022
01023 if(ThisPath == 0)
01024 return 0;
01025
01026
01027 if(!ThisPath->SetUpPath())
01028 return 0;
01029
01030 ThisPath->InkPath.FindStartOfPath();
01031
01032
01033 if(ThisType == GCN_LASTSUB_CLOSED)
01034 {
01035 ThisPath->InkPath.IsFilled = TRUE;
01036 ThisPath->InkPath.IsStroked = FALSE;
01037 } else {
01038 ThisPath->InkPath.IsFilled = FALSE;
01039 ThisPath->InkPath.IsStroked = TRUE;
01040 }
01041
01042 }
01043
01044 }
01045
01046 co.x = CDRDATA_SWORD(Coords[l].X);
01047 co.y = CDRDATA_SWORD(Coords[l].Y);
01048
01049
01050 if(NeedMoveTo && CoordType != cdrfPATHCOORDTYPE_MOVE)
01051 {
01052 if(!ThisPath->InkPath.InsertMoveTo(co))
01053 return 0;
01054 }
01055
01056 NeedMoveTo = FALSE;
01057
01058
01059 switch(CoordType)
01060 {
01061 case cdrfPATHCOORDTYPE_MOVE:
01062
01063 if(!ThisPath->InkPath.InsertMoveTo(co))
01064 return 0;
01065 break;
01066
01067 case cdrfPATHCOORDTYPE_LINETO:
01068
01069 if(!ThisPath->InkPath.InsertLineTo(co))
01070 return 0;
01071 break;
01072
01073 case cdrfPATHCOORDTYPE_CURVE:
01074
01075
01076 if(Control1 == 0 || Control2 == 0)
01077 {
01078 TRACEUSER( "Ben", _T("No control points for curve element\n"));
01079 return 0;
01080 }
01081
01082
01083 cn1.x = CDRDATA_SWORD(Coords[Control1].X);
01084 cn1.y = CDRDATA_SWORD(Coords[Control1].Y);
01085 cn2.x = CDRDATA_SWORD(Coords[Control2].X);
01086 cn2.y = CDRDATA_SWORD(Coords[Control2].Y);
01087
01088
01089 Flags.IsSelected = FALSE;
01090 Flags.IsSmooth = Flags.IsRotate = ((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_SMOOTH) != 0)?TRUE:FALSE;
01091 Flags.IsEndPoint;
01092
01093
01094 if(!ThisPath->InkPath.InsertCurveTo(cn1, cn2, co, &Flags))
01095 return 0;
01096 break;
01097
01098 case cdrfPATHCOORDTYPE_CONTROL:
01099
01100 Control1 = Control2;
01101 Control2 = l;
01102 break;
01103
01104 default:
01105 break;
01106 }
01107
01108
01109 if((Arrow->NodeTypes[l] & cdrfPATHCOORDATTR_CLOSE) != 0)
01110 {
01111
01112 if(CoordType != cdrfPATHCOORDTYPE_MOVE)
01113 {
01114 if(!ThisPath->InkPath.CloseSubPath())
01115 return 0;
01116
01117
01118 NeedMoveTo = TRUE;
01119 }
01120 }
01121 }
01122
01123
01124 ThisPath->InvalidateBoundingRect();
01125
01126
01127 if(ThisPath != 0)
01128 {
01129 if(FirstPath == 0)
01130 FirstPath = ThisPath;
01131
01132 if(LastPath != 0)
01133 ThisPath->AttachNode(LastPath, NEXT);
01134
01135 LastPath = ThisPath;
01136
01137 ThisPath = 0;
01138 }
01139
01140
01141 NodeRenderableBounded *ToInsert = 0;
01142 if(FirstPath == LastPath)
01143 {
01144 ToInsert = FirstPath;
01145 } else {
01146 ToInsert = new NodeGroup;
01147
01148 if(ToInsert == 0)
01149 return 0;
01150
01151 FirstPath->InsertChainSimple(ToInsert, FIRSTCHILD);
01152 }
01153
01154 Item->pNode = ToInsert;
01155
01156 return ToInsert;
01157 }
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 CDRArrowheadStoredItem::CDRArrowheadStoredItem(void)
01173 {
01174 pNode = 0;
01175 }
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 CDRArrowheadStoredItem::~CDRArrowheadStoredItem(void)
01192 {
01193 if(pNode != 0)
01194 pNode->CascadeDelete();
01195
01196 delete pNode;
01197 }
01198
01199
01200
01201
01202 typedef struct {
01203 BYTE C, M, Y, K;
01204 TCHAR *Name;
01205 } StandardCDRColour;
01206
01207 static StandardCDRColour StandardCDRColours[] = {
01208 {0, 0, 0, 100, "Black"},
01209 {0, 0, 0, 90, "90% Black"},
01210 {0, 0, 0, 80, "80% Black"},
01211 {0, 0, 0, 70, "70% Black"},
01212 {0, 0, 0, 60, "60% Black"},
01213 {0, 0, 0, 50, "50% Black"},
01214 {0, 0, 0, 40, "40% Black"},
01215 {0, 0, 0, 30, "30% Black"},
01216 {0, 0, 0, 20, "20% Black"},
01217 {0, 0, 0, 10, "10% Black"},
01218 {0, 0, 0, 0, "White"},
01219 {100, 100, 0, 0, "Blue"},
01220 {100, 0, 0, 0, "Cyan"},
01221 {100, 0, 100, 0, "Green"},
01222 {0, 0, 100, 0, "Yellow"},
01223 {0, 100, 100, 0, "Red"},
01224 {0, 100, 0, 0, "Magenta"},
01225 {20, 80, 0, 20, "Purple"},
01226 {0, 60, 100, 0, "Orange"},
01227 {0, 40, 20, 0, "Pink"},
01228 {0, 20, 20, 60, "Dark Brown"},
01229 {20, 20, 0, 0, "Powder Blue"},
01230 {40, 40, 0, 0, "Pastel Blue"},
01231 {60, 40, 0, 0, "Baby Blue"},
01232 {60, 60, 0, 0, "Electric Blue"},
01233 {40, 40, 0, 20, "Twilight Blue"},
01234 {60, 40, 0, 40, "Navy Blue"},
01235 {40, 40, 0, 60, "Deep Navy Blue"},
01236 {40, 20, 0, 40, "Desert Blue"},
01237 {100, 20, 0, 0, "Sky Blue"},
01238 {40, 0, 0, 0, "Ice Blue"},
01239 {20, 0, 0, 20, "Light BlueGreen"},
01240 {20, 0, 0, 40, "Ocean Green"},
01241 {20, 0, 0, 60, "Moss Green"},
01242 {20, 0, 0, 80, "Dark Green"},
01243 {40, 0, 20, 60, "Forest Green"},
01244 {60, 0, 40, 40, "Grass Green"},
01245 {40, 0, 20, 40, "Kentucky Green"},
01246 {60, 0, 40, 20, "Light Green"},
01247 {60, 0, 60, 20, "Spring Green"},
01248 {60, 0, 20, 0, "Turquoise"},
01249 {60, 0, 20, 20, "Sea Green"},
01250 {20, 0, 20, 20, "Faded Green"},
01251 {20, 0, 20, 0, "Ghost Green"},
01252 {40, 0, 40, 0, "Mint Green"},
01253 {20, 0, 20, 40, "Army Green"},
01254 {20, 0, 40, 40, "Avocado Green"},
01255 {20, 0, 60, 20, "Martian Green"},
01256 {20, 0, 40, 20, "Dull Green"},
01257 {40, 0, 100, 0, "Chartreuse"},
01258 {20, 0, 60, 0, "Moon Green"},
01259 {0, 0, 20, 80, "Murky Green"},
01260 {0, 0, 20, 60, "Olive Drab"},
01261 {0, 0, 20, 40, "Khaki"},
01262 {0, 0, 40, 40, "Olive"},
01263 {0, 0, 60, 20, "Banana Yellow"},
01264 {0, 0, 60, 0, "Light Yellow"},
01265 {0, 0, 40, 0, "Chalk"},
01266 {0, 0, 20, 0, "Pale Yellow"},
01267 {0, 20, 40, 40, "Brown"},
01268 {0, 40, 60, 20, "Red Brown"},
01269 {0, 20, 60, 20, "Gold"},
01270 {0, 60, 80, 0, "Autumn Orange"},
01271 {0, 40, 80, 0, "Light Orange"},
01272 {0, 40, 60, 0, "Peach"},
01273 {0, 20, 100, 0, "Deep Yellow"},
01274 {0, 20, 40, 0, "Sand"},
01275 {0, 20, 40, 60, "Walnut"},
01276 {0, 60, 60, 40, "Ruby Red"},
01277 {0, 60, 80, 20, "Brick Red"},
01278 {0, 60, 60, 0, "Tropical Pink"},
01279 {0, 40, 40, 0, "Soft Pink"},
01280 {0, 20, 20, 0, "Faded Pink"},
01281 {0, 40, 20, 40, "Crimson"},
01282 {0, 60, 40, 20, "Regal Red"},
01283 {0, 60, 20, 20, "Deep Rose"},
01284 {0, 100, 60, 0, "Neon Red"},
01285 {0, 60, 40, 0, "Deep Pink"},
01286 {0, 80, 40, 0, "Hot Pink"},
01287 {0, 40, 20, 20, "Dusty Rose"},
01288 {0, 40, 0, 60, "Plum"},
01289 {0, 60, 0, 40, "Deep Violet"},
01290 {0, 40, 0, 0, "Light Violet"},
01291 {0, 40, 0, 20, "Violet"},
01292 {0, 20, 0, 40, "Dusty Plum"},
01293 {0, 20, 0, 20, "Pale Purple"},
01294 {20, 60, 0, 20, "Majestic Purple"},
01295 {20, 80, 0, 0, "Neon Purple"},
01296 {20, 60, 0, 0, "Light Purple"},
01297 {20, 40, 0, 20, "Twilight Violet"},
01298 {20, 40, 0, 0, "Easter Purple"},
01299 {20, 40, 0, 60, "Deep Purple"},
01300 {20, 40, 0, 40, "Grape"},
01301 {40, 60, 0, 0, "Blue Violet"},
01302 {40, 100, 0, 0, "Blue Purple"},
01303 {40, 80, 0, 20, "Deep River"},
01304 {60, 80, 0, 0, "Deep Azure"},
01305 {40, 60, 0, 40, "Storm Blue"},
01306 {60, 80, 0, 20, "Deep Blue"},
01307 {100, 100, 100, 100, "100C100M100Y100K"}
01308 };
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 BOOL CDRFilter::AddStandardColourSet(Document *pDocument)
01323 {
01324 ColourListComponent *pColours = 0;
01325
01326 DocComponent *pComponent = pDocument->EnumerateDocComponents(NULL);
01327
01328 while (pComponent != NULL)
01329 {
01330
01331 if (pComponent->GetRuntimeClass() == CC_RUNTIME_CLASS(ColourListComponent))
01332 {
01333 pColours = (ColourListComponent *) pComponent;
01334 break;
01335 }
01336
01337
01338 pComponent = pDocument->EnumerateDocComponents(pComponent);
01339 }
01340
01341 if(pColours == 0)
01342 return TRUE;
01343
01344
01345 ImportedColours *pNewColours = new ImportedColours(pColours, FALSE);
01346 if(pNewColours == 0 || !pNewColours->Init())
01347 return FALSE;
01348
01349 BOOL ok = TRUE;
01350
01351
01352 ColourCMYK NewColour;
01353 for(INT32 l = 0; l < (sizeof(StandardCDRColours) / sizeof(StandardCDRColour)); l++)
01354 {
01355 NewColour.Cyan = ((double)StandardCDRColours[l].C) / 100;
01356 NewColour.Magenta = ((double)StandardCDRColours[l].M) / 100;
01357 NewColour.Yellow = ((double)StandardCDRColours[l].Y) / 100;
01358 NewColour.Key = ((double)StandardCDRColours[l].K) / 100;
01359
01360 String_64 ColNameS(StandardCDRColours[l].Name);
01361 if(!pNewColours->AddColour(&ColNameS, &NewColour))
01362 {
01363 ok = FALSE;
01364 break;
01365 }
01366 }
01367
01368
01369 if(ok)
01370 {
01371 pNewColours->AddColoursToDocument();
01372 }
01373 else
01374 {
01375 pNewColours->DestroyColours();
01376 }
01377
01378
01379 delete pNewColours;
01380
01381 return ok;
01382 }
01383