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 #include "camtypes.h"
00101 #include "cmxexdc.h"
00102 #include "cmxrendr.h"
00103 #include "cmxform.h"
00104
00105
00106
00107 #include "colcontx.h"
00108
00109
00110 #include "fillramp.h"
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 BOOL CMXExportDC::WriteBlankAttributes(INT32 Tag)
00127 {
00128
00129 if(Tag != -1)
00130 if(!StartTag(Tag))
00131 return FALSE;
00132
00133
00134 WriteByte(0);
00135
00136
00137 if(Tag != -1)
00138 if(!EndTag())
00139 return FALSE;
00140
00141 return TRUE;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 BOOL CMXExportDC::WriteAttributes(CMXRenderRegion *pReg, INT32 Tag, DocCoord *Coords, INT32 NumCoords, BOOL ForceNoFill)
00159 {
00160
00161 BOOL WasLens = FALSE;
00162 if(!WriteAttrCheckLens(pReg, Tag, Coords, NumCoords, &WasLens))
00163 return FALSE;
00164
00165
00166 if(WasLens)
00167 return TRUE;
00168
00169
00170 if(Tag != -1)
00171 if(!StartTag(Tag))
00172 return FALSE;
00173
00174
00175 WriteByte((ForceNoFill?0:cmxRENDATTRMASK_FILL) | cmxRENDATTRMASK_OUTLINE);
00176
00177
00178 if(!ForceNoFill)
00179 if(!WriteFillSpec(pReg, Coords, NumCoords, ForceNoFill))
00180 return FALSE;
00181
00182
00183 if(!WriteOutlineSpec(pReg))
00184 return FALSE;
00185
00186
00187 if(Tag != -1)
00188 if(!EndTag())
00189 return FALSE;
00190
00191 return TRUE;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 BOOL CMXExportDC::WriteFillType(WORD FillID)
00208 {
00209 ExportFile->write(&FillID, sizeof(FillID));
00210
00211 return TRUE;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 BOOL CMXExportDC::WriteFillSpec(CMXRenderRegion *pReg, DocCoord *Coords, INT32 NumCoords, BOOL NoFill)
00228 {
00229
00230 if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec))
00231 return FALSE;
00232
00233 if(NoFill)
00234 {
00235 if(!WriteFillType(cmxFILLID_NONE))
00236 return FALSE;
00237 }
00238 else
00239 {
00240
00241 FillGeometryAttribute *pFillGeometry
00242 = (FillGeometryAttribute *)pReg->GetCurrentAttribute(ATTR_FILLGEOMETRY);
00243
00244
00245 ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
00246 ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
00247
00248
00249 if(pFillGeometry->IsAFlatFill())
00250 {
00251
00252 DocColour *pCol = pFillGeometry->GetStartColour();
00253 ERROR2IF(pCol == NULL, FALSE, "not one of your earth colours");
00254 if(pCol->IsTransparent())
00255 {
00256
00257 if(!WriteFillType(cmxFILLID_NONE))
00258 return FALSE;
00259 }
00260 else
00261 {
00262
00263 if(!WriteFillType(cmxFILLID_UNIFORM)
00264 || !WriteFillSpecFlat(pReg, pFillGeometry))
00265 return FALSE;
00266 }
00267 }
00268 else if(pFillGeometry->IsAKindOfBitmapFill())
00269 {
00270
00271 if(!WriteFillType(9)
00272 || !WriteFillSpecBitmap(pReg, pFillGeometry, Coords, NumCoords))
00273 return FALSE;
00274 }
00275 else if(pFillGeometry->IsAGradFill())
00276 {
00277
00278 if(!WriteFillType(cmxFILLID_FOUNTAIN)
00279 || !WriteFillSpecGrad(pReg, pFillGeometry, Coords, NumCoords))
00280 return FALSE;
00281 }
00282 else
00283 {
00284
00285 if(!WriteFillType(cmxFILLID_NONE))
00286 return FALSE;
00287 }
00288 }
00289
00290
00291 if(!EndNestedTag())
00292 return FALSE;
00293
00294
00295 if(!WriteMinEndTag())
00296 return FALSE;
00297
00298 return TRUE;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 BOOL CMXExportDC::WriteFillSpecFlat(CMXRenderRegion *pReg, FillGeometryAttribute *pFill)
00314 {
00315
00316 DocColour *pFillColour = pFill->GetStartColour();
00317 ERROR2IF(pFillColour == NULL, FALSE, "Wibble. No fill colour on this here flat fill");
00318
00319
00320 WORD FillReference = GetColourReference(pFillColour);
00321
00322
00323 struct {
00324 WORD FillReference;
00325 WORD ScreenReference;
00326 } filldef = {FillReference, cmxSCREENREFERENCE};
00327
00328 if(!WriteNestedTag(cmxTAG_RenderAttr_FillSpec_Uniform, &filldef, sizeof(filldef))
00329 || !WriteMinEndTag())
00330 return FALSE;
00331
00332 return TRUE;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 BOOL CMXExportDC::WriteFillSpecGrad ( CMXRenderRegion *pReg,
00352 FillGeometryAttribute *pFill,
00353 DocCoord *Coords,
00354 INT32 NumCoords )
00355 {
00356 DocColour StartColour;
00357 DocColour EndColour;
00358 DocColour MidColour;
00359 BOOL Radial = FALSE;
00360 BOOL FourColour = FALSE;
00361
00362
00363 if ( pFill->IsARadialFill () )
00364 {
00365
00366
00367 StartColour = *( pFill->GetEndColour () );
00368 EndColour = *( pFill->GetStartColour () );
00369
00370 Radial = TRUE;
00371 }
00372 else if ( pFill->IsAConicalFill () || pFill->IsASquareFill () )
00373 {
00374
00375 StartColour = *( pFill->GetStartColour () );
00376 EndColour = *( pFill->GetEndColour () );
00377
00378 Radial = TRUE;
00379 }
00380 else if ( pFill->IsAFourColFill () )
00381 {
00382
00383
00384 StartColour = *( pFill->GetStartColour () );
00385 EndColour = *( pFill->GetEndColour3 () );
00386 MidColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2 (), 0.5f, NULL, FALSE, NULL );
00387
00388
00389 FourColour = TRUE;
00390 }
00391 else if ( pFill->IsAThreeColFill () )
00392 {
00393
00394
00395 StartColour = *( pFill->GetStartColour () );
00396 EndColour.Mix ( pFill->GetEndColour (), pFill->GetEndColour2 (), 0.5f, NULL, FALSE, NULL );
00397 }
00398 else
00399 {
00400
00401 StartColour = *( pFill->GetStartColour () );
00402 EndColour = *( pFill->GetEndColour () );
00403 }
00404
00405
00406 WORD StartColReference = GetColourReference ( &StartColour );
00407 WORD EndColReference = GetColourReference ( &EndColour );
00408 WORD MidColReference = 0;
00409 WORD FillMode = cmxFILLMODE_RGB;
00410
00411
00412
00413 if ( FourColour )
00414 {
00415 MidColReference = GetColourReference ( &MidColour );
00416 }
00417
00418
00419 FillEffectAttribute *pFillEff =
00420 (FillEffectAttribute *)pReg->GetCurrentAttribute(ATTR_FILLEFFECT);
00421 ERROR2IF(pFillEff == NULL || !pFillEff->IsKindOf(CC_RUNTIME_CLASS(FillEffectAttribute)), FALSE, "not a fill effect");
00422 BOOL Rainbow = FALSE, Alt = FALSE;
00423 if(IS_A(pFillEff, FillEffectRainbowAttribute))
00424 Rainbow = TRUE;
00425 if(IS_A(pFillEff, FillEffectAltRainbowAttribute))
00426 Rainbow = Alt = TRUE;
00427
00428 if(Rainbow)
00429 {
00430
00431
00432 ColourContext *Conv = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT);
00433
00434 ColourHSVT StartC;
00435 ColourHSVT EndC;
00436
00437 Conv->ConvertColour( &StartColour, (ColourGeneric *)&StartC);
00438 Conv->ConvertColour( &EndColour, (ColourGeneric *)&EndC);
00439
00440
00441 double Difference = (EndC.Hue.MakeDouble()) - (StartC.Hue.MakeDouble());
00442
00443 BOOL ClockWise = (Difference < 0);
00444
00445 if(fabs(Difference) >= 0.5)
00446 ClockWise = !ClockWise;
00447
00448 if(Alt = TRUE)
00449 ClockWise = !ClockWise;
00450
00451
00452 if(ClockWise)
00453 FillMode = cmxFILLMODE_HSB_CW;
00454 else
00455 FillMode = cmxFILLMODE_HSB_CCW;
00456 }
00457
00458
00459 DocCoord StartPoint = *( pFill->GetStartPoint() );
00460 DocCoord EndPoint;
00461
00462
00463 if ( pFill->IsAFourColFill () )
00464 {
00465
00466 EndPoint = *( pFill->GetEndPoint3 () );
00467 }
00468 else if ( pFill->IsAThreeColFill () )
00469 {
00470
00471 EndPoint = *( pFill->GetEndPoint () ) +
00472 *( pFill->GetEndPoint2 () ) -
00473 *( pFill->GetStartPoint () );
00474 }
00475 else
00476 {
00477
00478 EndPoint = *( pFill->GetEndPoint () );
00479 }
00480
00481
00482
00483 DocRect cBBox;
00484 CalcCorelBBox(Coords, NumCoords, &cBBox);
00485
00486
00487 if ( StartPoint == EndPoint || cBBox.Width () == 0 || cBBox.Height () == 0 )
00488 return WriteFillSpecFlat(pReg, pFill);
00489
00490
00491 DocCoord Centre;
00492 Centre.x = cBBox.lo.x + cBBox.Width() / 2;
00493 Centre.y = cBBox.lo.y + cBBox.Height() / 2;
00494
00495
00496
00497
00498 double dx = EndPoint.x - StartPoint.x;
00499 double dy = EndPoint.y - StartPoint.y;
00500 double PointDist = sqrt(((dx * dx) + (dy * dy)));
00501
00502
00503 double Angle = atan2(dy, dx);
00504
00505
00506
00507 INT32 StartPercent;
00508 INT32 EndPercent;
00509
00510 cmxFillBase1 fb1;
00511 fb1.Padding = 0;
00512 cmxFillBase2 fb2;
00513 fb2.XOffset = 0;
00514 fb2.YOffset = 0;
00515
00516 if(Radial)
00517 {
00518
00519
00520
00521
00522 DocCoord dCentre = StartPoint - Centre;
00523 fb2.XOffset = (dCentre.x * 100) / cBBox.Width();
00524 fb2.YOffset = (dCentre.y * 100) / cBBox.Height();
00525
00526 if(fb2.XOffset > 100) fb2.XOffset = 100;
00527 if(fb2.XOffset < -100) fb2.XOffset = -100;
00528 if(fb2.YOffset > 100) fb2.YOffset = 100;
00529 if(fb2.YOffset < -100) fb2.YOffset = -100;
00530
00531
00532
00533 double w = cBBox.Width(), h = cBBox.Height();
00534 double bboxdiagonal = sqrt(w*w + h*h);
00535 double cdx = dCentre.x, cdy = dCentre.y;
00536 double cendist = sqrt(cdx*cdx + cdy*cdy);
00537 double BodgeFactor = 1 + (cendist / (bboxdiagonal / 2));
00538 double targetradius = PointDist / BodgeFactor;
00539 double Pad = 50 * (1 - (2 * targetradius) / bboxdiagonal);
00540
00541 if(Pad < 0) Pad = 0;
00542 if(Pad > 44) Pad = 44;
00543
00544 fb1.Padding = (WORD)Pad;
00545
00546
00547 StartPercent = 0;
00548 EndPercent = 0;
00549
00550
00551 if(pFill->IsASquareFill())
00552 {
00553 WORD t = StartColReference;
00554 StartColReference = EndColReference;
00555 EndColReference = t;
00556 }
00557 }
00558
00559 else
00560 {
00561
00562
00563
00564
00565
00566
00567 double cAngle = Angle;
00568 INT32 cAR = 0;
00569 while(cAngle > (PI/2))
00570 {
00571 cAngle -= PI/2;
00572 cAR++;
00573 }
00574
00575
00576
00577 INT32 qdx = cBBox.Width() / 2;
00578 INT32 qdy = cBBox.Height() / 2;
00579 if((cAR & 1) != 0)
00580 {
00581
00582 INT32 t = qdy;
00583 qdy = qdx;
00584 qdx = t;
00585 }
00586 DocCoord i;
00587 if(qdy == 0)
00588 {
00589
00590 i.x = qdx;
00591 i.y = 0;
00592 }
00593 else
00594 {
00595 double predqdy = qdx * tan(cAngle);
00596 if(predqdy > qdy)
00597 {
00598
00599 i.x = (INT32)(((double)qdy) / tan(cAngle));
00600 i.y = qdy;
00601 }
00602 else
00603 {
00604
00605 i.x = qdx;
00606 i.y = (INT32)(((double)qdx) * tan(cAngle));
00607 }
00608 }
00609
00610
00611
00612
00613
00614
00615
00616 INT32 linelength = (INT32)sqrt(((double)(i.x) * (double)(i.x)) + ((double)(i.y) * (double)(i.y)));
00617
00618 if(linelength == 0)
00619 return WriteFillSpecFlat(pReg, pFill);
00620
00621
00622 DocCoord dStartPoint = StartPoint - Centre;
00623 DocCoord dEndPoint = EndPoint - Centre;
00624
00625
00626
00627 Matrix Mat(((- Angle) * 360.0) / (2*PI));
00628 Mat.transform(&dStartPoint);
00629 Mat.transform(&dEndPoint);
00630
00631
00632 INT32 dStart = dStartPoint.x + linelength;
00633 INT32 dEnd = linelength - dEndPoint.x;
00634 if(dStart < 0) dStart = 0;
00635 if(dEnd < 0) dEnd = 0;
00636 INT32 dPad;
00637 if(dStart < dEnd)
00638 dPad = dStart;
00639 else
00640 dPad = dEnd;
00641
00642 INT32 padval = (dPad * 100) / (linelength * 2);
00643 if(padval < 0) padval = 0;
00644 if(padval > 44) padval = 44;
00645 fb1.Padding = (WORD)padval;
00646
00647
00648 linelength -= dPad;
00649
00650
00651
00652 StartPercent = (INT32)((dStartPoint.x + linelength) * 100);
00653 EndPercent = (INT32)((dEndPoint.x + linelength) * 100);
00654 StartPercent /= (linelength * 2);
00655 EndPercent /= (linelength * 2);
00656
00657
00658 if(StartPercent < 0) StartPercent = 0;
00659 if(StartPercent > 100) StartPercent = 100;
00660 if(EndPercent < 0) EndPercent = 0;
00661 if(EndPercent > 100) EndPercent = 100;
00662 if(EndPercent < StartPercent)
00663 {
00664 INT32 t = StartPercent;
00665 StartPercent = EndPercent;
00666 EndPercent = t;
00667 }
00668 }
00669
00670
00671
00672 if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_Fountain_Base))
00673 return FALSE;
00674
00675 if(pFill->IsARadialFill())
00676 fb1.Type = cmxFOUNTAINTYPE_RADIAL;
00677 else if(pFill->IsASquareFill())
00678 fb1.Type = cmxFOUNTAINTYPE_SQUARE;
00679 else if(pFill->IsAConicalFill())
00680 fb1.Type = cmxFOUNTAINTYPE_CONICAL;
00681 else
00682 fb1.Type = cmxFOUNTAINTYPE_LINEAR;
00683 fb1.Screen = cmxSCREENREFERENCE;
00684
00685
00686
00687 fb2.StepCount = 0;
00688 fb2.FillMode = FillMode;
00689 fb2.RateMethod = 0;
00690 fb2.RateValue = 50;
00691
00692 if(!Radial)
00693 {
00694 if(FillMode == cmxFILLMODE_RGB)
00695 {
00696
00697
00698
00699 fb2.FillMode = cmxFILLMODE_CUSTOM;
00700 }
00701 else
00702 {
00703
00704
00705
00706 StartPercent = 0;
00707 EndPercent = 0;
00708 }
00709 }
00710
00711
00712 ExportFile->write(&fb1, sizeof(fb1));
00713
00714 WriteAngle(Angle);
00715
00716 if(ThirtyTwoBit)
00717 {
00718 ExportFile->write(&fb2, sizeof(fb2));
00719 }
00720 else
00721 {
00722
00723 cmxFillBase2_16 b = {0, (SWORD)fb2.XOffset, (SWORD)fb2.YOffset,
00724 fb2.StepCount, fb2.FillMode};
00725
00726 ExportFile->write(&b, sizeof(b));
00727 }
00728
00729
00730 if(!EndNestedTag())
00731 return FALSE;
00732
00733
00734 if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_Fountain_Color))
00735 return FALSE;
00736
00737 cmxGradFillColour col;
00738 ColourRamp *pRamp = pFill->GetColourRamp ();
00739 WORD NCol = 2 + ( ( StartPercent != 0 ) ? 1 : 0 ) +
00740 ( ( EndPercent != 100 ) ? 1 : 0 ) + ( FourColour ? 1 : 0 );
00741
00742
00743 if ( pRamp != NULL )
00744 {
00745 UINT32 FirstIndex = 0;
00746 UINT32 LastIndex = 0;
00747
00748
00749
00750 pRamp->GetIndexRange ( &FirstIndex, &LastIndex );
00751
00752
00753
00754
00755
00756 NCol += 1 + LastIndex - FirstIndex;
00757 }
00758
00759
00760 ExportFile->write ( &NCol, sizeof ( NCol ) );
00761
00762
00763 if(StartPercent != 0)
00764 {
00765 col.ColRef = StartColReference;
00766 col.ColPos = 0;
00767 ExportFile->write(&col, sizeof(col));
00768 }
00769
00770 col.ColRef = StartColReference;
00771 col.ColPos = (WORD)StartPercent;
00772 ExportFile->write(&col, sizeof(col));
00773
00774
00775 if ( FourColour )
00776 {
00777 col.ColRef = MidColReference;
00778 col.ColPos = ( WORD ) ( ( StartPercent + EndPercent ) / 2 );
00779 ExportFile->write ( &col, sizeof ( col ) );
00780 }
00781
00782
00783 if ( pRamp != NULL )
00784 {
00785 ColRampItem *pColour = pRamp->GetFirstCol ();
00786
00787
00788 while ( pColour != NULL )
00789 {
00790 cmxGradFillColour RampColour;
00791
00792
00793 RampColour.ColPos = ( WORD ) ( 100.0f * pColour->GetPosition () );
00794 RampColour.ColRef = GetColourReference ( &( pColour->GetColour () ) );
00795
00796
00797 ExportFile->write ( &RampColour, sizeof ( RampColour ) );
00798
00799
00800 pColour = pRamp->GetNextCol ( pColour );
00801 }
00802 }
00803
00804
00805 col.ColRef = EndColReference;
00806 col.ColPos = (WORD)EndPercent;
00807 ExportFile->write(&col, sizeof(col));
00808
00809 if(EndPercent != 100)
00810 {
00811 col.ColPos = 100;
00812 ExportFile->write(&col, sizeof(col));
00813 }
00814
00815 if(!EndNestedTag())
00816 return FALSE;
00817
00818
00819 if(!WriteMinEndTag())
00820 return FALSE;
00821
00822 return TRUE;
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 BOOL CMXExportDC::WriteFillSpecBitmap(CMXRenderRegion *pReg, FillGeometryAttribute *pFill, DocCoord *Coords, INT32 NumCoords)
00839 {
00840
00841 BitmapFillAttribute *pBFillAttr = (BitmapFillAttribute *)pFill;
00842 ERROR3IF(!pBFillAttr->IsKindOf(CC_RUNTIME_CLASS(BitmapFillAttribute)), "not a bitmap fill attr");
00843
00844
00845 DocColour *pStartColour = 0;
00846 DocColour *pEndColour = 0;
00847 EFFECTTYPE Effect = EFFECT_RGB;
00848
00849
00850 pStartColour = pFill->GetStartColour();
00851 pEndColour = pFill->GetEndColour();
00852 if(pStartColour == 0 || pEndColour == 0
00853 || pStartColour->IsTransparent()
00854 || pEndColour->IsTransparent())
00855 {
00856 pStartColour = 0;
00857 pEndColour = 0;
00858 }
00859
00860 if(pStartColour != 0)
00861 {
00862
00863 Effect = pReg->GetFillEffect();
00864 }
00865
00866
00867 KernelBitmap *pBitmap = pBFillAttr->BitmapRef.GetBitmap();
00868 WORD BitmapRef = GetBitmapReference(pBitmap, pStartColour, pEndColour, Effect);
00869
00870
00871 CMXReferBitmapFill *pBFill = new CMXReferBitmapFill(this);
00872 if(pBFill == 0)
00873 return FALSE;
00874 pBFill->Set(BitmapRef);
00875
00876
00877 ReferList.AddTail(pBFill);
00878
00879
00880 WORD BitmapFillProcReference = GetProcedureReference(pBFill);
00881
00882
00883 if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec_ColorBM))
00884 return FALSE;
00885
00886 ExportFile->write(&BitmapFillProcReference, sizeof(BitmapFillProcReference));
00887
00888
00889 if(!StartNestedTag(cmxTAG_Tiling))
00890 return FALSE;
00891
00892
00893 DocCoord *Start = pFill->GetStartPoint();
00894 DocCoord *End1 = pFill->GetEndPoint();
00895 DocCoord *End2 = pFill->GetEndPoint2();
00896
00897
00898 cmxTilingEnd tile;
00899
00900
00901
00902
00903
00904 DocRect cBBox;
00905 double TileWidth = Start->Distance ( *End1 );
00906 double TileHeight = Start->Distance ( *End2 );
00907
00908
00909 CalcCorelBBox(Coords, NumCoords, &cBBox);
00910
00911
00912
00913 if ( ThirtyTwoBit )
00914 {
00915 cmxTilingBegin32 Tile32;
00916 Tile32.Width = static_cast<DWORD> ( Round ( TileWidth * ScaleFactor ) );
00917 Tile32.Height = static_cast<DWORD> ( Round ( TileHeight * ScaleFactor ) );
00918
00919 WriteData ( &Tile32, sizeof ( Tile32 ) );
00920 }
00921 else
00922 {
00923 cmxTilingBegin16 Tile16;
00924 Tile16.Width = static_cast<WORD> ( Round ( TileWidth * ScaleFactor ) );
00925 Tile16.Height = static_cast<WORD> ( Round ( TileHeight * ScaleFactor ) );
00926
00927 WriteData ( &Tile16, sizeof ( Tile16 ) );
00928 }
00929
00930
00931 double dX = static_cast<double> ( Start->x - cBBox.lo.x );
00932 double dY = static_cast<double> ( cBBox.hi.y - Start->y );
00933
00934
00935 tile.XOffset = ( static_cast<WORD> ( Round ( ( dX * 100.0 ) / TileWidth ) ) ) % 100;
00936 tile.YOffset = ( static_cast<WORD> ( Round ( ( dY * 100.0 ) / TileHeight ) ) ) % 100;
00937
00938 tile.InterTileOffset = tile.TilingFlags = 0;
00939
00940
00941 ExportFile->write(&tile, sizeof(tile));
00942 if(!EndNestedTag() || !WriteMinEndTag())
00943 return FALSE;
00944
00945
00946 DocRect bbox = DocRect(0, 0, cmxBITMAPFILLTILESIZE_X, cmxBITMAPFILLTILESIZE_Y);
00947
00948 if(!WriteBBox(&bbox, FALSE))
00949 return FALSE;
00950
00951 if(!EndNestedTag() || !WriteMinEndTag())
00952 return FALSE;
00953
00954 return TRUE;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 BOOL CMXExportDC::WritePath ( DocCoord *Coords,
00974 PathVerb *Verbs,
00975 INT32 NumCoords,
00976 BOOL Filled )
00977 {
00978
00979
00980
00981
00982 BOOL ForceNoFill = TRUE;
00983 for(INT32 p = 0; p < NumCoords; p++)
00984 {
00985 if((Verbs[p] & PT_CLOSEFIGURE) != 0)
00986 ForceNoFill = FALSE;
00987 }
00988 if(!Filled)
00989 ForceNoFill = TRUE;
00990
00991
00992 if(!StartCommand(cmxINSTR_PolyCurve))
00993 return FALSE;
00994
00995
00996 if(!WriteAttributes(pRenderRegion, cmxTAG_PolyCurve_RenderingAttr, Coords, NumCoords, ForceNoFill))
00997 return FALSE;
00998
00999
01000 if(!StartTag(cmxTAG_PolyCurve_PointList))
01001 return FALSE;
01002
01003
01004
01005 DocRect bb;
01006 DocCoord fc = Coords[0];
01007 pMatrix->transform(&fc);
01008 bb.lo = fc;
01009 bb.hi = fc;
01010
01011
01012 WORD Count = (WORD)NumCoords;
01013 ExportFile->write(&Count, sizeof(Count));
01014
01015
01016 INT32 l;
01017 TRACEUSER( "Ben", _T("\nPath\n"));
01018 for(l = 0; l < NumCoords; l++)
01019 {
01020 DocCoord Coord = Coords[l];
01021 pMatrix->transform(&Coord);
01022
01023
01024 if(ThirtyTwoBit)
01025 {
01026 cmxPoint32 p = {Coord.x, Coord.y};
01027 ExportFile->write(&p, sizeof(p));
01028 }
01029 else
01030 {
01031 TRACEUSER( "Ben", _T("Coord %d %d\n"), Coord.x, Coord.y);
01032 cmxPoint16 p = {(SWORD)Coord.x, (SWORD)Coord.y};
01033 ExportFile->write(&p, sizeof(p));
01034 }
01035
01036
01037 if(Coord.x < bb.lo.x) bb.lo.x = Coord.x;
01038 if(Coord.y < bb.lo.y) bb.lo.y = Coord.y;
01039 if(Coord.x > bb.hi.x) bb.hi.x = Coord.x;
01040 if(Coord.y > bb.hi.y) bb.hi.y = Coord.y;
01041 }
01042
01043
01044 INT32 BezCount = 0;
01045 for(l = 0; l < NumCoords; l++)
01046 {
01047 BYTE Type;
01048
01049 switch(Verbs[l] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO))
01050 {
01051 case PT_MOVETO:
01052 {
01053 Type = CMXNODETYPE_TYPE_MOVE | CMXNODETYPE_USER;
01054
01055
01056 for(INT32 lp = l + 1; lp < NumCoords; lp++)
01057 {
01058
01059 if((Verbs[lp] & (PT_LINETO | PT_MOVETO | PT_BEZIERTO)) == PT_MOVETO)
01060 break;
01061
01062
01063 if((Verbs[lp] & PT_CLOSEFIGURE) != 0)
01064 {
01065 Type |= CMXNODETYPE_CLOSED;
01066 break;
01067 }
01068 }
01069 }
01070 BezCount = 0;
01071 break;
01072
01073 case PT_LINETO:
01074 Type = CMXNODETYPE_TYPE_LINE | CMXNODETYPE_USER;
01075 BezCount = 0;
01076 break;
01077
01078 case PT_BEZIERTO:
01079
01080
01081 if(BezCount == 2)
01082 {
01083 Type = CMXNODETYPE_TYPE_CURVE | CMXNODETYPE_USER;
01084 }
01085 else
01086 {
01087 Type = CMXNODETYPE_TYPE_ARC;
01088 }
01089 BezCount++;
01090 if(BezCount > 2)
01091 BezCount = 0;
01092 break;
01093
01094 default:
01095 ERROR3("Unknown node type");
01096 break;
01097 }
01098
01099 if((Verbs[l] & PT_CLOSEFIGURE) != 0)
01100 {
01101 Type |= CMXNODETYPE_CLOSED;
01102 }
01103
01104 ExportFile->write(&Type, sizeof(Type));
01105 }
01106
01107
01108 if(!EndTag())
01109 return FALSE;
01110
01111
01112 if(!StartTag(cmxTAG_PolyCurve_BoundingBox)
01113 || !WriteBBox(&bb, FALSE)
01114 || !EndTag())
01115 return FALSE;
01116
01117
01118 if(!WriteMinEndTag()
01119 || !EndCommand())
01120 return FALSE;
01121
01122
01123
01124 return TRUE;
01125 }
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140 WORD CMXExportDC::GetColourReference(DocColour *pTheLovelyColour)
01141 {
01142
01143
01144
01145
01146
01147
01148 INT32 Ref = 0;
01149
01150
01151 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01152 while(pEn != 0)
01153 {
01154 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01155
01156 if(pEn->IsInWhichDesc() == cmxDESC_COLOUR)
01157 {
01158 Ref++;
01159
01160 CMXReferColour *pLC = (CMXReferColour *)pEn;
01161 ERROR3IF(!pLC->IsKindOf(CC_RUNTIME_CLASS(CMXReferColour)), "not a refer colour, when it said it was");
01162
01163
01164 if(pLC->AreYouThisColour(pTheLovelyColour))
01165 {
01166
01167 return Ref;
01168 }
01169 }
01170
01171 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01172 }
01173
01174
01175 CMXReferColour *pNewRefCol = new CMXReferColour(this);
01176 if(pNewRefCol == 0)
01177 return 0;
01178
01179 pNewRefCol->SetColour(pTheLovelyColour);
01180
01181 ReferList.AddTail(pNewRefCol);
01182
01183
01184 return (WORD)Ref + 1;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201 WORD CMXExportDC::GetArrowReference(ArrowRec *pArrow)
01202 {
01203
01204 if(pArrow->IsNullArrow())
01205 return 0;
01206
01207
01208 INT32 Ref = 0;
01209
01210
01211 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01212 while(pEn != 0)
01213 {
01214 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01215
01216 if(pEn->IsInWhichDesc() == cmxDESC_ARROW)
01217 {
01218 Ref++;
01219
01220 CMXReferArrow *pAr = (CMXReferArrow *)pEn;
01221 ERROR3IF(!pAr->IsKindOf(CC_RUNTIME_CLASS(CMXReferArrow)), "not an arrow, when it said it was");
01222
01223
01224 if(pAr->AreYouThisArrow(pArrow))
01225 {
01226
01227 return Ref;
01228 }
01229 }
01230
01231 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01232 }
01233
01234
01235 CMXReferArrow *pNewArrow = new CMXReferArrow(this);
01236 if(pNewArrow == 0)
01237 return 0;
01238
01239 pNewArrow->Set(pArrow);
01240
01241 ReferList.AddTail(pNewArrow);
01242
01243
01244 return (WORD)Ref + 1;
01245 }
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 WORD CMXExportDC::GetBitmapReference(KernelBitmap *pTheLovelyBitmap, DocColour *pStartCol,
01262 DocColour *pEndCol, EFFECTTYPE Effect, CMXReferBitmap **ppRB)
01263 {
01264
01265 INT32 Ref = 0;
01266
01267
01268 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01269 while(pEn != 0)
01270 {
01271 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01272
01273 if(pEn->IsInWhichIndex() == cmxINDEX_EMBEDFILE && IS_A(pEn, CMXReferBitmap))
01274 {
01275 Ref++;
01276
01277 CMXReferBitmap *pBitty = (CMXReferBitmap *)pEn;
01278
01279
01280 if(pBitty->AreYouThisBitmap(pTheLovelyBitmap, pStartCol, pEndCol, Effect))
01281 {
01282
01283 if(ppRB != 0)
01284 (*ppRB) = pBitty;
01285
01286 return Ref;
01287 }
01288 }
01289
01290 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01291 }
01292
01293
01294 CMXReferBitmap *pNewRefBit = new CMXReferBitmap(this);
01295 if(pNewRefBit == 0)
01296 return 0;
01297
01298 pNewRefBit->Set(pTheLovelyBitmap, pStartCol, pEndCol, Effect);
01299
01300 ReferList.AddTail(pNewRefBit);
01301
01302
01303 if(ppRB != 0)
01304 (*ppRB) = pNewRefBit;
01305
01306
01307 return (WORD)Ref + 1;
01308 }
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 BOOL CMXReferPen::WriteInDesc(CMXExportDC *pDC)
01324 {
01325 if(pDC->IsThirtyTwoBit())
01326 {
01327
01328 if(!pDC->StartTag(cmxTAG_DescrSection_Pen))
01329 return FALSE;
01330
01331 cmxPen32 pen;
01332
01333 double scaledwidth = ((double)Width) * CAMCOORD_SCALEFACTOR32;
01334 pen.Width = (DWORD)scaledwidth;
01335 pen.Aspect = 100;
01336 pen.Angle = 0;
01337 pDC->WriteData(&pen, sizeof(pen));
01338
01339
01340 if(!pDC->WriteMatrix())
01341 return FALSE;
01342
01343
01344 if(!pDC->EndTag()
01345 || !pDC->WriteMinEndTag())
01346 return FALSE;
01347 }
01348 else
01349 {
01350 cmxPen16 pen;
01351
01352 double scaledwidth = ((double)Width) * pDC->GetScaleFactor();
01353 pen.Width = (WORD)scaledwidth;
01354 pen.Aspect = 100;
01355 pen.Angle = 0;
01356 pDC->WriteData(&pen, sizeof(pen));
01357
01358
01359 if(!pDC->WriteMatrix())
01360 return FALSE;
01361 }
01362
01363 return TRUE;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 BOOL CMXReferArrowheads::WriteInDesc(CMXExportDC *pDC)
01380 {
01381 struct {
01382 WORD Start,End;
01383 } en = {Start, End};
01384
01385 return pDC->WriteData(&en, sizeof(en));
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401 BOOL CMXReferLineStyle::WriteInDesc(CMXExportDC *pDC)
01402 {
01403 if(!pDC->WriteTag(cmxTAG_DescrSection_LineStyle, &LineStyle, sizeof(LineStyle))
01404 || !pDC->WriteMinEndTag())
01405 return FALSE;
01406
01407 return TRUE;
01408 }
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 BOOL CMXReferLineStyle::AreYouThisStyle(cmxLineStyle *pLineStyle)
01424 {
01425
01426
01427 if(memcmp(&LineStyle, pLineStyle, sizeof(cmxLineStyle)) == 0)
01428 {
01429
01430 return TRUE;
01431 }
01432
01433
01434 return FALSE;
01435 }
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 BOOL CMXReferOutline::WriteInDesc(CMXExportDC *pDC)
01451 {
01452 if(!pDC->WriteTag(cmxTAG_DescrSection_Outline, &Outline, sizeof(Outline))
01453 || !pDC->WriteMinEndTag())
01454 return FALSE;
01455
01456 return TRUE;
01457 }
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472 BOOL CMXReferOutline::AreYouThisOutline(cmxOutline *pOutline)
01473 {
01474
01475
01476 if(memcmp(&Outline, pOutline, sizeof(cmxOutline)) == 0)
01477 {
01478
01479 return TRUE;
01480 }
01481
01482
01483 return FALSE;
01484 }
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499 BOOL CMXExportDC::WriteOutlineSpec(CMXRenderRegion *pReg)
01500 {
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512 MILLIPOINT Width;
01513
01514 LineWidthAttribute *pLineWidthA
01515 = (LineWidthAttribute *)pReg->GetCurrentAttribute(ATTR_LINEWIDTH);
01516
01517
01518 ERROR2IF(pLineWidthA == 0, FALSE, "No line width attribute");
01519 ERROR3IF(!pLineWidthA->IsKindOf(CC_RUNTIME_CLASS(LineWidthAttribute)), "not a line width attribute");
01520
01521 Width = pLineWidthA->LineWidth;
01522
01523
01524 DocColour *pColour;
01525
01526 StrokeColourAttribute *pColA
01527 = (StrokeColourAttribute *)pReg->GetCurrentAttribute(ATTR_STROKECOLOUR);
01528
01529 ERROR2IF(pColA == 0, FALSE, "No stroke colour attribute");
01530 ERROR3IF(!pColA->IsKindOf(CC_RUNTIME_CLASS(StrokeColourAttribute)), "not a stroke colour attribute");
01531
01532 pColour = pColA->GetStartColour();
01533
01534
01535 BOOL TransparentLine = FALSE;
01536 WORD ColRef;
01537 if(pColour->IsTransparent())
01538 {
01539 TransparentLine = TRUE;
01540 Width = 0;
01541 }
01542 else
01543 ColRef = GetColourReference(pColour);
01544
01545
01546 cmxLineStyle LineStyle;
01547 LineStyle.Spec = TransparentLine?cmxLINESPEC_NONE:0;
01548 LineStyle.CapAndJoin = 0;
01549
01550
01551
01552 JoinTypeAttribute *pJTA
01553 = (JoinTypeAttribute *)pReg->GetCurrentAttribute(ATTR_JOINTYPE);
01554
01555 ERROR2IF(pJTA == 0, FALSE, "No join type attribute");
01556 ERROR3IF(!pJTA->IsKindOf(CC_RUNTIME_CLASS(JoinTypeAttribute)), "not a join type attribute");
01557
01558 switch(pJTA->JoinType)
01559 {
01560 case RoundJoin: LineStyle.CapAndJoin |= cmxCAPJOIN_ROUNDJOIN; break;
01561 case BevelledJoin: LineStyle.CapAndJoin |= cmxCAPJOIN_BEVELJOIN; break;
01562 default: break;
01563 }
01564
01565
01566
01567 StartCapAttribute *pSCA
01568 = (StartCapAttribute *)pReg->GetCurrentAttribute(ATTR_STARTCAP);
01569
01570 ERROR2IF(pSCA == 0, FALSE, "No start cap attribute");
01571 ERROR3IF(!pSCA->IsKindOf(CC_RUNTIME_CLASS(StartCapAttribute)), "not a start cap attribute");
01572
01573 switch(pSCA->StartCap)
01574 {
01575 case LineCapRound: LineStyle.CapAndJoin |= cmxCAPJOIN_ROUNDCAP; break;
01576 case LineCapSquare: LineStyle.CapAndJoin |= cmxCAPJOIN_SQUARECAP; break;
01577 default: break;
01578 }
01579
01580
01581 DashRec *pDash;
01582 DashPatternAttribute *pDas
01583 = (DashPatternAttribute *)pReg->GetCurrentAttribute(ATTR_DASHPATTERN);
01584
01585 ERROR2IF(pDas == 0, FALSE, "No dash pattern attribute");
01586 ERROR3IF(!pDas->IsKindOf(CC_RUNTIME_CLASS(DashPatternAttribute)), "not a dash pattern attribute");
01587
01588 pDash = &pDas->DashPattern;
01589
01590 if(pDash->Elements != 0)
01591 LineStyle.Spec |= cmxLINESPEC_DOTDASH;
01592 else
01593 LineStyle.Spec |= cmxLINESPEC_SOLIDOUTLINE;
01594
01595
01596 EndArrowAttribute *pEa
01597 = (EndArrowAttribute *)pReg->GetCurrentAttribute(ATTR_ENDARROW);
01598
01599 ERROR2IF(pEa == 0, FALSE, "No arrow attribute");
01600 ERROR3IF(!pEa->IsKindOf(CC_RUNTIME_CLASS(EndArrowAttribute)), "not a arrow attribute");
01601 StartArrowAttribute *pSa
01602 = (StartArrowAttribute *)pReg->GetCurrentAttribute(ATTR_STARTARROW);
01603
01604 ERROR2IF(pSa == 0, FALSE, "No arrow attribute");
01605 ERROR3IF(!pSa->IsKindOf(CC_RUNTIME_CLASS(StartArrowAttribute)), "not a arrow attribute");
01606
01607
01608 WORD StartArrow = GetArrowReference(&pSa->StartArrow);
01609 WORD EndArrow = GetArrowReference(&pEa->EndArrow);
01610
01611
01612 BOOL FoundPen = FALSE;
01613 WORD PenRef = 0;
01614 BOOL FoundLineStyle = FALSE;
01615 WORD LineStyleRef = 0;
01616 BOOL FoundArrowheads = FALSE;
01617 WORD ArrowheadsRef = 0;
01618 BOOL FoundDotDash = FALSE;
01619 WORD DotDashRef = 0;
01620
01621 WORD LastOutlineRef = 0;
01622
01623 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01624 while(pEn != 0)
01625 {
01626 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01627
01628 switch(pEn->IsInWhichDesc())
01629 {
01630
01631 case cmxDESC_PEN:
01632 if(!FoundPen)
01633 {
01634 PenRef++;
01635
01636 CMXReferPen *pPen = (CMXReferPen *)pEn;
01637 ERROR3IF(!pPen->IsKindOf(CC_RUNTIME_CLASS(CMXReferPen)), "not a refer pen, when it said it was");
01638
01639
01640 if(pPen->AreYouThisWidth(Width))
01641 {
01642
01643 FoundPen = TRUE;
01644 }
01645 }
01646 break;
01647
01648 case cmxDESC_LINESTYLE:
01649 if(!FoundLineStyle)
01650 {
01651 LineStyleRef++;
01652
01653 CMXReferLineStyle *pSt = (CMXReferLineStyle *)pEn;
01654 ERROR3IF(!pSt->IsKindOf(CC_RUNTIME_CLASS(CMXReferLineStyle)), "not a refer LineStyle, when it said it was");
01655
01656
01657 if(pSt->AreYouThisStyle(&LineStyle))
01658 {
01659
01660 FoundLineStyle = TRUE;
01661 }
01662 }
01663 break;
01664
01665 case cmxDESC_ARROWHEADS:
01666 if(!FoundArrowheads)
01667 {
01668 ArrowheadsRef++;
01669
01670 CMXReferArrowheads *pAh = (CMXReferArrowheads *)pEn;
01671 ERROR3IF(!pAh->IsKindOf(CC_RUNTIME_CLASS(CMXReferArrowheads)), "not a arrowheads, when it said it was");
01672
01673
01674 if(pAh->AreYouThisArrowheads(StartArrow, EndArrow))
01675 {
01676
01677 FoundArrowheads = TRUE;
01678 }
01679 }
01680 break;
01681
01682 case cmxDESC_DOTDASH:
01683 if(!FoundDotDash)
01684 {
01685 DotDashRef++;
01686
01687 CMXReferDotDash *pDd = (CMXReferDotDash *)pEn;
01688 ERROR3IF(!pDd->IsKindOf(CC_RUNTIME_CLASS(CMXReferDotDash)), "not a refer dot dash, when it said it was");
01689
01690
01691 if(pDd->AreYouThisDotDash(pDash))
01692 {
01693
01694 FoundDotDash = TRUE;
01695 }
01696 }
01697 break;
01698
01699 case cmxDESC_OUTLINE:
01700 LastOutlineRef++;
01701 break;
01702
01703 default:
01704
01705 break;
01706 }
01707
01708 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01709 }
01710
01711
01712 BOOL NewReferObjectCreated = FALSE;
01713
01714 if(!FoundPen)
01715 {
01716 NewReferObjectCreated = TRUE;
01717
01718 CMXReferPen *pPen = new CMXReferPen(this);
01719 if(pPen == NULL)
01720 return FALSE;
01721
01722 pPen->SetWidth(Width);
01723 PenRef++;
01724
01725 ReferList.AddTail(pPen);
01726 }
01727
01728 if(!FoundLineStyle)
01729 {
01730 NewReferObjectCreated = TRUE;
01731
01732 CMXReferLineStyle *pLs = new CMXReferLineStyle(this);
01733 if(pLs == NULL)
01734 return FALSE;
01735
01736 pLs->SetLineStyle(&LineStyle);
01737 LineStyleRef++;
01738
01739 ReferList.AddTail(pLs);
01740 }
01741
01742 if(!FoundArrowheads)
01743 {
01744 NewReferObjectCreated = TRUE;
01745
01746 CMXReferArrowheads *pAh = new CMXReferArrowheads(this);
01747 if(pAh == NULL)
01748 return FALSE;
01749
01750 pAh->SetArrowheads(StartArrow, EndArrow);
01751 ArrowheadsRef++;
01752
01753 ReferList.AddTail(pAh);
01754 }
01755
01756 if(!FoundDotDash)
01757 {
01758 NewReferObjectCreated = TRUE;
01759
01760 CMXReferDotDash *pDd = new CMXReferDotDash(this);
01761 if(pDd == NULL)
01762 return FALSE;
01763
01764 pDd->Set(pDash);
01765 DotDashRef++;
01766
01767 ReferList.AddTail(pDd);
01768 }
01769
01770
01771 cmxOutline Outline;
01772 memset(&Outline, 0, sizeof(Outline));
01773
01774 Outline.LineStyle = LineStyleRef;
01775 Outline.Screen = cmxSCREENREFERENCE;
01776 if(TransparentLine)
01777 Outline.Colour = 1;
01778 else
01779 Outline.Colour = ColRef;
01780 Outline.Arrowheads = ArrowheadsRef;
01781 Outline.Pen = PenRef;
01782 Outline.DotDash = DotDashRef;
01783
01784
01785 BOOL FoundOutline = FALSE;
01786 WORD OutlineRef = 0;
01787 if(NewReferObjectCreated == FALSE)
01788 {
01789 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01790 while(pEn != 0)
01791 {
01792 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01793
01794 if(pEn->IsInWhichDesc() == cmxDESC_OUTLINE)
01795 {
01796 OutlineRef++;
01797
01798 CMXReferOutline *pLC = (CMXReferOutline *)pEn;
01799 ERROR3IF(!pLC->IsKindOf(CC_RUNTIME_CLASS(CMXReferOutline)), "not a refer outline, when it said it was");
01800
01801
01802 if(pLC->AreYouThisOutline(&Outline))
01803 {
01804 FoundOutline = TRUE;
01805 break;
01806 }
01807 }
01808
01809 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01810 }
01811 }
01812
01813
01814 if(FoundOutline == FALSE)
01815 {
01816 OutlineRef = LastOutlineRef + 1;
01817
01818
01819 CMXReferOutline *pOlt = new CMXReferOutline(this);
01820 if(pOlt == NULL)
01821 return FALSE;
01822
01823
01824 pOlt->SetOutline(&Outline);
01825
01826
01827 ReferList.AddTail(pOlt);
01828 }
01829
01830
01831 if(!WriteNestedTag(cmxTAG_RenderAttr_OutlineSpec, &OutlineRef, sizeof(OutlineRef)))
01832 return FALSE;
01833
01834
01835 if(!WriteMinEndTag())
01836 return FALSE;
01837
01838 return TRUE;
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855 void CMXExportDC::CalcCorelBBox(DocCoord *Coords, INT32 NumCoords, DocRect *Result)
01856 {
01857 ERROR3IF(Coords == NULL || NumCoords < 1, "dodgy coords");
01858
01859
01860 Result->lo = Coords[0];
01861 Result->hi = Coords[0];
01862
01863
01864 for(INT32 l = 1; l < NumCoords; l++)
01865 {
01866 if(Result->lo.x > Coords[l].x) Result->lo.x = Coords[l].x;
01867 if(Result->lo.y > Coords[l].y) Result->lo.y = Coords[l].y;
01868 if(Result->hi.x < Coords[l].x) Result->hi.x = Coords[l].x;
01869 if(Result->hi.y < Coords[l].y) Result->hi.y = Coords[l].y;
01870 }
01871
01872
01873 }
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890 WORD CMXExportDC::GetProcedureReference(CMXReferListItem *pProc)
01891 {
01892 ERROR3IF(!pProc->IsAProcedure(), "item is not a procedure");
01893
01894
01895 WORD Ref = 0;
01896 CMXReferListItem *pEn = (CMXReferListItem *)ReferList.GetHead();
01897 while(pEn != 0)
01898 {
01899 ERROR3IF(!pEn->IsKindOf(CC_RUNTIME_CLASS(CMXReferListItem)), "unexpected type of entry in refer list");
01900
01901 if(pEn->IsAProcedure())
01902 {
01903
01904 Ref++;
01905
01906
01907 if(pEn == pProc)
01908 return Ref;
01909 }
01910
01911 pEn = (CMXReferListItem *)ReferList.GetNext(pEn);
01912 }
01913
01914 return 1;
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932 BOOL CMXExportDC::WriteAttrCheckLens(CMXRenderRegion *pReg, INT32 Tag, DocCoord *Coords, INT32 NumCoords, BOOL *WasLens)
01933 {
01934
01935 *WasLens = FALSE;
01936
01937
01938 TranspFillAttribute *pTra =
01939 (TranspFillAttribute *)pReg->GetCurrentAttribute(ATTR_TRANSPFILLGEOMETRY);
01940
01941 if(pTra == NULL)
01942 {
01943 TRACEUSER( "Ben", _T("No transparent fill attribute -- assuming it's not transparent\n"));
01944 return TRUE;
01945 }
01946 ERROR3IF(!pTra->IsKindOf(CC_RUNTIME_CLASS(TranspFillAttribute)), "not a transparent fill attribute");
01947
01948
01949 UINT32 TransparencyValue = 0;
01950 if(pTra->IsAFlatFill())
01951 {
01952 TransparencyValue = *pTra->GetStartTransp();
01953 }
01954 else
01955 {
01956
01957 TransparencyValue = (*pTra->GetStartTransp() + *pTra->GetEndTransp()) / 2;
01958 }
01959
01960
01961 if (TransparencyValue == 0)
01962 return TRUE;
01963
01964 TRACEUSER( "Ben", _T("transparent, has value %d\n"), TransparencyValue);
01965
01966
01967 if(WriteAttrCheckIgnoreLens(pReg, Coords, NumCoords))
01968 {
01969
01970 return TRUE;
01971 }
01972
01973
01974 WORD UniformRate = 1000 - ((TransparencyValue * 1000) / 255);
01975
01976
01977 WORD ColourReference = 1;
01978
01979
01980 FillGeometryAttribute *pFillGeometry
01981 = (FillGeometryAttribute *)pReg->GetCurrentAttribute(ATTR_FILLGEOMETRY);
01982
01983
01984 ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
01985 ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
01986
01987
01988 DocColour *pColour = pFillGeometry->GetStartColour();
01989
01990 if(pColour != 0 && !pColour->IsTransparent())
01991 {
01992
01993 ColourReference = GetColourReference(pColour);
01994 }
01995
01996
01997 CMXReferLens *pLens = new CMXReferLens(this);
01998 if(pLens == NULL)
01999 return FALSE;
02000
02001
02002 DocRect bb;
02003 CalcCorelBBox(Coords, NumCoords, &bb);
02004
02005
02006 if(!pLens->Set(this, &bb))
02007 return FALSE;
02008
02009
02010 ReferList.AddTail(pLens);
02011
02012
02013
02014 if(Tag != -1)
02015 if(!StartTag(Tag))
02016 return FALSE;
02017
02018
02019 WriteByte(cmxRENDATTRMASK_FILL | cmxRENDATTRMASK_OUTLINE | cmxRENDATTRMASK_LENS);
02020
02021
02022 if(!StartNestedTag(cmxTAG_RenderAttr_FillSpec)
02023 ||!WriteFillType(cmxFILLID_UNIFORM))
02024 return FALSE;
02025 struct {
02026 WORD FillReference;
02027 WORD ScreenReference;
02028 } filldef = {ColourReference, cmxSCREENREFERENCE};
02029 if(!WriteNestedTag(cmxTAG_RenderAttr_FillSpec_Uniform, &filldef, sizeof(filldef))
02030 || !WriteMinEndTag()
02031 || !EndNestedTag()
02032 || !WriteMinEndTag())
02033 return FALSE;
02034
02035
02036 if(!WriteOutlineSpec(pReg))
02037 return FALSE;
02038
02039
02040 cmxGlassLensDefn lendef;
02041 lendef.LensType = cmxLENSTYPE_GLASS;
02042
02043 switch(pTra->GetTranspType())
02044 {
02045 default: lendef.TintMethod = cmxLENSTINTMETH_AVERAGE; break;
02046 case TT_StainGlass: lendef.TintMethod = cmxLENSTINTMETH_SUBTRACT; break;
02047 case TT_Bleach: lendef.TintMethod = cmxLENSTINTMETH_ADD; break;
02048 }
02049 lendef.UniformRate = UniformRate;
02050 lendef.ColourReference = ColourReference;
02051 lendef.RangeProcReference = GetProcedureReference(pLens);
02052
02053 if(!WriteNestedTag(cmxTAG_RenderAttr_LensSpec_Base, &lendef, sizeof(lendef)))
02054 return FALSE;
02055
02056 if(ThirtyTwoBit)
02057 {
02058 cmxLensFrozView fv;
02059 fv.FlagFrozen = 0;
02060 fv.FlagActive = 0;
02061 fv.ViewPointX = 0;
02062 fv.ViewPointY = 0;
02063
02064 if(!WriteNestedTag(cmxTAG_RenderAttr_LensSpec_FrozViewp, &fv, sizeof(fv))
02065 || !WriteMinEndTag())
02066 return FALSE;
02067 }
02068
02069
02070 if(Tag != -1)
02071 if(!EndTag())
02072 return FALSE;
02073
02074
02075 *WasLens = TRUE;
02076
02077
02078 SetCMXFlag(cmxSTRUCTFLAGS_HASLENS);
02079
02080 return TRUE;
02081 }
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099 BOOL CMXExportDC::WriteAttrCheckIgnoreLens(CMXRenderRegion *pReg, DocCoord *Coords, INT32 NumCoords)
02100 {
02101
02102 DocRect BBox;
02103 CalcCorelBBox(Coords, NumCoords, &BBox);
02104
02105
02106 INT32 LensesBehindThisOne = 0;
02107 CMXLensBBox *pEn = (CMXLensBBox *)LensBBoxes.GetHead();
02108 while(pEn != 0)
02109 {
02110
02111 if(pEn->DoesIntersect(&BBox))
02112 LensesBehindThisOne++;
02113
02114
02115 pEn = (CMXLensBBox *)LensBBoxes.GetNext(pEn);
02116 }
02117
02118
02119 CMXLensBBox *pNewLensBBox = new CMXLensBBox(&BBox);
02120 if(pNewLensBBox != NULL)
02121 LensBBoxes.AddTail(pNewLensBBox);
02122
02123
02124 if(LensesBehindThisOne > CMX_MAX_OVERLAP_LENSES)
02125 {
02126 TRACEUSER( "Ben", _T("found transparency to ignore, %d lenses behind\n"), LensesBehindThisOne);
02127
02128 if(!AreIgnoreingOverlappedLenses && !HaveAskedUserAboutLenses)
02129 {
02130 HaveAskedUserAboutLenses = TRUE;
02131
02132 INT32 Result = InformWarning(_R(IDW_CMXOVERLAPPEDLENS), _R(IDB_CMXDOLENSES), _R(IDB_CMXIGNORELENSES), 0, 0, 2, 1);
02133
02134 switch(Result)
02135 {
02136 case 1:
02137 AreIgnoreingOverlappedLenses = FALSE;
02138 break;
02139
02140 case 2:
02141 default:
02142 AreIgnoreingOverlappedLenses = TRUE;
02143 break;
02144 }
02145 }
02146
02147
02148 if(AreIgnoreingOverlappedLenses)
02149 {
02150
02151 OverlappedLensesHaveBeenIgnored = TRUE;
02152
02153 return TRUE;
02154 }
02155 }
02156
02157 return FALSE;
02158 }
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173 BOOL CMXReferLens::Set(CMXExportDC *pDC, DocRect *tBBox)
02174 {
02175
02176 BBox = *tBBox;
02177
02178
02179 CommandFilePosition = pDC->GetCurrentInstrFilePosition();
02180
02181
02182 LayerNumber = pDC->GetLayerNumber();
02183
02184 return TRUE;
02185 }
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200 BOOL CMXReferLens::WriteSection(CMXExportDC *pDC)
02201 {
02202
02203 LensDescFilePosition = pDC->GetFilePosition();
02204
02205
02206 if(!pDC->StartSection(CMXExportDC::CMXSECTION_LENS))
02207 return FALSE;
02208
02209
02210 cmxLensDescriptionSection len;
02211 len.ParentType = cmxREFLISTEN_TYPE_LAYER;
02212 len.Page = 1;
02213 len.ParentReference = LayerNumber;
02214 len.StartAddress = pDC->GetFirstInstrFilePosition();
02215 len.EndAddress = CommandFilePosition;
02216 pDC->WriteData(&len, sizeof(len));
02217
02218
02219 Matrix *pMat = pDC->GetTransMatrix();
02220 DocRect b = BBox;
02221 pMat->TransformBounds(&b);
02222 if(!pDC->WriteBBox(&b))
02223 return FALSE;
02224
02225
02226 if(!pDC->EndSection())
02227 return FALSE;
02228
02229 return TRUE;
02230 }
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247 BOOL CMXReferLens::WriteInReferenceList(CMXExportDC *pDC)
02248 {
02249 ERROR2IF(pDC == 0, FALSE, "no DC");
02250
02251
02252 cmxRefListEntryRefOffset en;
02253 memset(&en, '\0', sizeof(en));
02254
02255 en.Association = cmxREFLISTEN_DESC_LENS;
02256 en.Type = cmxREFLISTEN_TYPE_INSTRUCTION;
02257 en.Offset = CommandFilePosition;
02258
02259 pDC->WriteData(&en, sizeof(en));
02260
02261 return TRUE;
02262 }
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278 BOOL CMXReferLens::WriteInIndex(CMXExportDC *pDC)
02279 {
02280
02281 cmxProcIndexEntry en;
02282 pDC->WriteSizeInFile(sizeof(en));
02283 en.RefList = -1;
02284 en.Procedure = LensDescFilePosition;
02285
02286 return pDC->WriteData(&en, sizeof(en));
02287 }
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 BOOL CMXReferBitmapFill::WriteInIndex(CMXExportDC *pDC)
02304 {
02305
02306 cmxProcIndexEntry en;
02307 pDC->WriteSizeInFile(sizeof(en));
02308 en.RefList = -1;
02309 en.Procedure = ProcedureFilePosition;
02310
02311 return pDC->WriteData(&en, sizeof(en));
02312 }
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328 BOOL CMXReferBitmap::WriteInIndex(CMXExportDC *pDC)
02329 {
02330 cmxEmbedFileIndexEntry en;
02331 pDC->WriteSizeInFile(sizeof(en));
02332 en.Offset = BitmapFileOffset;
02333 en.Type = cmxEMBEDFILETYPE_RIMAGE;
02334
02335 return pDC->WriteData(&en, sizeof(en));
02336 }
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352 BOOL CMXReferBitmap::WriteSection(CMXExportDC *pDC)
02353 {
02354
02355
02356 KernelBitmap *pBitmap = Ref.GetBitmap();
02357 ERROR2IF(pBitmap == NULL, FALSE, "no bitmap in ref");
02358 OILBitmap *bit = pBitmap->ActualBitmap;
02359 ERROR2IF(bit == NULL, FALSE, "kernel bitmap didn't have a oil bitmap");
02360
02361
02362 BitmapFileOffset = pDC->GetFilePosition();
02363
02364
02365 if(Contone)
02366 {
02367
02368 View *pView = NULL;
02369 if (pDC->GetRenderRegion()!=NULL)
02370 pView=pDC->GetRenderRegion()->GetRenderView();
02371
02372
02373 if (!bit->BuildContonePalette(StartColour, EndColour, Effect, pView))
02374 return FALSE;
02375
02376
02377 pDC->GetRenderRegion()->SetAreExportingContoneBitmap(TRUE);
02378 }
02379 else
02380 {
02381
02382 pDC->GetRenderRegion()->SetAreExportingContoneBitmap(FALSE);
02383 }
02384
02385
02386 if(!bit->ExportBitmap(pDC->GetRenderRegion()))
02387 return FALSE;
02388
02389 if(Contone)
02390 {
02391
02392 bit->DestroyContonePalette();
02393 }
02394
02395 return TRUE;
02396 }
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412 BOOL CMXReferBitmapFill::WriteSection(CMXExportDC *pDC)
02413 {
02414
02415 ProcedureFilePosition = pDC->GetFilePosition();
02416
02417
02418 if(!pDC->StartSection(CMXExportDC::CMXSECTION_PROCBITFILL))
02419 return FALSE;
02420
02421
02422 DocRect bbox = DocRect(0, 0, cmxBITMAPFILLTILESIZE_X, cmxBITMAPFILLTILESIZE_Y);
02423
02424
02425 if(!pDC->StartPage(&bbox, TRUE))
02426 return FALSE;
02427
02428
02429 DocCoord Paral[4] =
02430 { DocCoord(0, cmxBITMAPFILLTILESIZE_Y),
02431 DocCoord(cmxBITMAPFILLTILESIZE_X, cmxBITMAPFILLTILESIZE_Y),
02432 DocCoord(cmxBITMAPFILLTILESIZE_X, 0),
02433 DocCoord(0, 0)
02434 };
02435
02436 if ( !pDC->WriteBitmap ( 0, Paral, CMXExportDC::CMXBITMAPCOLOURSOURCE_NONE,
02437 FALSE, BitmapReference ) )
02438 return FALSE;
02439
02440
02441 if(!pDC->EndPage())
02442 return FALSE;
02443
02444
02445 if(!pDC->EndSection())
02446 return FALSE;
02447
02448 return TRUE;
02449 }
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469 BOOL CMXExportDC::WriteBitmap ( KernelBitmap *pBitmap,
02470 DocCoord *pParallelogram,
02471 CMXBitmapColourSource ColSource,
02472 BOOL TransformParallelogram,
02473 WORD BitmapReference )
02474 {
02475
02476 DocColour *pStartColour = 0;
02477 DocColour *pEndColour = 0;
02478 EFFECTTYPE Effect = EFFECT_RGB;
02479
02480
02481 switch(ColSource)
02482 {
02483 case CMXBITMAPCOLOURSOURCE_FILLGEOMETRY:
02484 ERROR2(FALSE, "fill geometry bitmap colour source not implemented");
02485 break;
02486
02487 case CMXBITMAPCOLOURSOURCE_LINEANDFILL:
02488 {
02489
02490
02491 StrokeColourAttribute *pColA
02492 = (StrokeColourAttribute *)pRenderRegion->GetCurrentAttribute(ATTR_STROKECOLOUR);
02493
02494 ERROR2IF(pColA == 0, FALSE, "No stroke colour attribute");
02495 ERROR3IF(!pColA->IsKindOf(CC_RUNTIME_CLASS(StrokeColourAttribute)), "not a stroke colour attribute");
02496 pStartColour = pColA->GetStartColour();
02497
02498 if(pStartColour != 0 && pStartColour->IsTransparent())
02499 pStartColour = 0;
02500
02501
02502 if(pStartColour != 0)
02503 {
02504
02505 FillGeometryAttribute *pFillGeometry
02506 = (FillGeometryAttribute *)pRenderRegion->GetCurrentAttribute(ATTR_FILLGEOMETRY);
02507
02508 ERROR2IF(pFillGeometry == 0, FALSE, "No fill geometry");
02509 ERROR3IF(!pFillGeometry->IsKindOf(CC_RUNTIME_CLASS(FillGeometryAttribute)), "not one of them there fill geometries");
02510
02511
02512 pEndColour = pFillGeometry->GetStartColour();
02513
02514 if(pEndColour == NULL || pEndColour->IsTransparent())
02515 {
02516
02517 pStartColour = 0;
02518 pEndColour = 0;
02519 }
02520 else
02521 {
02522
02523 Effect = pRenderRegion->GetFillEffect();
02524 }
02525 }
02526 }
02527 break;
02528
02529 default:
02530 case CMXBITMAPCOLOURSOURCE_NONE:
02531 break;
02532 }
02533
02534
02535 WORD BitmapRef = 0;
02536 if(pBitmap == 0)
02537 {
02538 BitmapRef = BitmapReference;
02539 }
02540 else
02541 {
02542 BitmapRef = GetBitmapReference(pBitmap, pStartColour, pEndColour, Effect);
02543 }
02544 if(BitmapRef == 0)
02545 return TRUE;
02546
02547
02548 DocCoord Para[4];
02549 ERROR2IF(pMatrix == NULL, FALSE, "no matrix");
02550 for(INT32 z = 0; z < (sizeof(Para) / sizeof(DocCoord)); z++)
02551 {
02552 Para[z] = pParallelogram[z];
02553 if(TransformParallelogram)
02554 pMatrix->transform(&(Para[z]));
02555 }
02556
02557
02558 if(!StartCommand(cmxINSTR_DrawImage))
02559 return FALSE;
02560
02561
02562 if(!WriteBlankAttributes(cmxTAG_DrawImage_RenderingAttr))
02563 return FALSE;
02564
02565
02566 if(!StartTag(cmxTAG_DrawImage_DrawImageSpecification))
02567 return FALSE;
02568
02569
02570 DocRect ImEx;
02571 if(ThirtyTwoBit)
02572 {
02573 ImEx.lo.x = ImEx.lo.y = 0;
02574 ImEx.hi.x = 2048;
02575 ImEx.hi.y = 2048;
02576 }
02577 else
02578 {
02579 ImEx.lo.x = 0;
02580 ImEx.lo.y = -2048;
02581 ImEx.hi.x = 2048;
02582 ImEx.hi.y = 0;
02583 }
02584 if(!WriteBBox(&ImEx, FALSE) ||
02585 !WriteBBox(&ImEx, FALSE))
02586 return FALSE;
02587
02588
02589 double magX = 2048.0;
02590 double magY = 2048.0;
02591 cmxMatrix Matrix = {cmxMATRIXTYPE_GENERAL,
02592 (double)(Para[2].x - Para[3].x) / magX,
02593 (double)(Para[2].y - Para[3].y) / magY,
02594 (double)(Para[0].x - Para[3].x) / magX,
02595 (double)(Para[0].y - Para[3].y) / magY,
02596 Para[3].x,
02597 Para[3].y};
02598
02599 if(!ThirtyTwoBit)
02600 {
02601
02602 Matrix.f += Matrix.d * 2048;
02603 }
02604
02605
02606 ExportFile->write(&Matrix, sizeof(Matrix));
02607
02608
02609 cmxDrawImageEndBits eb;
02610 eb.ImageType = cmxDRAWIMAGE_IMAGETYPE_COLOUR;
02611 eb.FileRef1 = BitmapRef;
02612 eb.FileRef2 = 0;
02613 if(!WriteData(&eb, sizeof(eb)))
02614 return FALSE;
02615
02616
02617 if(!EndTag())
02618 return FALSE;
02619
02620
02621 if(!WriteMinEndTag()
02622 || !EndCommand())
02623 return FALSE;
02624
02625 return TRUE;
02626 }