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
00104
00105 #include "camtypes.h"
00106
00107 #include "osrndrgn.h"
00108 #include <math.h>
00109
00110
00111
00112
00113
00114 #include "camelot.h"
00115
00116 #include "rendbits.h"
00117 #include "grndrgn.h"
00118
00119
00120 #include "devcolor.h"
00121 #include "oilbitmap.h"
00122
00123
00124
00125
00126 #include "camview.h"
00127
00128
00129 #include "fuzzclip.h"
00130 #include "nodeelip.h"
00131 #include "noderect.h"
00132 #include "princomp.h"
00133 #include "printctl.h"
00134 #include "psrndrgn.h"
00135 #include "palman.h"
00136
00137 #include "maskedrr.h"
00138
00139 #include "textfuns.h"
00140 #include "colcontx.h"
00141
00142 #include "nodebmp.h"
00143 #include "fontman.h"
00144
00145 #include "gradtbl.h"
00146 #include "unicdman.h"
00147 #include "mrhbits.h"
00148 #include "strkattr.h"
00149 #include "cartprov.h"
00150 #include "lineattr.h"
00151
00152 DECLARE_SOURCE("$Revision: 1571 $");
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 static BOOL WantGDIPalette = TRUE;
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 static BOOL WantBetterLines;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static BOOL PrintRotatedTextAsPaths = FALSE;
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215 INT32 OSRenderRegion::HitTestRadius = 3;
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 BOOL BodgeRectangles = FALSE;
00231
00232
00233
00234
00235
00236 EORCacheClass OSRenderRegion::EORCache;
00237
00238 BOOL OSRenderRegion::DoBetterLines;
00239
00240 wxPoint OSRenderRegion::PointArray[SIZEOF_POLYLINE_BUFFER];
00241
00242 static INT32 GradFillQuality = 1;
00243
00244 CC_IMPLEMENT_DYNAMIC(OSRenderRegion, RenderRegion)
00245 CC_IMPLEMENT_DYNAMIC(PaperRenderRegion, OSRenderRegion)
00246
00247 #define new CAM_DEBUG_NEW
00248
00249
00250 OSRRFontInfo::OSRRFontInfo()
00251 {
00252 Rotation = FIXED16(0);
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 BOOL OSRenderRegion::Init()
00271 {
00272 if (Camelot.DeclareSection(TEXT("DisplayKludges"), 10))
00273 {
00274 Camelot.DeclarePref( NULL, TEXT("SlowRectangles"), &BodgeRectangles, FALSE, TRUE );
00275 }
00276
00277 if (Camelot.DeclareSection(TEXT("Printing"), 10))
00278 {
00279 Camelot.DeclarePref( NULL, TEXT("PrintRotatedTextAsShapes"), &PrintRotatedTextAsPaths, FALSE, TRUE );
00280 }
00281
00282 if (Camelot.DeclareSection(TEXT("Screen"), 10))
00283 {
00284 Camelot.DeclarePref(NULL, TEXT("GDIPalette"), &WantGDIPalette, FALSE, TRUE );
00285 Camelot.DeclarePref(NULL, TEXT("BetterLines"), &WantBetterLines, 0, 2 );
00286
00287 switch (WantBetterLines)
00288 {
00289 case 0:
00290 DoBetterLines = TRUE;
00291 break;
00292
00293 case 1:
00294 DoBetterLines = TRUE;
00295 break;
00296
00297 case 2:
00298 DoBetterLines = FALSE;
00299 break;
00300 }
00301 }
00302
00303 if (Camelot.DeclareSection(TEXT("Mouse"), 10))
00304 {
00305 Camelot.DeclarePref(NULL, TEXT("HitTestRadius"), &HitTestRadius, 0, 10);
00306 }
00307
00308 return TRUE;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 RenderRegion* OSRenderRegion::Create(DocRect ClipRect, Matrix ConvertMatrix,
00350 FIXED16 ViewScale, RenderType rType,
00351 View* pView, BOOL UseOSRendering, BOOL bForce32BPP)
00352 {
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 OSRenderRegion *pOS = NULL;
00369
00370 if (rType == RENDERTYPE_MONOBITMAP || rType == RENDERTYPE_COLOURBITMAP || rType == RENDERTYPE_HITDETECT)
00371 {
00372 RenderRegion *pRender = OSRenderBitmap::Create(ClipRect, ConvertMatrix, ViewScale, rType);
00373
00374 if (pRender)
00375 {
00376
00377
00378 if (!pRender->IsKindOf( CC_RUNTIME_CLASS(OSRenderRegion) ))
00379 return pRender;
00380
00381 pOS = (OSRenderRegion*) pRender;
00382 }
00383 }
00384 else if (rType == RENDERTYPE_SCREENPAPER)
00385 {
00386
00387
00388 pOS = new PaperRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00389 }
00390 else if ((rType == RENDERTYPE_PRINTER) || (rType == RENDERTYPE_PRINTER_PS))
00391 {
00392 #ifndef STANDALONE
00393
00394 Document *pDoc = pView->GetDoc();
00395 ERROR3IF(pDoc == NULL, "No document attached to view when printing!");
00396 if (pDoc != NULL)
00397 {
00398
00399 PrintComponent *pPrint =
00400 (PrintComponent *) pDoc->GetDocComponent(CC_RUNTIME_CLASS(PrintComponent));
00401 ERROR2IF(pPrint == NULL, NULL, "Unable to find PrintComponent in document.");
00402
00403 PrintControl *pPrintControl = pPrint->GetPrintControl();
00404 ERROR2IF(pPrintControl == NULL, NULL,
00405 "Unable to find PrintControl object in document component.");
00406
00407 PrintMethodType PrintType = pPrintControl->GetPrintMethod();
00408
00409
00410 if ((PrintType == PRINTMETHOD_AABITMAP) ||
00411 (PrintType == PRINTMETHOD_BITMAP))
00412 {
00413
00414 return GRenderRegion::Create(ClipRect, ConvertMatrix, ViewScale,
00415 rType, pView);
00416 }
00417 }
00418
00419
00420 if (rType == RENDERTYPE_PRINTER_PS)
00421 {
00422
00423 return new PrintPSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00424 }
00425 #endif
00426
00427
00428 return new OSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00429 }
00430 else
00431 {
00432
00433
00434
00435 if ((!UseOSRendering) && (rType != RENDERTYPE_PRINTER))
00436 {
00437 RenderRegion *pRender;
00438 pRender = GRenderRegion::Create(ClipRect, ConvertMatrix, ViewScale, rType, pView, bForce32BPP);
00439 if (pRender)
00440 return pRender;
00441 }
00442
00443
00444
00445 pOS = new OSRenderRegion(ClipRect, ConvertMatrix, ViewScale);
00446 }
00447
00448 if (!pOS)
00449 return NULL;
00450
00451
00452
00453 if (
00454 (rType == RENDERTYPE_METAFILE16) ||
00455 (rType == RENDERTYPE_METAFILE32)
00456 )
00457 pOS -> RFlags.Metafile = TRUE;
00458
00459
00460 if (rType == RENDERTYPE_MONOBITMAP)
00461 {
00462 pOS -> RenderFlags.VeryMono = TRUE;
00463 }
00464
00465 if (rType == RENDERTYPE_HITDETECT)
00466 {
00467 pOS -> RenderFlags.VeryMono = FALSE;
00468 pOS -> RenderFlags.HitDetect = TRUE;
00469 pOS -> m_DoCompression = TRUE;
00470 }
00471
00472 if (rType == RENDERTYPE_COLOURBITMAP)
00473 {
00474 pOS -> RenderFlags.VeryMono = FALSE;
00475 pOS -> m_DoCompression = TRUE;
00476 }
00477
00478 if (
00479 (rType == RENDERTYPE_SCREEN) ||
00480 (rType == RENDERTYPE_SCREENPAPER) ||
00481 (rType == RENDERTYPE_SCREENXOR)
00482 )
00483 {
00484
00485 if (WantGDIPalette && PaletteManager::UsePalette())
00486 pOS->RFlags.UsePalette = TRUE;
00487 }
00488
00489
00490
00491 return pOS;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 OSRenderRegion::OSRenderRegion(DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale)
00514 : RenderRegion(ClipRect, ConvertMatrix, ViewScale)
00515 {
00516 CurrentPen = 0;
00517 CurrentBrush = 0;
00518
00519
00520 OldFont = NULL;
00521 OSClipRegion = NULL;
00522 OldPalette = NULL;
00523 FontInfo.pRenderFont = NULL;
00524 FontInfo.pOldFont = NULL;
00525
00526 RFlags.Metafile = FALSE;
00527
00528 RFlags.ValidPen = FALSE;
00529 RFlags.ValidBrush = FALSE;
00530 RFlags.UsePalette = FALSE;
00531
00532
00533
00534 IsPaperRendered = TRUE;
00535
00536
00537 GetRenderRegionCaps(&Caps);
00538
00539
00540 SepTables = NULL;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 OSRenderRegion::OSRenderRegion(const OSRenderRegion &other)
00558 : RenderRegion(other)
00559 {
00560
00561 CurrentPen = 0;
00562 CurrentBrush = 0;
00563
00564
00565 OldFont = NULL;
00566 OSClipRegion = NULL;
00567 OldPalette = NULL;
00568 FontInfo.pRenderFont = NULL;
00569 FontInfo.pOldFont = NULL;
00570
00571 RFlags = other.RFlags;
00572
00573
00574 GetRenderRegionCaps(&Caps);
00575
00576
00577 SepTables = NULL;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 OSRenderRegion::~OSRenderRegion()
00591 {
00592 if (RenderFlags.Rendering)
00593 {
00594 TRACE( _T("StopRender() was not called before destructor\n") );
00595 StopRender();
00596 }
00597
00598
00599
00600 ENSURE(OSClipRegion == NULL, "Clip Region wasn't deleted");
00601
00602 if (SepTables != NULL)
00603 {
00604 CCFree(SepTables);
00605 SepTables = NULL;
00606 }
00607 }
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 BOOL OSRenderRegion::AttachDevice(View* ViewToAttach, wxDC* DCToAttach, Spread* SpreadToAttach, bool fOwned )
00629 {
00630
00631 if (!RenderRegion::AttachDevice( ViewToAttach, DCToAttach, SpreadToAttach, fOwned ))
00632 return FALSE;
00633
00634 ENSURE(RenderDC != NULL,"Attempted to attach Invalid DC to RenderRegion");
00635
00636 RenderFlags.Printing = CCDC::ConvertFromNativeDC(RenderDC)->IsPrinting();
00637
00638
00639 return TRUE;
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 BOOL OSRenderRegion::InitDevice()
00657 {
00658
00659 if (!RenderRegion::InitDevice())
00660 return FALSE;
00661
00662
00663
00664
00665
00666
00667 if (IsPrinting())
00668 {
00669
00670
00671
00672
00673
00674
00675
00676 }
00677 else
00678 {
00679 GDrawBrush.Init( RenderDC );
00680 }
00681
00682
00683 PrintControl *pPrintControl = RenderView->GetPrintControl();
00684 PrintFillQuality FillQuality;
00685
00686 if (pPrintControl != NULL)
00687 FillQuality = pPrintControl->GetFillQuality();
00688 else
00689 FillQuality = PRINTFILLQUALITY_MEDIUM;
00690
00691 switch (FillQuality)
00692 {
00693 case PRINTFILLQUALITY_LOW:
00694 GradFillQuality = 2;
00695 break;
00696
00697 case PRINTFILLQUALITY_HIGH:
00698 GradFillQuality = 0;
00699 break;
00700
00701 case PRINTFILLQUALITY_MEDIUM:
00702 default:
00703 GradFillQuality = 1;
00704 break;
00705 }
00706
00707
00708
00709 return TRUE;
00710 }
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 void OSRenderRegion::InitClipping()
00727 {
00728
00729
00730
00731
00732
00733
00734 WinRect OSClipRect = DocRectToWin(CurrentClipRect, 0,0,0,0);
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 {
00749 delete OSClipRegion;
00750 OSClipRegion = new wxRegion(OSClipRect);
00751 ENSURE(OSClipRegion != NULL,"'new' failed when creating OSClipRegion");
00752
00753
00754 if (OSClipRegion)
00755 RenderDC->SetClippingRegion(*OSClipRegion);
00756 }
00757 }
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 void OSRenderRegion::DeInitClipping()
00771 {
00772 delete OSClipRegion;
00773 OSClipRegion = NULL;
00774
00775
00776 if (!RFlags.Metafile)
00777 RenderDC->DestroyClippingRegion();
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 void OSRenderRegion::InitAttributes()
00793 {
00794 CurrentPen = 0;
00795 CurrentBrush = 0;
00796
00797
00798 OldFont = NULL;
00799
00800 if (!RFlags.Metafile)
00801 {
00802
00803
00804 PORTNOTE("other","OSRenderRegion::InitAttributes - removed setting of default font");
00805 #if !defined(EXCLUDE_FROM_XARALX)
00806 wxFont* FixedSystemFont = FontFactory::GetCFont(STOCKFONT_RNDRGNFIXEDTEXT);
00807 if (FixedSystemFont != NULL)
00808 OldFont = RenderDC->SetFont(*FixedSystemFont);
00809 #endif
00810 }
00811
00812 SetOSDrawingMode();
00813 SetLineAttributes();
00814 SetFillAttributes();
00815
00816 if (!RFlags.Metafile)
00817 {
00818
00819
00820
00821
00822
00823
00824
00825 DocCoord DocOrigin;
00826 DocOrigin.x = 0;
00827 DocOrigin.y = 0;
00828
00829
00830
00831 WinCoord OSOrigin;
00832 OSOrigin = DocCoordToWin(DocOrigin);
00833
00834
00835
00836
00837 PORTNOTE("other", "Check this");
00838
00839 {
00840 if (RenderView)
00841 {
00842
00843 CCamView* RenderWindow = RenderView->GetConnectionToOilView();
00844 if ( RenderWindow!=NULL && RenderWindow->GetFrame()!=NULL )
00845 RenderWindow->GetFrame()->ClientToScreen(OSOrigin);
00846
00847
00848
00849
00850 }
00851 }
00852
00853
00854
00855 NewBrushOrg.x = OSOrigin.x & 7;
00856 NewBrushOrg.y = OSOrigin.y & 7;
00857 }
00858
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 void OSRenderRegion::DeInitAttributes()
00872 {
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 if (OldFont != NULL)
00889 {
00890 RenderDC->SetFont(*OldFont);
00891 OldFont = NULL;
00892 }
00893
00894
00895 if (FontInfo.pRenderFont != NULL)
00896 {
00897 RenderDC->SetFont(*FontInfo.pOldFont);
00898 FontInfo.pOldFont = NULL;
00899 delete FontInfo.pRenderFont;
00900 FontInfo.pRenderFont = NULL;
00901 }
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 void OSRenderRegion::SetLineAttributes(ChangeLineAttrType Type)
00918 {
00919 RFlags.ValidPen = FALSE;
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 void OSRenderRegion::SetFillAttributes(ChangeAttrType)
00936 {
00937 RFlags.ValidBrush = FALSE;
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 void OSRenderRegion::SetQualityLevel()
00951 {
00952 }
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 wxColour OSRenderRegion::CalcEORColour( DocColour &Wanted, COLORREF Background )
00972 {
00973
00974
00975 INT32 R,G,B;
00976 Wanted.GetRGBValue(&R,&G,&B);
00977 return wxColour(
00978 GetRValue(Background)^R,
00979 GetGValue(Background)^G,
00980 GetBValue(Background)^B
00981 );
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048 }
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065 void OSRenderRegion::FlushEORCache(void)
01066 {
01067 EORCache.Valid = FALSE;
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 void OSRenderRegion::CalcLogBrush(wxBrush* lpBrush, DocColour &Col)
01089 {
01090 if (Col.IsTransparent())
01091 {
01092 lpBrush->SetColour(*wxBLACK);
01093 lpBrush->SetStyle(wxTRANSPARENT);
01094 }
01095 else
01096 {
01097
01098 if (RenderFlags.VeryMono)
01099
01100 if (RRQuality.GetFillQuality() <= Quality::NoFill)
01101 {
01102 lpBrush->SetColour(*wxBLACK);
01103 lpBrush->SetStyle(wxTRANSPARENT);
01104 }
01105 else
01106 {
01107 lpBrush->SetStyle(wxSOLID);
01108 lpBrush->SetColour(*wxBLACK);
01109 }
01110 else if (DrawingMode != DM_EORPEN)
01111 {
01112 if (GDrawBrush.Available())
01113 GDrawBrush.GetLogBrush( CurrentColContext, Col, lpBrush );
01114 else
01115 {
01116 INT32 R,G,B;
01117 Col.GetRGBValue(&R, &G, &B);
01118 lpBrush->SetStyle(wxSOLID);
01119 lpBrush->SetColour(R, G, B);
01120 }
01121 }
01122 else
01123 {
01124 lpBrush->SetStyle(wxSOLID);
01125 lpBrush->SetColour(CalcEORColour(Col));
01126 }
01127 }
01128 }
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 void OSRenderRegion::CreateNewPen()
01142 {
01143
01144 BOOL EmptyPen = RR_STROKECOLOUR().IsTransparent();
01145 const enum Quality::Line LineQuality = RRQuality.GetLineQuality();
01146
01147
01148 if ( RRQuality.GetFillQuality() <= Quality::NoFill )
01149 EmptyPen = FALSE;
01150
01151 if (
01152
01153 !RenderFlags.VeryMono &&
01154 !RenderFlags.bImmediateRender &&
01155 (LineQuality >= Quality::FullLine) &&
01156 !EmptyPen
01157 )
01158 {
01159
01160
01161
01162 INT32 PenWidth = MPtoLP(RR_LINEWIDTH());
01163 if (IsPrinting())
01164 {
01165
01166 if (PenWidth < 2)
01167 PenWidth = 2;
01168 }
01169
01170 INT32 R,G,B;
01171 RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
01172 RenderPen[CurrentPen] = wxPen(wxColour(R,G,B), PenWidth, wxSOLID);
01173
01174
01175 switch (RR_STARTCAP())
01176 {
01177 case LineCapRound:
01178 RenderPen[CurrentPen].SetCap(wxCAP_ROUND);
01179 break;
01180
01181 case LineCapSquare:
01182 RenderPen[CurrentPen].SetCap(wxCAP_PROJECTING);
01183 break;
01184
01185 case LineCapButt:
01186 RenderPen[CurrentPen].SetCap(wxCAP_BUTT);
01187 break;
01188
01189 default:
01190 ENSURE(FALSE, "Bad startcap");
01191 break;
01192 }
01193 switch (RR_JOINTYPE())
01194 {
01195 case BevelledJoin:
01196 RenderPen[CurrentPen].SetJoin(wxJOIN_BEVEL);
01197 break;
01198
01199 case MitreJoin:
01200 RenderPen[CurrentPen].SetJoin(wxJOIN_MITER);
01201 break;
01202
01203 case RoundJoin:
01204 RenderPen[CurrentPen].SetJoin(wxJOIN_ROUND);
01205 break;
01206
01207 default:
01208 ENSURE(FALSE, "bad jointype");
01209 break;
01210 }
01211 return ;
01212 }
01213
01214
01215
01216 if (EmptyPen)
01217 RenderPen[CurrentPen] = wxPen(*wxTRANSPARENT_PEN);
01218 else
01219 {
01220 INT32 PenWidth = MPtoLP(RR_LINEWIDTH());
01221
01222 if (RR_LINEWIDTH()==0 || LineQuality < Quality::FullLine)
01223 PenWidth = 0;
01224 else
01225 {
01226 MILLIPOINT LineWidth = RR_LINEWIDTH();
01227 if ((RenderFlags.VeryMono || RenderFlags.HitDetect) && LineWidth < GetScaledPixelWidth())
01228 PenWidth = MPtoLP(GetScaledPixelWidth());
01229 }
01230
01231 wxColour Colour(0,0,0);
01232 if (RenderFlags.VeryMono || LineQuality < Quality::ThinLine)
01233 Colour = *wxBLACK;
01234 else if (DrawingMode==DM_EORPEN)
01235 Colour = CalcEORColour(RR_STROKECOLOUR());
01236 else
01237 {
01238 INT32 R,G,B;
01239 RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
01240 Colour = wxColour(R, G, B);
01241 }
01242
01243 RenderPen[CurrentPen] = wxPen(Colour, PenWidth, wxSOLID);
01244 }
01245 }
01246
01247 void OSRenderRegion::SelectNewPen()
01248 {
01249
01250 CurrentPen = 1 - CurrentPen;
01251
01252
01253 CreateNewPen();
01254
01255 RenderDC->SetPen(RenderPen[CurrentPen]);
01256
01257 RFlags.ValidPen = TRUE;
01258 }
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272 void OSRenderRegion::CreateNewBrush()
01273 {
01274 if (RRQuality.GetFillQuality() <= Quality::NoFill )
01275 {
01276 RenderBrush[CurrentBrush].SetColour(*wxBLACK);
01277 RenderBrush[CurrentBrush].SetStyle(wxTRANSPARENT);
01278 }
01279 else
01280 CalcLogBrush( &RenderBrush[CurrentBrush], RR_FILLCOLOUR() );
01281 }
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 void OSRenderRegion::SelectNewBrush()
01296 {
01297
01298 CurrentBrush = 1 - CurrentBrush;
01299
01300
01301 CreateNewBrush();
01302
01303
01304 if (!RFlags.Metafile)
01305 {
01306
01307
01308 PORTNOTE("other","OSRenderRegion::SelectNewBrush - removed setting of brush origin");
01309 #if !defined(EXCLUDE_FROM_XARALX)
01310 RenderDC->SetBrushOrg(NewBrushOrg);
01311 #endif
01312 }
01313
01314
01315 RenderDC->SetBrush(RenderBrush[CurrentBrush]);
01316
01317
01318 if (RR_WINDINGRULE() == EvenOddWinding)
01319 nFillStyle = wxODDEVEN_RULE;
01320 else
01321 nFillStyle = wxWINDING_RULE;
01322
01323
01324 RFlags.ValidBrush = TRUE;
01325 }
01326
01327
01328 void OSRenderRegion::GetValidPen()
01329 {
01330 if (!RFlags.ValidPen)
01331 SelectNewPen();
01332 }
01333
01334 void OSRenderRegion::GetValidBrush()
01335 {
01336 if (!RFlags.ValidBrush)
01337 SelectNewBrush();
01338 }
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359 BOOL OSRenderRegion::SelectNewFont(WORD Typeface, BOOL Bold, BOOL Italic,
01360 MILLIPOINT Width, MILLIPOINT Height, ANGLE Rotation)
01361 {
01362 PORTNOTETRACE("text","OSRenderRegion::SelectNewFont - do nothing");
01363 #ifndef EXCLUDE_FROM_XARALX
01364
01365 if ((FontInfo.pRenderFont != NULL) &&
01366 (FontInfo.Typeface == Typeface) &&
01367 (FontInfo.Bold == Bold) &&
01368 (FontInfo.Italic == Italic) &&
01369 (FontInfo.Width == Width) &&
01370 (FontInfo.Height == Height) &&
01371 (FontInfo.Rotation == Rotation))
01372 {
01373
01374 TRACEUSER( "Tim", _T("Using the cached font\n"));
01375 return TRUE;
01376 }
01377
01378
01379 if (Rotation != FIXED16(0))
01380 {
01381
01382
01383
01384
01385
01386
01387
01388
01389 if (PrintRotatedTextAsPaths)
01390 return FALSE;
01391 }
01392
01393 TRACEUSER( "Tim", _T("Font cache invalid - generating font to use\n"));
01394
01395
01396 if (FontInfo.pOldFont != NULL)
01397 {
01398 RenderDC->SelectObject(FontInfo.pOldFont);
01399 FontInfo.pOldFont = NULL;
01400 }
01401
01402 if (FontInfo.pRenderFont != NULL)
01403 {
01404 delete FontInfo.pRenderFont;
01405 FontInfo.pRenderFont = NULL;
01406 }
01407
01408
01409 ENUMLOGFONT *pEnumLogFont = FONTMANAGER->GetEnumLogFont(Typeface);
01410 if (pEnumLogFont == NULL)
01411
01412 return FALSE;
01413
01414
01415 TRY
01416 {
01417 FontInfo.pRenderFont = new wxFont;
01418 }
01419 CATCH (CMemoryException, e)
01420 {
01421 return FALSE;
01422 }
01423 END_CATCH
01424
01425
01426 INT32 FontWeight = Bold ? FW_BOLD : FW_NORMAL;
01427
01428
01429
01430 FIXED16 fxPixWidth = 0;
01431 FIXED16 fxPixHeight = 0;
01432
01433
01434
01435
01436
01437
01438
01439
01440 RenderView->GetScaledPixelSize(&fxPixWidth, &fxPixHeight);
01441
01442
01443 INT32 FontWidth = (INT32) (Width / fxPixWidth.MakeDouble());
01444 INT32 FontHeight = (INT32) (Height / fxPixHeight.MakeDouble());
01445
01446 if (FontHeight == FontWidth)
01447 {
01448
01449
01450 FontWidth = 0;
01451 }
01452 else
01453 {
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 if (FontInfo.pRenderFont->CreateFont(-100, 0, 0, 0, FontWeight, Italic,
01478 FALSE, FALSE, DEFAULT_CHARSET,
01479 OUT_TT_PRECIS, CLIP_TT_ALWAYS,
01480 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
01481 pEnumLogFont->elfLogFont.lfFaceName) == 0)
01482 {
01483
01484 delete FontInfo.pRenderFont;
01485 FontInfo.pRenderFont = NULL;
01486 return FALSE;
01487 }
01488
01489
01490 TEXTMETRIC Metrics;
01491
01492 if (TRUE)
01493 {
01494
01495 wxDC* pDesktopDC = CWnd::GetDesktopWindow()->GetDC();
01496
01497
01498 FontInfo.pOldFont = pDesktopDC->SetFont(FontInfo.pRenderFont);
01499 pDesktopDC->GetTextMetrics(&Metrics);
01500
01501
01502 pDesktopDC->SetFont(FontInfo.pOldFont);
01503 CWnd::GetDesktopWindow()->ReleaseDC(pDesktopDC);
01504 }
01505 else
01506 {
01507
01508
01509 FontInfo.pOldFont = RenderDC->SelectObject(FontInfo.pRenderFont);
01510
01511
01512 RenderDC->GetTextMetrics(&Metrics);
01513
01514
01515 RenderDC->SelectObject(FontInfo.pOldFont);
01516 }
01517
01518
01519
01520 FontWidth = MulDiv(Metrics.tmAveCharWidth, FontWidth, 100);
01521
01522
01523 delete FontInfo.pRenderFont;
01524
01525
01526 TRY
01527 {
01528 FontInfo.pRenderFont = new CFont;
01529 }
01530 CATCH (CMemoryException, e)
01531 {
01532 return FALSE;
01533 }
01534 END_CATCH
01535 }
01536
01537
01538 INT32 lfRotation;
01539 if (Rotation == FIXED16(0))
01540 lfRotation = 0;
01541 else
01542 lfRotation = (INT32) ( (Rotation.MakeDouble() * 360.0 * 10.0) / (2 * PI) );
01543
01544
01545 if (FontInfo.pRenderFont->CreateFont(-FontHeight, FontWidth, lfRotation, 0, FontWeight, Italic,
01546 FALSE, FALSE, DEFAULT_CHARSET,
01547 OUT_TT_PRECIS, CLIP_TT_ALWAYS,
01548 PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
01549 pEnumLogFont->elfLogFont.lfFaceName) == 0)
01550 {
01551
01552
01553 delete FontInfo.pRenderFont;
01554 FontInfo.pRenderFont = NULL;
01555 return FALSE;
01556 }
01557
01558
01559 FontInfo.pOldFont = RenderDC->SetFont(FontInfo.pRenderFont);
01560
01561
01562 FontInfo.Typeface = Typeface;
01563 FontInfo.Bold = Bold;
01564 FontInfo.Italic = Italic;
01565 FontInfo.Width = Width;
01566 FontInfo.Height = Height;
01567 FontInfo.Rotation = Rotation;
01568 #endif
01569
01570 return TRUE;
01571 }
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584 void OSRenderRegion::SetOSDrawingMode()
01585 {
01586
01587 switch (DrawingMode)
01588 {
01589 case DM_COPYPEN:
01590 if (!RenderDC->IsKindOf(CLASSINFO(wxPostScriptDC)))
01591 RenderDC->SetLogicalFunction(wxCOPY);
01592 break;
01593 case DM_EORPEN:
01594 case DM_EORDITHER:
01595
01596
01597
01598
01599 RenderDC->SetLogicalFunction(wxXOR);
01600 break;
01601
01602 default:
01603 ERROR3("Bad drawing mode in OSRenderRegion::SetOSDrawingMode()");
01604 }
01605
01606
01607
01608
01609 SetLineAttributes();
01610 SetFillAttributes();
01611 }
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 BOOL OSRenderRegion::StartRender()
01625 {
01626
01627 if (!RenderRegion::StartRender())
01628 return FALSE;
01629
01630 ENSURE(RenderDC != NULL,"StartRender Called when DC was Invalid");
01631
01632
01633 ENSURE(RenderFlags.Rendering == FALSE, "Initialise called whilst already rendering");
01634 TRACEUSER("Gavin",_T("OSRenderRegion::StartRender - RenderFlags.Rendering = TRUE;\n"));
01635 RenderFlags.Rendering = TRUE;
01636
01637 PixelScale = RenderView->GetPixelWidth();
01638
01639 InitClipping();
01640 InitAttributes();
01641
01642 if (RFlags.UsePalette)
01643 OldPalette = PaletteManager::StartPaintPalette(RenderDC);
01644
01645 GDrawBrush.Start();
01646
01647 #if defined(_DEBUG) && defined(__WXMSW__)
01648
01649
01650 GdiSetBatchLimit(1);
01651 #endif
01652
01653 return TRUE;
01654 }
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672 BOOL OSRenderRegion::StopRender()
01673 {
01674
01675
01676 #if 0
01677 {
01678 TRACE( _T("OSRR# DebugClipRect = (%d, %d) - (%d, %d)\n"), CurrentClipRect.lo.x, CurrentClipRect.lo.y, CurrentClipRect.hi.x, CurrentClipRect.hi.y);
01679 DocRect TempRect(CurrentClipRect);
01680 TempRect.Inflate(-GetScaledPixelWidth());
01681 TRACE( _T("OSRR# Filling = (%d, %d) - (%d, %d)\n"), TempRect.lo.x, TempRect.lo.y, TempRect.hi.x, TempRect.hi.y);
01682 Path ClipPath;
01683 ClipPath.Initialise();
01684 ClipPath.CreatePathFromDocRect(&TempRect);
01685
01686 SaveContext();
01687 SetLineColour(COLOUR_TRANS);
01688 SetFillColour(COLOUR_RED);
01689 DrawPath(&ClipPath);
01690 RestoreContext();
01691 }
01692 #endif
01693 #if 0
01694 {
01695 SaveContext();
01696 SetLineColour(COLOUR_TRANS);
01697 SetFillColour(COLOUR_BLUE);
01698
01699 DocRect SmallRect(750, 750, 1500, 1500);
01700 Path ThePath;
01701 ThePath.Initialise();
01702 ThePath.CreatePathFromDocRect(&SmallRect);
01703
01704 DrawPath(&ThePath);
01705 ThePath.Translate(50, 1500);
01706 DrawPath(&ThePath);
01707 ThePath.Translate(50, 1500);
01708 DrawPath(&ThePath);
01709 ThePath.Translate(50, 1500);
01710 DrawPath(&ThePath);
01711 ThePath.Translate(50, 1500);
01712 DrawPath(&ThePath);
01713 ThePath.Translate(50, 1500);
01714 DrawPath(&ThePath);
01715 ThePath.Translate(50, 1500);
01716 DrawPath(&ThePath);
01717 ThePath.Translate(50, 1500);
01718 DrawPath(&ThePath);
01719 ThePath.Translate(50, 1500);
01720 DrawPath(&ThePath);
01721 ThePath.Translate(50, 1500);
01722 DrawPath(&ThePath);
01723 ThePath.Translate(50, 1500);
01724 DrawPath(&ThePath);
01725 ThePath.Translate(50, 1500);
01726 DrawPath(&ThePath);
01727 ThePath.Translate(50, 1500);
01728 DrawPath(&ThePath);
01729 ThePath.Translate(50, 1500);
01730 DrawPath(&ThePath);
01731 ThePath.Translate(50, 1500);
01732 DrawPath(&ThePath);
01733 ThePath.Translate(50, 1500);
01734 DrawPath(&ThePath);
01735
01736 RestoreContext();
01737 }
01738 #endif
01739
01740
01741
01742 ENSURE(RenderFlags.Rendering, "DeInitialise called before Initialise");
01743
01744 DeInitClipping();
01745 DeInitAttributes();
01746
01747 if (OldPalette)
01748 {
01749 PaletteManager::StopPaintPalette(RenderDC, OldPalette);
01750 OldPalette = NULL;
01751 }
01752
01753
01754 InnerRect.MakeEmpty();
01755 OuterRect.MakeEmpty();
01756
01757 TRACEUSER("Gavin",_T("OSRenderRegion::StopRender - RenderFlags.Rendering = FALSE;\n"));
01758 RenderFlags.Rendering = FALSE;
01759
01760 GDrawBrush.Stop();
01761
01762 if (SepTables != NULL)
01763 {
01764 CCFree(SepTables);
01765 SepTables = NULL;
01766 }
01767
01768 return TRUE;
01769 }
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788 void OSRenderRegion::SetSolidColours(BOOL SetSolid)
01789 {
01790 if (GDrawBrush.Available())
01791 GDrawBrush.SetSolidColours(SetSolid);
01792 }
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808 void OSRenderRegion::DrawPathToOutputDevice(Path* PathToDraw, PathShape)
01809 {
01810
01811 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
01812 return;
01813
01814
01815 GetValidPen();
01816 GetValidBrush();
01817
01818
01819 RenderPath(PathToDraw);
01820
01821
01822 DrawPathArrowHeads(NORMALPATH(PathToDraw));
01823 }
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871 void OSRenderRegion::DrawRect(DocRect* RectToRend)
01872 {
01873
01874 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
01875 return;
01876
01877 GetValidPen();
01878 GetValidBrush();
01879
01880
01881
01882
01883
01884
01885
01886 if (!RectToRend->IsIntersectedWith(CurrentClipRect))
01887 return;
01888
01889
01890 DocRect DrawRect = RectToRend->Intersection(InnerRect);
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900 WinRect Rect;
01901
01902
01903
01904
01905
01906
01907 Rect = DocRectToWin(DrawRect, 0,0,0,0, TRUE);
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927 RenderDC->DrawRectangle(Rect);
01928
01929 }
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 void OSRenderRegion::DrawDragRect(DocRect* RectToDraw)
01945 {
01946 GetValidPen();
01947 GetValidBrush();
01948
01949
01950
01951
01952
01953
01954 WinRect Rect = DocRectToWin(*RectToDraw, 0,0,0,0);
01955
01956
01957
01958
01959
01960 if ( DrawingMode != DM_EORPEN ||
01961 (
01962 Rect.width !=1 &&
01963 Rect.height!=1
01964 ) )
01965 RenderDC->DrawRectangle(Rect);
01966 }
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998 void OSRenderRegion::DrawDragBounds(DocRect *RectToRender)
01999 {
02000 INT32 OurOldBkMode = RenderDC->GetBackgroundMode() ;
02001 INT32 OurOldDrawingMode = RenderDC->GetLogicalFunction();
02002 wxPen OurOldPen = RenderDC->GetPen() ;
02003
02004 wxPen DotPen(CalcEORColour(RR_STROKECOLOUR()),1,wxDOT);
02005 RenderDC->SetPen(DotPen);
02006 RenderDC->SetBackgroundMode(wxTRANSPARENT);
02007 RenderDC->SetLogicalFunction(wxXOR);
02008
02009
02010
02011 WinCoord Points[5];
02012 Points[0] =
02013 Points[4] = DocCoordToWin(RectToRender->lo);
02014 Points[1] = DocCoordToWin(DocCoord(RectToRender->lo.x, RectToRender->hi.y));
02015 Points[2] = DocCoordToWin(RectToRender->hi);
02016 Points[3] = DocCoordToWin(DocCoord(RectToRender->hi.x, RectToRender->lo.y));
02017
02018
02019 RenderDC->DrawLines(5,Points);
02020
02021
02022 RenderDC->SetLogicalFunction(OurOldDrawingMode);
02023 RenderDC->SetBackgroundMode(OurOldBkMode);
02024 RenderDC->SetPen(OurOldPen);
02025 }
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042 void OSRenderRegion::DrawDashLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
02043 {
02044 INT32 OurOldBkMode = RenderDC->GetBackgroundMode() ;
02045 INT32 OurOldDrawingMode = RenderDC->GetLogicalFunction();
02046 wxPen OurOldPen = RenderDC->GetPen() ;
02047
02048 wxPen DotPen(CalcEORColour(RR_STROKECOLOUR()),1,wxDOT);
02049 RenderDC->SetPen(DotPen);
02050 RenderDC->SetBackgroundMode(wxTRANSPARENT);
02051 RenderDC->SetLogicalFunction(wxXOR);
02052
02053
02054 WinCoord StartPt = DocCoordToWin(StartPoint);
02055 WinCoord EndPt = DocCoordToWin(EndPoint );
02056 RenderDC->DrawLine(StartPt,EndPt);
02057
02058
02059 RenderDC->SetLogicalFunction(OurOldDrawingMode);
02060 RenderDC->SetBackgroundMode(OurOldBkMode);
02061 RenderDC->SetPen(OurOldPen);
02062 }
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077 void OSRenderRegion::DrawLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
02078 {
02079
02080 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
02081 return;
02082
02083 GetValidPen();
02084 GetValidBrush();
02085
02086 const UINT32 LINEVERTICES = 2;
02087 wxPoint LinePoints[LINEVERTICES];
02088 LinePoints[0] = DocCoordToWin(StartPoint);
02089 LinePoints[1] = DocCoordToWin(EndPoint);
02090
02091 RenderDC->DrawLine(LinePoints[0],LinePoints[1]);
02092 #if 0
02093 if (!StartArrow.IsNull)
02094 DrawLineArrow(StartArrow, StartPoint, EndPoint);
02095
02096 if (!EndArrow.IsNull)
02097 DrawLineArrow(EndArrow, EndPoint, StartPoint);
02098 #endif
02099 }
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112 void OSRenderRegion::DrawPixel(const DocCoord &Point)
02113 {
02114 wxPoint LinePoint = DocCoordToWin(Point);
02115
02116
02117 INT32 R,G,B;
02118 RR_STROKECOLOUR().GetRGBValue(&R,&G,&B);
02119 RenderDC->SetPen(wxColour(R,G,B));
02120 RenderDC->DrawPoint(LinePoint);
02121 }
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 void OSRenderRegion::DrawCross(const DocCoord &Point, const UINT32 Size)
02138 {
02139 GetValidPen();
02140
02141 const MILLIPOINT Length = Size * ScaledPixelWidth;
02142
02143
02144 DocCoord Coords[3];
02145 Coords[0] = Point;
02146
02147 Coords[1].x = Point.x - Length;
02148 Coords[1].y = Point.y - Length;
02149
02150 Coords[2].x = Point.x + Length + ScaledPixelWidth;
02151 Coords[2].y = Point.y + Length + ScaledPixelWidth;
02152
02153
02154 wxPoint Points[3];
02155 Points[0] = DocCoordToWin(Coords[0]);
02156 Points[1] = DocCoordToWin(Coords[1]);
02157 Points[2] = DocCoordToWin(Coords[2]);
02158
02159
02160 RenderDC->DrawLine(Points[1].x,Points[0].y,Points[2].x,Points[0].y);
02161
02162 RenderDC->DrawLine(Points[0].x,Points[1].y,Points[0].x,Points[2].y);
02163 }
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196 void OSRenderRegion::DrawFixedSystemText(StringBase *TheText, DocRect &BoundsRect, UINT32 uFormat )
02197 {
02198 wxString Text = (wxString)(TCHAR *)(*TheText);
02199 wxRect Rect(0,0,0,0);
02200
02201 wxFont SaveFont=RenderDC->GetFont();
02202
02203 wxFont FixedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
02204 FixedFont.SetPointSize(8);
02205 RenderDC->SetFont(FixedFont);
02206
02207 wxDC * pDC = RenderDC;
02208 wxSize DPI = GetFixedDCPPI(*pDC);
02209 INT32 XDPI = DPI.GetWidth();
02210 INT32 YDPI = DPI.GetHeight();
02211 INT32 LineHeight = RenderDC->GetCharHeight();
02212
02213 if (uFormat & FORMAT_CALCRECT)
02214 {
02215
02216
02217 wxCoord w, h;
02218 RenderDC->GetTextExtent(Text, &w, &h);
02219 Rect = wxRect(0, 0, w, h);
02220
02221
02222 if(XDPI == 0 || YDPI == 0 || LineHeight == 0)
02223 {
02224 ERROR3("Can not calculate text size");
02225 BoundsRect = DocRect(0, 0, 0, 0);
02226 RenderDC->SetFont(SaveFont);
02227 return;
02228 }
02229
02230
02231 BoundsRect = DocRect(0, 0,
02232 (INT32)(((double)Rect.width * IN_MP_VAL) / XDPI),
02233 (INT32)(((double)LineHeight * IN_MP_VAL) / YDPI) );
02234 RenderDC->SetFont(SaveFont);
02235 return;
02236 }
02237
02238
02239
02240 DocRect brect=BoundsRect;
02241
02242 brect.hi.y -= ((brect.hi.y-brect.lo.y)-(INT32)(((double)LineHeight * IN_MP_VAL) / YDPI))/2;
02243
02244 Rect = DocRectToWin(brect, 0,0,0,0, TRUE);
02245
02246
02247
02248
02249
02250 if (Rect.width>0)
02251 {
02252
02253
02254
02255 wxBrush SaveBrush=RenderDC->GetBrush();
02256 INT32 SaveBackgroundMode=RenderDC->GetBackgroundMode();
02257
02258
02259 RenderDC->SetBackgroundMode(wxTRANSPARENT);
02260 RenderDC->DrawText(Text, Rect.GetLeft(), Rect.GetTop());
02261
02262
02263
02264
02265
02266 RenderDC->SetBackgroundMode(SaveBackgroundMode);
02267 RenderDC->SetBrush(*wxTRANSPARENT_BRUSH);
02268 RenderDC->SetBrush(wxNullBrush);
02269 RenderDC->SetBrush(SaveBrush);
02270
02271
02272
02273
02274 }
02275
02276 RenderDC->SetFont(SaveFont);
02277 }
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317 void OSRenderRegion::SetFixedSystemTextColours(DocColour *TextCol, DocColour *Background)
02318 {
02319 if (TextCol != NULL)
02320 {
02321 COLORREF Clr = ConvertColourToScreenWord(CurrentColContext, TextCol);
02322 RenderDC->SetTextForeground(Clr);
02323 }
02324
02325 if (Background != NULL)
02326 {
02327 COLORREF Clr = ConvertColourToScreenWord(CurrentColContext, Background);
02328 RenderDC->SetTextBackground(Clr);
02329 }
02330 }
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359 void OSRenderRegion::GetFixedSystemTextSize(StringBase *TheText, DocRect *BoundsRect, double* atDpi)
02360 {
02361 wxString Text = (wxString)(TCHAR *)(*TheText);
02362
02363 ERROR3IF(TheText == NULL, "OSRenderRegion::GetFixedSystemTextSize given a null text pointer");
02364 ERROR3IF(BoundsRect == NULL, "OSRenderRegion::GetFixedSystemTextSize given a null bounds rect pointer");
02365 if(TheText == NULL || BoundsRect == NULL)
02366 return;
02367
02368 wxFont SaveFont=RenderDC->GetFont();
02369
02370 wxFont FixedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
02371 FixedFont.SetPointSize(8);
02372 RenderDC->SetFont(FixedFont);
02373
02374 INT32 LineHeight = 0;
02375
02376
02377 LineHeight = RenderDC->GetCharHeight();
02378 wxCoord w, h;
02379 RenderDC->GetTextExtent(Text, &w, &h);
02380 wxRect Rect(0, 0, w, h);
02381
02382 RenderDC->SetFont(SaveFont);
02383
02384 wxDC * pDC = RenderDC;
02385 wxSize DPI = GetFixedDCPPI(*pDC);
02386 INT32 XDPI = DPI.GetWidth();
02387 INT32 YDPI = DPI.GetHeight();
02388
02389 if(XDPI == 0 || YDPI == 0 || LineHeight == 0)
02390 {
02391 ERROR3("Can not calculate text size");
02392 *BoundsRect = DocRect(0, 0, 0, 0);
02393 return;
02394 }
02395
02396
02397 *BoundsRect = DocRect(0, 0,
02398 (INT32)(((double)Rect.width * IN_MP_VAL) / XDPI),
02399 (INT32)(((double)LineHeight * IN_MP_VAL) / YDPI) );
02400 return;
02401
02402 }
02403
02404
02405
02406 #define MAX_POLYGONS 256
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438 INT32 OSRenderRegion::RawRenderPath( DocCoord *const Coords, PathVerb *const Verbs, INT32 NumCoords,
02439 INT32 *PolyCounts, INT32 *ResCount,
02440 INT32 Flatness, INT32 *pActualFlatness )
02441 {
02442
02443 if (Flatness < 0)
02444 return 0;
02445
02446
02447 INT32 MaxFlatness;
02448
02449
02450 if (Flatness == 0)
02451 {
02452
02453 if (RFlags.Metafile)
02454 {
02455 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
02456
02457 if (RenderView->IS_KIND_OF(MetafileView))
02458 Flatness = ((MetafileView*)RenderView)->GetMetafileFlatness();
02459 else
02460 #endif
02461 Flatness = 512;
02462 }
02463 else
02464 {
02465 Flatness = CalcPathFlattening();
02466 }
02467 }
02468
02469 MaxFlatness = Flatness * 8;
02470
02471
02472 INT32 Count = 0;
02473
02474
02475 INT32 PointsSoFar = 0;
02476
02477
02478 INT32 ReadPos = 0;
02479
02480
02481 BOOL Worked = FALSE;
02482 while (!Worked && (Flatness <= MaxFlatness) &&(Flatness > 0))
02483 {
02484
02485 InsertPos = 0;
02486
02487 ReadPos = 0;
02488 Count = 0;
02489 PointsSoFar = 0;
02490
02491 Worked = TRUE;
02492 BOOL KeepGoing = TRUE;
02493
02494
02495 while (
02496 KeepGoing &&
02497 (ReadPos < NumCoords) &&
02498 Worked
02499 )
02500 {
02501 if ( InsertPos >= SIZEOF_POLYLINE_BUFFER )
02502 {
02503
02504
02505
02506 TRACE( _T("Path too complex to flatten\n"));
02507 InsertPos = 0;
02508 Worked = FALSE;
02509 break;
02510 }
02511
02512
02513 Coord P[4];
02514 INT32 OldInsertPos;
02515
02516 switch ( (Verbs[ReadPos]) & (~PT_CLOSEFIGURE) )
02517 {
02518 case PT_MOVETO:
02519
02520 if (InsertPos>0)
02521 {
02522
02523 PolyCounts[Count] = InsertPos - PointsSoFar;
02524
02525
02526 PointsSoFar = InsertPos;
02527
02528
02529 Count++;
02530
02531
02532 if (Count == MAX_POLYGONS)
02533 {
02534 TRACE( _T("Too many polygons in path to render\n") );
02535 InsertPos = 0;
02536 Worked = FALSE;
02537 break;
02538 }
02539
02540 if (ResCount==NULL)
02541 {
02542
02543 KeepGoing = FALSE;
02544 break;
02545 }
02546 }
02547
02548
02549 PointArray[InsertPos] = DocCoordToWin(Coords[ReadPos]);
02550 InsertPos++;
02551 ReadPos++;
02552 break;
02553
02554
02555 case PT_LINETO:
02556
02557 PointArray[InsertPos] = DocCoordToWin(Coords[ReadPos]);
02558 InsertPos++;
02559 ReadPos++;
02560 break;
02561
02562
02563 case PT_BEZIERTO:
02564
02565 ENSURE((Verbs[ReadPos+1]) & (~PT_CLOSEFIGURE), "Bezier found with 1 point");
02566 ENSURE((Verbs[ReadPos+2]) & (~PT_CLOSEFIGURE), "Bezier found with 2 points");
02567
02568
02569 ENSURE(ReadPos>0, "Broken path found while flattening" );
02570 OldInsertPos = InsertPos;
02571
02572
02573 P[0] = DocCoordToOS256(Coords[ReadPos-1]);
02574 P[1] = DocCoordToOS256(Coords[ReadPos]);
02575 P[2] = DocCoordToOS256(Coords[ReadPos+1]);
02576 P[3] = DocCoordToOS256(Coords[ReadPos+2]);
02577
02578 if (!Bezier(P[0].x,P[0].y, P[1].x,P[1].y, P[2].x,P[2].y, P[3].x,P[3].y, Flatness))
02579 {
02580
02581 Worked = FALSE;
02582 break;
02583 }
02584
02585
02586
02587 if (InsertPos == OldInsertPos+1)
02588 {
02589 if (Coords[ReadPos-1].x == Coords[ReadPos+2].x)
02590 PointArray[OldInsertPos].x = PointArray[OldInsertPos-1].x;
02591 if (Coords[ReadPos-1].y == Coords[ReadPos+2].y)
02592 PointArray[OldInsertPos].y = PointArray[OldInsertPos-1].y;
02593 }
02594
02595
02596
02597
02598 ReadPos+=3;
02599 break;
02600
02601 default:
02602 ENSURE( FALSE, "We found a Path Element that does not exist!" );
02603 break;
02604 }
02605
02606 if (ResCount==NULL)
02607 {
02608
02609 if (Verbs[ReadPos-1] & PT_CLOSEFIGURE)
02610 KeepGoing = FALSE;
02611 }
02612 }
02613
02614
02615 Flatness *= 2;
02616 }
02617
02618 if (!Worked)
02619 {
02620
02621 }
02622
02623 else if (InsertPos>0)
02624 {
02625 PolyCounts[Count] = InsertPos - PointsSoFar;
02626 Count++;
02627
02628 if (ResCount)
02629 *ResCount = Count;
02630 }
02631 else
02632 {
02633 if (ResCount)
02634 *ResCount = 0;
02635 else
02636 {
02637 ENSURE(FALSE, "strange short path");
02638 Worked = FALSE;
02639 }
02640 }
02641
02642
02643 if (pActualFlatness != NULL)
02644 *pActualFlatness = Flatness;
02645
02646
02647 return Worked ? ReadPos : 0;
02648 }
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 BOOL OSRenderRegion::SetClipToPathTemporary( Path *const PathToDraw)
02667 {
02668 PORTNOTETRACE("other","OSRenderRegion::SetClipToPathTemporary - do nothing");
02669 #ifndef EXCLUDE_FROM_XARALX
02670 BOOL Worked;
02671 Worked = RawRenderPath32( PathToDraw );
02672 if (Worked)
02673 {
02674
02675 if (!Worked)
02676 TRACE( _T("SelectClipPath failed"));
02677 }
02678 else
02679 TRACE( _T("RawPath32 failed in Clip"));
02680 return Worked;
02681 #else
02682 return FALSE;
02683 #endif
02684 }
02685
02686
02687 #define TEST_MANUAL_LINES 0
02688
02689 #ifdef _MAC
02690
02691 #define LONGEST_SEGMENT 2048
02692 #else
02693 #define LONGEST_SEGMENT 8192
02694 #endif
02695 static DocCoord ConvPoints[ LONGEST_SEGMENT ];
02696 static PathVerb ConvVerbs[ LONGEST_SEGMENT ];
02697
02698
02699
02700 BOOL OSRenderRegion::StrokeProperly( Path *const DrawPath )
02701 {
02702
02703 const INT32 Flatten = ScaledPixelWidth/2;
02704
02705 DashType* pDashRec = NULL;
02706 DashType GavinDash;
02707
02708
02709 DocColour Col = RR_STROKECOLOUR();
02710 if (Col.IsTransparent())
02711 return TRUE;
02712
02713
02714 if ((RR_DASHPATTERN().Elements == 0) || (RR_LINEWIDTH() == 0))
02715 {
02716
02717 pDashRec = &GavinDash;
02718 MakeDashType(RR_DASHPATTERN(), pDashRec);
02719 }
02720 else
02721 {
02722
02723 MILLIPOINT Width = RR_LINEWIDTH();
02724 DashRec &DashPattern = RR_DASHPATTERN();
02725
02726 if ((RRQuality.GetLineQuality() >= Quality::FullLine) && DashPattern.Elements > 0)
02727 {
02728 INT32 Length = DashPattern.Elements;
02729
02730 if (Length > 8) Length = 8;
02731
02732 BOOL DoScale = DashPattern.ScaleWithLineWidth;
02733 FIXED16 Scale = DoScale ? (double(Width) / double(DashPattern.LineWidth)) : 1;
02734
02735 GavinDash.Length = Length;
02736 GavinDash.Offset = LongMulFixed16(DashPattern.DashStart, Scale);
02737
02738 for (INT32 el = 0; el < Length; el++)
02739 {
02740 GavinDash.Array[el] = LongMulFixed16(DashPattern.ElementData[el], Scale);
02741 }
02742
02743 pDashRec = &GavinDash;
02744 }
02745 }
02746
02747 INT32 Result = GRenderRegion::StrokePathToPath( DrawPath->GetCoordArray(),
02748 DrawPath->GetVerbArray(),
02749 DrawPath->GetNumCoords(),
02750 ConvPoints,
02751 ConvVerbs,
02752 sizeof(ConvVerbs),
02753 FALSE,
02754 RR_LINEWIDTH(),
02755 Flatten,
02756 RR_STARTCAP(),
02757 RR_JOINTYPE(),
02758 pDashRec );
02759 if (Result>0)
02760 {
02761
02762
02763
02764 wxBrush NewBrush;
02765 #if TEST_MANUAL_LINES
02766
02767 NewBrush.CreateStockObject( NULL_BRUSH );
02768 wxPen DPen(wxBLACK,0);
02769 wxPen DOldPen = GetPen();
02770 RenderDC->SetPen( &DPen );
02771 #else
02772
02773
02774
02775
02776 CalcLogBrush(&NewBrush,RR_STROKECOLOUR());
02777 #endif
02778 wxBrush OldBrush = RenderDC->GetBrush();
02779 RenderDC->SetBrush(NewBrush);
02780
02781
02782
02783
02784
02785
02786 INT32 PathSizeLeft = Result;
02787 DocCoord* PathSoFar = ConvPoints;
02788 PathVerb* VerbSoFar = ConvVerbs;
02789 INT32 PolySize;
02790
02791 while (PathSizeLeft > 0)
02792 {
02793
02794 INT32 Read = RawRenderPath( PathSoFar, VerbSoFar, PathSizeLeft, &PolySize, NULL );
02795
02796 if (Read)
02797 {
02798
02799
02800 RenderDC->DrawPolygon(PolySize,PointArray,0,0,nFillStyle);
02801 PathSoFar += Read;
02802 VerbSoFar += Read;
02803 PathSizeLeft -= Read;
02804 ENSURE(PathSizeLeft>=0, "Path backwards too far");
02805 }
02806 else
02807 {
02808 TRACE( _T("RawRenderPath failed\n"));
02809 break;
02810 }
02811 }
02812 RenderDC->SetBrush( OldBrush );
02813
02814 #if TEST_MANUAL_LINES
02815 RenderDC->SetPen( DOldPen );
02816 DPen.DeleteObject();
02817 #endif
02818
02819 return TRUE;
02820 }
02821 else if (Result<0)
02822 {
02823 return FALSE;
02824 }
02825 else
02826 return TRUE;
02827 }
02828
02829 void OSRenderRegion::MakeDashType(DashRec& KernelDash, DashType* GavinDash)
02830 {
02831 INT32 Length = KernelDash.Elements;
02832
02833 if (Length > 8) Length = 8;
02834
02835 GavinDash->Length = Length;
02836 GavinDash->Offset = KernelDash.DashStart;
02837
02838 for (INT32 el = 0; el < Length; el++)
02839 {
02840 GavinDash->Array[el] = KernelDash.ElementData[el];
02841 }
02842 }
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856 void OSRenderRegion::RenderPath( Path *DrawPath )
02857 {
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872 BOOL ExtendedFill = FALSE;
02873
02874
02875 FillGeometryAttribute *pFillProvider =
02876 (FillGeometryAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02877
02878 if (pFillProvider->GetRuntimeClass() != CC_RUNTIME_CLASS(FlatFillAttribute))
02879 ExtendedFill = TRUE;
02880
02881
02882 if (RRQuality.GetFillQuality() < Quality::Graduated)
02883 ExtendedFill = FALSE;
02884
02885
02886
02887
02888
02889
02890
02891
02892 BOOL StrokeProvided = FALSE;
02893 StrokeTypeAttrValue* pStroke = (StrokeTypeAttrValue*) GetCurrentAttribute(ATTR_STROKETYPE);
02894 VariableWidthAttrValue* pVarWidth = (VariableWidthAttrValue*) GetCurrentAttribute(ATTR_VARWIDTH);
02895 if (pVarWidth && pStroke)
02896 {
02897
02898 if (pStroke->GetPathProcessor() != NULL && pVarWidth->GetWidthFunction() != NULL)
02899 StrokeProvided = TRUE;
02900 }
02901
02902
02903
02904 if (ExtendedFill)
02905 {
02906 if (!pFillProvider->RenderFill(this, DrawPath))
02907
02908 ExtendedFill = FALSE;
02909 }
02910
02911 wxPen NewPen,OldPen;
02912
02913
02914
02915
02916 BOOL ManualStroke = !StrokeProvided;
02917 if (ManualStroke)
02918 ManualStroke = GRenderRegion::StrokePathAvailable();
02919
02920 if (ManualStroke)
02921 {
02922
02923
02924
02925 if (!DoBetterLines)
02926 {
02927 ManualStroke = FALSE;
02928 }
02929
02930 else if ((RR_DASHPATTERN().Elements != 0) && (RR_LINEWIDTH() > 0))
02931 {
02932
02933 }
02934 else
02935 {
02936 INT32 dpLineWidth = MPtoLP(RR_LINEWIDTH());
02937
02938
02939
02940 if (dpLineWidth > 0)
02941 {
02942
02943 }
02944
02945 else if ((RR_LINEWIDTH() == 0) || (dpLineWidth <= 3))
02946 {
02947 ManualStroke = FALSE;
02948 }
02949 else if (RR_STROKECOLOUR().IsTransparent() ||
02950 (RRQuality.GetLineQuality() < Quality::FullLine)
02951 )
02952 {
02953 ManualStroke = FALSE;
02954 }
02955 }
02956 }
02957
02958 if (ManualStroke || StrokeProvided)
02959 {
02960
02961
02962
02963
02964 OldPen = RenderDC->GetPen();
02965
02966
02967
02968
02969 RenderDC->SetPen(*wxTRANSPARENT_PEN);
02970 }
02971
02972 INT32 Count;
02973
02974
02975 INT32 PolyCounts[MAX_POLYGONS];
02976
02977
02978 INT32 Flatness = 0;
02979
02980
02981 INT32 Attempts = 8;
02982
02983 BOOL Worked = FALSE;
02984
02985
02986 while (!Worked && (Attempts > 0))
02987 {
02988 Worked = RawRenderPath( NORMALPATH(DrawPath), PolyCounts, &Count, Flatness, &Flatness );
02989 Attempts--;
02990 }
02991
02992 if (Worked)
02993 {
02994 if (Count)
02995 {
02996 #ifndef _MAC
02997 if (DrawPath->IsFilled && !ExtendedFill)
02998 RenderDC->DrawPolyPolygon(Count,PolyCounts,PointArray,0,0,nFillStyle);
02999 else
03000 #endif
03001 {
03002
03003 wxPoint* PointList = PointArray;
03004 INT32 *CountList = PolyCounts;
03005 INT32 count;
03006
03007 while (Count--)
03008 {
03009 count = *CountList++;
03010 RenderDC->DrawLines(count,PointList);
03011 PointList += count;
03012 }
03013 }
03014 }
03015 }
03016 else
03017 {
03018 TRACE( _T("Unable to flatten path into out buffer\n"));
03019 }
03020
03021
03022 if (ManualStroke)
03023 {
03024 StrokeProperly( DrawPath );
03025 RenderDC->SetPen( OldPen );
03026 }
03027 }
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047 BOOL OSRenderRegion::Bezier(INT32 Px0,INT32 Py0, INT32 Px1,INT32 Py1,
03048 INT32 Px2,INT32 Py2, INT32 Px3,INT32 Py3,
03049 INT32 Flatness)
03050 {
03051
03052 if (!(Flatness > 0))
03053 return FALSE;
03054
03055 INT32 diff;
03056
03057 INT32 dx0 = (Px1*3 - Px0*2 - Px3);
03058 dx0 = dx0 < 0 ? -dx0 : dx0;
03059
03060 INT32 dy0 = (Py1*3 - Py0*2 - Py3);
03061 dy0 = dy0 < 0 ? -dy0 : dy0;
03062
03063
03064 if (dx0 >= dy0)
03065 diff = 3*dx0 + dy0;
03066 else
03067 diff = dx0 + 3*dy0;
03068
03069
03070 if (diff > Flatness)
03071 {
03072
03073 return Split(Px0,Py0, Px1,Py1, Px2,Py2, Px3,Py3, Flatness);
03074 }
03075
03076 INT32 dx1 = (Px2*3 - Px0 - Px3*2);
03077 dx1 = dx1 < 0 ? -dx1 : dx1;
03078
03079 INT32 dy1 = (Py2*3 - Py0 - Py3*2);
03080 dy1 = dy1 < 0 ? -dy1 : dy1;
03081
03082
03083 if (dx1 >= dy1)
03084 diff = 3*dx1 + dy1;
03085 else
03086 diff = dx1 + 3*dy1;
03087
03088
03089 if (diff > Flatness)
03090 {
03091
03092 return Split(Px0,Py0, Px1,Py1, Px2,Py2, Px3,Py3, Flatness);
03093 }
03094
03095 if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03096 return FALSE;
03097
03098
03099 PointArray[InsertPos].x = INT32((Px3+128)/256);
03100 PointArray[InsertPos].y = INT32((Py3+128)/256);
03101 InsertPos++;
03102
03103
03104 return TRUE;
03105 }
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126 BOOL OSRenderRegion::Split(INT32 Px0,INT32 Py0, INT32 Px1,INT32 Py1,
03127 INT32 Px2,INT32 Py2, INT32 Px3,INT32 Py3,
03128 INT32 Flatness)
03129 {
03130
03131
03132 INT32 lx0 = Px0;
03133 INT32 ly0 = Py0;
03134 INT32 lx1 = (Px0 + Px1)/2;
03135 INT32 ly1 = (Py0 + Py1)/2;
03136 INT32 lx2 = (Px0 + 2*Px1 + Px2)/4;
03137 INT32 ly2 = (Py0 + 2*Py1 + Py2)/4;
03138 INT32 lx3 = (Px0 + 3*Px1 + 3*Px2 + Px3)/8;
03139 INT32 ly3 = (Py0 + 3*Py1 + 3*Py2 + Py3)/8;
03140
03141
03142 INT32 rx0 = lx3;
03143 INT32 ry0 = ly3;
03144 INT32 rx1 = (Px1 + 2*Px2 + Px3)/4;
03145 INT32 ry1 = (Py1 + 2*Py2 + Py3)/4;
03146 INT32 rx2 = (Px2 + Px3)/2;
03147 INT32 ry2 = (Py2 + Py3)/2;
03148 INT32 rx3 = Px3;
03149 INT32 ry3 = Py3;
03150
03151 if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03152 return FALSE;
03153
03154
03155 if (!Bezier(lx0,ly0, lx1,ly1, lx2,ly2, lx3,ly3, Flatness))
03156
03157 return FALSE;
03158
03159 if (InsertPos >= SIZEOF_POLYLINE_BUFFER)
03160 return FALSE;
03161
03162
03163 return Bezier(rx0,ry0, rx1,ry1, rx2,ry2, rx3,ry3, Flatness);
03164 }
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181 INT32 OSRenderRegion::CalcPathFlattening()
03182 {
03183 MILLIPOINT PixelWidth = GetScaledPixelWidth();
03184 INT32 Accuracy = PixelWidth/8;
03185
03186 return max(Accuracy, INT32(10));
03187
03188 }
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204 INT32 OSRenderRegion::MPtoLP(MILLIPOINT MPtoConvert)
03205 {
03206 MILLIPOINT PixelWidth = GetScaledPixelWidth();
03207 return INT32(MPtoConvert/PixelWidth);
03208 }
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223 MILLIPOINT OSRenderRegion::CalcScaledPixelWidth()
03224 {
03225
03226 return (MILLIPOINT)( (RenderView->GetPixelWidth().MakeDouble() / ScaleFactor.MakeDouble()) + 0.5 );
03227
03228
03229
03230
03231 }
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248 MILLIPOINT OSRenderRegion::CalcPixelWidth()
03249 {
03250 PORTNOTE("other","Can't handle different DPIs, using X")
03251 return MILLIPOINT(double(72000) / double(OSRenderRegion::GetFixedDCPPI(*RenderDC).x));
03252 }
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269 void OSRenderRegion::DrawBlob(DocCoord p, BlobType type)
03270 {
03271 DocRect MyBlob;
03272
03273 GetBlobRect( ScaleFactor, p, type, &MyBlob);
03274
03275
03276
03277
03278
03279 DrawDragRect( &MyBlob );
03280 }
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299 void OSRenderRegion::DrawBitmap(const DocCoord &Point, KernelBitmap* pBitmap)
03300 {
03301 PORTNOTETRACE("other","OSRenderRegion::DrawBitmap - do nothing");
03302 #ifndef EXCLUDE_FROM_XARALX
03303
03304 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03305 return;
03306
03307
03308 if (pBitmap == NULL || pBitmap->ActualBitmap == NULL)
03309 {
03310 ERROR3("NULL Bitmap passed to DrawBitmap");
03311 return;
03312 }
03313
03314
03315 WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
03316
03317
03318 if (
03319 (WinBM->BMInfo==NULL) ||
03320 (WinBM->BMBytes==NULL)
03321 )
03322 return;
03323
03324
03325 INT32 Width = WinBM->GetWidth();
03326 INT32 Height = WinBM->GetHeight();
03327
03328
03329 POINT Origin = DocCoordToWin(Point);
03330 Origin.y = Origin.y - Height;
03331
03332 CDC MemDC;
03333
03334 MemDC.CreateCompatibleDC(RenderDC);
03335
03336 CBitmap Bitmap;
03337
03338 Bitmap.CreateCompatibleBitmap(RenderDC, Width, Height);
03339
03340
03341
03342 CBitmap* OldBmp = MemDC.SelectObject(&Bitmap);
03343
03344 if (OldBmp == NULL)
03345 {
03346 TRACE( _T("Couldn't select Bitmap into CDC in DrawBitmap\n"));
03347 return;
03348 }
03349
03350
03351 SetDIBitsToDevice( MemDC.m_hDC,
03352 0,0,
03353 Width,
03354 Height,
03355 0,0,
03356 0,
03357 Height,
03358 WinBM->BMBytes,
03359 WinBM->BMInfo,
03360 DIB_RGB_COLORS
03361 );
03362
03363
03364 RenderDC->BitBlt( Origin.x, Origin.y,
03365 Width,
03366 Height,
03367 &MemDC,
03368 0,0,
03369 SRCCOPY
03370 );
03371
03372
03373 MemDC.SelectObject(OldBmp);
03374 Bitmap.DeleteObject();
03375 #endif
03376 }
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396 void OSRenderRegion::DrawBitmap(const DocCoord &Point, UINT32 BitmapID, UINT32 ToolID)
03397 {
03398
03399 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03400 return;
03401
03402 wxBitmap * pBitmap=CamArtProvider::Get()->FindBitmap((ResourceID)BitmapID);
03403
03404 if (!pBitmap)
03405 return;
03406
03407
03408
03409 INT32 Height = pBitmap->GetHeight();
03410
03411
03412 wxPoint Origin = DocCoordToWin(Point);
03413 Origin.y = Origin.y - Height;
03414
03415 RenderDC->DrawBitmap(*pBitmap, Origin.x, Origin.y, TRUE);
03416
03417 }
03418
03419 BOOL OSRenderRegion::DrawTransformedBitmap(NodeBitmap *pNodeBitmap)
03420 {
03421
03422
03423 if (IsPrinting())
03424 {
03425
03426 if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
03427 return TRUE;
03428
03429 if ((!RenderComplexShapes) && (pNodeBitmap->NeedsTransparency()))
03430 return TRUE;
03431
03432
03433 if (CurrentColContext->GetColourPlate() == NULL ||
03434 CurrentColContext->GetColourPlate()->IsDisabled())
03435 {
03436
03437
03438 if (pNodeBitmap->HasSimpleOrientation(this))
03439 {
03440
03441 DocCoord *Coords = pNodeBitmap->InkPath.GetCoordArray();
03442
03443
03444 OilCoord TopLeft(Coords[0].x, Coords[0].y);
03445 RenderMatrix.transform(&TopLeft);
03446 WinCoord DestTopLeft = TopLeft.ToWin(RenderView);
03447
03448
03449 MILLIPOINT Width = Coords[1].x - Coords[0].x;
03450 MILLIPOINT Height = Coords[0].y - Coords[3].y;
03451
03452 FIXED16 fxPixelSize = 0;
03453 RenderView->GetScaledPixelSize(&fxPixelSize, &fxPixelSize);
03454 double dPixelSize = fxPixelSize.MakeDouble();
03455 INT32 DestWidth = (INT32) ((((double) Width) / dPixelSize) + 0.5);
03456 INT32 DestHeight = (INT32) ((((double) Height) / dPixelSize) + 0.5);
03457
03458
03459 CWxBitmap *WxBM = (CWxBitmap *) pNodeBitmap->GetBitmap()->ActualBitmap;
03460
03461 wxImage *pwxImage=WxBM->MakewxImage(DestWidth, DestHeight);
03462
03463 if (pwxImage)
03464 {
03465 wxBitmap TheBitmap(*pwxImage);
03466 RenderDC->DrawBitmap(TheBitmap, DestTopLeft.x, DestTopLeft.y, TRUE);
03467 delete pwxImage;
03468 }
03469 }
03470 }
03471 }
03472
03473
03474 RenderComplexShapes = TRUE;
03475 BOOL bOk = RenderRegion::DrawTransformedBitmap(pNodeBitmap);
03476 RenderComplexShapes = FALSE;
03477
03478 return bOk;
03479 }
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499 void OSRenderRegion::DrawBitmapBlob(const DocCoord &Point, KernelBitmap* BlobShape)
03500 {
03501 PORTNOTETRACE("other","OSRenderRegion::DrawBitmapBlob - do nothing");
03502 #ifndef EXCLUDE_FROM_XARALX
03503 ENSURE(BlobShape != NULL, "NULL Bitmap passed to DrawBitmapBlob");
03504
03505
03506 if (BlobShape->ActualBitmap == NULL)
03507 return;
03508
03509
03510 WinBitmap *WinBM = (WinBitmap*)BlobShape->ActualBitmap;
03511
03512
03513 if (
03514 (WinBM->BMInfo==NULL) ||
03515 (WinBM->BMBytes==NULL)
03516 )
03517 return;
03518
03519
03520 INT32 Width = WinBM->BMInfo->bmiHeader.biWidth;
03521 INT32 Height = WinBM->BMInfo->bmiHeader.biHeight;
03522
03523
03524 POINT Origin = FindBitmapOrigin(Point, Width, Height);
03525
03526 CDC MemDC;
03527
03528 MemDC.CreateCompatibleDC(RenderDC);
03529
03530 CBitmap Bitmap;
03531
03532 Bitmap.CreateCompatibleBitmap(RenderDC, Width, Height);
03533
03534
03535
03536 CBitmap* OldBmp = MemDC.SelectObject(&Bitmap);
03537
03538 if (OldBmp == NULL)
03539 {
03540 TRACE( _T("Couldn't select Bitmap into CDC in DrawBitmapBlob\n"));
03541 return;
03542 }
03543
03544
03545
03546 SetDIBitsToDevice( MemDC.m_hDC,
03547 0,0,
03548 Width,
03549 Height,
03550 0,0,
03551 0,
03552 Height,
03553 WinBM->BMBytes,
03554 WinBM->BMInfo,
03555 DIB_RGB_COLORS
03556 );
03557
03558
03559 RenderDC->BitBlt( Origin.x, Origin.y,
03560 Width,
03561 Height,
03562 &MemDC,
03563 0,0,
03564 SRCINVERT
03565 );
03566
03567
03568 MemDC.SelectObject(OldBmp);
03569 Bitmap.DeleteObject();
03570 #endif
03571 }
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591 void OSRenderRegion::DrawBitmapBlob( const DocCoord &Point, ResourceID resID )
03592 {
03593 wxBitmap *pBitmap = (CamArtProvider::Get())->FindBitmap( resID );
03594 if( NULL == pBitmap )
03595 {
03596 TRACE( _T("wxBitmap failed to create in DrawBitmapBlob\n"));
03597 return;
03598 }
03599
03600
03601 INT32 Width = pBitmap->GetWidth();
03602 INT32 Height = pBitmap->GetHeight();
03603
03604
03605 wxPoint Origin = FindBitmapOrigin(Point, Width, Height);
03606
03607
03608 wxMemoryDC memDc;
03609 memDc.SelectObject( *pBitmap );
03610 RenderDC->Blit( Origin.x, Origin.y, Width, Height, &memDc, 0, 0, wxXOR );
03611 }
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640 wxPoint OSRenderRegion::FindBitmapOrigin(DocCoord Centre, INT32 Width, INT32 Height)
03641 {
03642 DocCoord Origin;
03643 double PelSize;
03644
03645 DocView *pDocView = DocView::GetSelected();
03646 ERROR3IF(pDocView == NULL, "OSRenderRegion::FindBitmapOrigin() when no view is selected!");
03647 if (pDocView)
03648 PelSize = (pDocView->GetPixelWidth() / pDocView->GetViewScale()).MakeDouble();
03649 else
03650 PelSize = 750;
03651
03652
03653 Origin.x = Centre.x - (MILLIPOINT)(0.5 + (((double)Width * PelSize)/2));
03654 Origin.y = Centre.y + (MILLIPOINT)(0.5 + (((double)Height * PelSize)/2));
03655
03656 return DocCoordToWin(Origin);
03657 }
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681 void OSRenderRegion::GetBlobRect( FIXED16 Scale, const DocCoord& BlobPoint, BlobType bType, DocRect *pResult )
03682 {
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692 MILLIPOINT BlobSize;
03693 DocView *pDocView = DocView::GetSelected();
03694 ERROR3IF(pDocView == NULL, "OSRenderRegion::GetBlobRect() when no view is selected!");
03695
03696
03697
03698
03699 const double PelSize = (pDocView->GetPixelWidth() / Scale).MakeDouble();
03700
03701
03702
03703
03704
03705 switch (bType)
03706 {
03707 case BT_UNSELECTED:
03708 BlobSize = (MILLIPOINT)((double)UnSelectedBlobSize * PelSize);
03709 break;
03710
03711 case BT_SELECTED:
03712 BlobSize = (MILLIPOINT)((double)SelectedBlobSize * PelSize);
03713 break;
03714
03715 case BT_CLICKME:
03716 BlobSize = (MILLIPOINT)((double)HitTestRadius * PelSize);
03717 break;
03718
03719 case BT_SELECTEDLARGEST:
03720 BlobSize = max( (MILLIPOINT)((double)UnSelectedBlobSize * PelSize),
03721 (MILLIPOINT)((double)SelectedBlobSize * PelSize) );
03722 break;
03723
03724 case BT_MSTAGEFILLUNSELECTED:
03725 BlobSize = (MILLIPOINT)((double)MultiStageUnSelectedBlobSize * PelSize);
03726 break;
03727
03728 case BT_MSTAGEFILLSELECTED:
03729 BlobSize = (MILLIPOINT)((double)MultiStageSelectedBlobSize * PelSize);
03730 break;
03731
03732 case BT_MSTAGESELECTEDLARGEST:
03733 BlobSize = max( (MILLIPOINT)((double)MultiStageSelectedBlobSize * PelSize),
03734 (MILLIPOINT)((double)MultiStageUnSelectedBlobSize * PelSize) );
03735 break;
03736
03737 case BT_CLIPVIEW:
03738 BlobSize = (MILLIPOINT)((double)ClipViewBlobSize * PelSize);
03739 break;
03740
03741 default:
03742 ENSURE( FALSE, "GetBlobRect() was called with an invalid BlobType" );
03743 BlobSize = 0;
03744 break;
03745 }
03746
03747
03748 pResult->lo.x = BlobPoint.x - BlobSize - (MILLIPOINT)(PelSize/2.0);
03749 pResult->lo.y = BlobPoint.y - BlobSize - (MILLIPOINT)(PelSize/2.0);
03750 pResult->hi.x = BlobPoint.x + BlobSize + (MILLIPOINT)(PelSize/2.0);
03751 pResult->hi.y = BlobPoint.y + BlobSize + (MILLIPOINT)(PelSize/2.0);
03752
03753 }
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772 MILLIPOINT OSRenderRegion::GetHitTestRadius(DocView *pDocView)
03773
03774 {
03775 FIXED16 fxViewScale = pDocView->GetViewScale();
03776 FIXED16 fxPelSize = ((FIXED16) HitTestRadius) * pDocView->GetPixelWidth();
03777 return (MILLIPOINT) (fxPelSize / fxViewScale).MakeLong();
03778 }
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794 WinCoord OSRenderRegion::DocCoordToWin(const DocCoord& DocPoint)
03795 {
03796 OilCoord OilPoint;
03797
03798 OilPoint.x = MatrixCalc( RenderMatrix.a, DocPoint.x, RenderMatrix.c, DocPoint.y) +
03799 RenderMatrix.e;
03800
03801 OilPoint.y = MatrixCalc( RenderMatrix.b, DocPoint.x, RenderMatrix.d, DocPoint.y) +
03802 RenderMatrix.f;
03803
03804 return OilPoint.ToWin(RenderView);
03805 }
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819 Coord OSRenderRegion::DocCoordToOS256(const DocCoord& DocPoint)
03820 {
03821 OilCoord OilPoint;
03822
03823 OilPoint.x = MatrixCalc( RenderMatrix.a, DocPoint.x, RenderMatrix.c, DocPoint.y) +
03824 RenderMatrix.e;
03825
03826 OilPoint.y = MatrixCalc( RenderMatrix.b, DocPoint.x, RenderMatrix.d, DocPoint.y) +
03827 RenderMatrix.f;
03828
03829 Coord OS256Point;
03830
03831 FIXED16 PixelWidth = RenderView->GetPixelWidth();
03832 OS256Point.x = MPtoOS256(OilPoint.x, PixelWidth);
03833
03834
03835
03836
03837
03838 OS256Point.y = -(MPtoOS256(OilPoint.y, PixelWidth));
03839
03840 return OS256Point;
03841 }
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864 WinRect OSRenderRegion::DocRectToWin(View *pView,
03865 const Matrix &RenderMatrix,
03866 const DocRect& DRect,
03867 INT32 leftshift, INT32 topshift,
03868 INT32 rightshift, INT32 bottomshift,
03869 BOOL MightClip)
03870 {
03871 WinRect WinRect;
03872
03873
03874 ERROR3IF(pView == NULL, "NULL view in OSRenderRegion::DocRectToWin()");
03875
03876 OilCoord OilLo;
03877 OilCoord OilHi;
03878
03879 OilLo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
03880 OilLo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;
03881 OilHi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
03882 OilHi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;
03883
03884
03885
03886 MILLIPOINT Temp;
03887
03888 if (OilLo.x > OilHi.x)
03889 {
03890 Temp = OilLo.x;
03891 OilLo.x = OilHi.x;
03892 OilHi.x = Temp;
03893 }
03894
03895 if (OilLo.y > OilHi.y)
03896 {
03897 Temp = OilLo.y;
03898 OilLo.y = OilHi.y;
03899 OilHi.y = Temp;
03900 }
03901
03902 WinCoord WinLo;
03903 WinCoord WinHi;
03904
03905 WinLo = OilLo.ToWin(pView);
03906 WinHi = OilHi.ToWin(pView);
03907
03908 WinRect.x = WinLo.x + leftshift;
03909 WinRect.y = WinHi.y + topshift;
03910 WinRect.width = WinHi.x + rightshift -WinRect.x;
03911 WinRect.height = WinLo.y + bottomshift-WinRect.y;
03912
03913 PORTNOTE("other", "Check this use of WIN32")
03914 if (
03915 MightClip
03916
03917
03918
03919 )
03920 {
03921
03922
03923 wxRect MaxRect(-100, -100, 32100, 32100 );
03924 WinRect.Intersect(MaxRect);
03925 }
03926
03927 return WinRect;
03928 }
03929
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951 WinRect OSRenderRegion::DocRectToWin(const Matrix &RenderMatrix, const DocRect& DRect,
03952 const double dpi)
03953 {
03954 WinRect WinRect;
03955
03956 OilCoord OilLo;
03957 OilCoord OilHi;
03958
03959 OilLo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
03960 OilLo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;
03961 OilHi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
03962 OilHi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;
03963
03964
03965
03966 MILLIPOINT Temp;
03967
03968 if (OilLo.x > OilHi.x)
03969 {
03970 Temp = OilLo.x;
03971 OilLo.x = OilHi.x;
03972 OilHi.x = Temp;
03973 }
03974
03975 if (OilLo.y > OilHi.y)
03976 {
03977 Temp = OilLo.y;
03978 OilLo.y = OilHi.y;
03979 OilHi.y = Temp;
03980 }
03981
03982 WinCoord WinLo;
03983 WinCoord WinHi;
03984
03985 WinLo = OilLo.ToWin(dpi);
03986 WinHi = OilHi.ToWin(dpi);
03987
03988 WinRect.x = WinLo.x;
03989 WinRect.y = WinHi.y;
03990 WinRect.width = WinHi.x-WinRect.x;
03991 WinRect.height = WinLo.y-WinRect.y;
03992
03993 return WinRect;
03994 }
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016 DocRect OSRenderRegion::WinRectToDoc(const Matrix &RenderMatrix, const WinRect& WRect,
04017 const double dpi)
04018 {
04019 DocRect dr;
04020
04021 WinCoord WinLo(WRect.x, WRect.GetBottomEx());
04022 WinCoord WinHi(WRect.GetRightEx(), WRect.y);
04023 OilCoord OilLo = OilCoord( LongMulFixed16(WinLo.x, 72000L / dpi),
04024 -LongMulFixed16(WinLo.y, 72000L / dpi)
04025 );
04026 OilCoord OilHi = OilCoord( LongMulFixed16(WinHi.x, 72000L / dpi),
04027 -LongMulFixed16(WinHi.y, 72000L / dpi)
04028 );
04029
04030 Matrix inv = RenderMatrix.Inverse();
04031
04032 dr.lo.x = MatrixCalc( inv.a, OilLo.x, inv.c, OilLo.y ) + inv.e;
04033 dr.lo.y = MatrixCalc( inv.b, OilLo.x, inv.d, OilLo.y ) + inv.f;
04034 dr.hi.x = MatrixCalc( inv.a, OilHi.x, inv.c, OilHi.y ) + inv.e;
04035 dr.hi.y = MatrixCalc( inv.b, OilHi.x, inv.d, OilHi.y ) + inv.f;
04036
04037
04038
04039 MILLIPOINT Temp;
04040
04041 if (dr.lo.x > dr.hi.x)
04042 {
04043 Temp = dr.lo.x;
04044 dr.lo.x = dr.hi.x;
04045 dr.hi.x = Temp;
04046 }
04047
04048 if (dr.lo.y > dr.hi.y)
04049 {
04050 Temp = dr.lo.y;
04051 dr.lo.y = dr.hi.y;
04052 dr.hi.y = Temp;
04053 }
04054
04055 return dr;
04056 }
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081 WinRect OSRenderRegion::BitmapDocRectToWin(Matrix &RenderMatrix, const DocRect& DRect,
04082 const double dpi)
04083 {
04084
04085 OilRect OilRec;
04086 OilRec.lo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e;
04087 OilRec.lo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f;
04088 OilRec.hi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e;
04089 OilRec.hi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f;
04090
04091 if (OilRec.lo.x > OilRec.hi.x)
04092 {
04093 MILLIPOINT Temp = OilRec.lo.x;
04094 OilRec.lo.x = OilRec.hi.x;
04095 OilRec.hi.x = Temp;
04096 }
04097 if (OilRec.lo.y > OilRec.hi.y)
04098 {
04099 MILLIPOINT Temp = OilRec.lo.y;
04100 OilRec.lo.y = OilRec.hi.y;
04101 OilRec.hi.y = Temp;
04102 }
04103
04104 OilCoord OilSize(OilRec.hi.x-OilRec.lo.x, OilRec.hi.y-OilRec.lo.y);
04105
04106 #if 0
04107
04108
04109
04110
04111 WinCoord WinSize = OilSize.ToWin(dpi) ;
04112 #else
04113
04114
04115
04116
04117 WinCoord WinSize( +(INT32)floor(OilSize.x*dpi/72000.0+0.5), -(INT32)floor(OilSize.y*dpi/72000.0+0.5) ) ;
04118 #endif
04119
04120
04121
04122
04123
04124
04125
04126
04127 OilCoord OilLo = OilCoord(OilRec.lo.x,OilRec.lo.y);
04128 WinCoord WinLo = OilLo.ToWin(dpi);
04129
04130 WinRect WinRectangle;
04131 WinRectangle.x = WinLo.x;
04132 WinRectangle.y = WinLo.y + WinSize.y;
04133 WinRectangle.width = WinLo.x + WinSize.x-WinRectangle.x;
04134 WinRectangle.height = WinLo.y-WinRectangle.y;
04135
04136 return WinRectangle;
04137 }
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166 BOOL OSRenderRegion::CalculateGavinOffsetsWinRect( const Matrix& RenderMatrix,
04167 const DocRect& DRect,
04168 const double dpi,
04169 GMATRIX* GMat,
04170 BOOL bCentralise,
04171 double* pdXCentralAdjust,
04172 double* pdYCentralAdjust)
04173 {
04174 OilRect OilRec ;
04175 OilRec.lo.x = MatrixCalc( RenderMatrix.a, DRect.lo.x, RenderMatrix.c, DRect.lo.y ) + RenderMatrix.e ;
04176 OilRec.lo.y = MatrixCalc( RenderMatrix.b, DRect.lo.x, RenderMatrix.d, DRect.lo.y ) + RenderMatrix.f ;
04177 OilRec.hi.x = MatrixCalc( RenderMatrix.a, DRect.hi.x, RenderMatrix.c, DRect.hi.y ) + RenderMatrix.e ;
04178 OilRec.hi.y = MatrixCalc( RenderMatrix.b, DRect.hi.x, RenderMatrix.d, DRect.hi.y ) + RenderMatrix.f ;
04179
04180 if (OilRec.lo.x > OilRec.hi.x)
04181 {
04182 MILLIPOINT Temp = OilRec.lo.x ;
04183 OilRec.lo.x = OilRec.hi.x ;
04184 OilRec.hi.x = Temp ;
04185 }
04186 if (OilRec.lo.y > OilRec.hi.y)
04187 {
04188 MILLIPOINT Temp = OilRec.lo.y ;
04189 OilRec.lo.y = OilRec.hi.y ;
04190 OilRec.hi.y = Temp ;
04191 }
04192 OilCoord OilSize( OilRec.hi.x-OilRec.lo.x, OilRec.hi.y-OilRec.lo.y ) ;
04193
04194
04195
04196
04197
04198
04199
04200
04201 double Scale = (dpi/72000.0)*(1<<16)*(1<<FX) ;
04202 double WinXOffset = -OilRec.lo.x * Scale;
04203 double WinYOffset = -OilRec.lo.y * Scale;
04204
04205 if (bCentralise)
04206 {
04207
04208
04209
04210
04211 WinCoord WinSize( +(INT32)floor(OilSize.x*dpi/72000.0+0.5), -(INT32)floor(OilSize.y*dpi/72000.0+0.5) ) ;
04212 OilCoord NewOilSize( +(INT32)floor(WinSize.x*72000.0/dpi+0.5), -(INT32)floor(WinSize.y*72000.0/dpi+0.5) ) ;
04213
04214 if (pdXCentralAdjust) *pdXCentralAdjust = ((NewOilSize.x-OilSize.x)/2.0) * Scale;
04215 if (pdYCentralAdjust) *pdYCentralAdjust = ((NewOilSize.y-OilSize.y)/2.0) * Scale;
04216
04217 }
04218
04219
04220 if (pdXCentralAdjust) WinXOffset += *pdXCentralAdjust;
04221 if (pdYCentralAdjust) WinYOffset += *pdYCentralAdjust;
04222
04223
04224
04225
04226 GMat->CX = MakeXLong(WinXOffset) ;
04227 GMat->CY = MakeXLong(WinYOffset) ;
04228
04229 return TRUE;
04230 }
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299 static inline INT32 GetDiagonal( const WinRect& Rectangle )
04300 {
04301 const double W = Rectangle.width;
04302 const double H = Rectangle.height;
04303 return (INT32) sqrt(W*W+H*H);
04304 }
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321 BOOL OSRenderRegion::RenderBitmapFill(Path *PathToDraw, BitmapFillAttribute* Fill)
04322 {
04323 if (Fill->GetBitmap() == NULL || Fill->GetBitmap()->ActualBitmap == NULL)
04324 return FALSE;
04325
04326
04327
04328 if ((RenderFlags.VeryMono) || (RFlags.Metafile))
04329 return FALSE;
04330
04331 ENSURE( Fill->GetBitmap()->ActualBitmap->IsKindOf( CC_RUNTIME_CLASS( CWxBitmap ) ), "Strange bitmapfill");
04332
04333
04334
04335
04336
04337 GDrawContext* GD = GRenderRegion::GetStaticDrawContext();
04338 CWxBitmap *WxBM = NULL;
04339 CWxBitmap *OrigWxBM = NULL;
04340
04341 const INT32 bpp = Fill->GetBitmap()->GetBPP();
04342 BYTE *pGreyTable = NULL;
04343
04344 if (Fill->GetStartColour() != NULL && Fill->GetEndColour() != NULL)
04345 {
04346
04347 WxBM = (CWxBitmap*)Fill->GetBitmap()->GetGreyscaleVersion();
04348
04349 if (WxBM == NULL && bpp == 8)
04350 {
04351
04352 pGreyTable = Fill->GetBitmap()->ActualBitmap->GetGreyscaleTable();
04353 }
04354 }
04355
04356
04357
04358
04359 if (WxBM == NULL)
04360 {
04361 if (bpp != 32)
04362 {
04363 WxBM = (CWxBitmap*)Fill->GetBitmap()->ActualBitmap;
04364 }
04365 else
04366 {
04367 WxBM = (CWxBitmap*)CBMPBits::RenderBMPFillAttrToTransparentWhiteRect(Fill);
04368 }
04369 }
04370
04371 if (!WxBM)
04372 {
04373 return (FALSE);
04374 }
04375
04376 if( (WxBM->BMInfo==NULL) || (WxBM->BMBytes==NULL) )
04377 return FALSE;
04378
04379
04380
04381
04382
04383
04384 wxPoint BottomLeft = DocCoordToWin( Fill->StartPoint );
04385 wxPoint BottomRight = DocCoordToWin( Fill->EndPoint );
04386 wxPoint TopLeft = DocCoordToWin( Fill->EndPoint2 );
04387
04388 INT32 DestWidth = BottomRight.x - BottomLeft.x;
04389 INT32 DestHeight = BottomLeft.y - TopLeft.y;
04390 if (DestWidth==0 || DestHeight==0)
04391 {
04392 return TRUE;
04393 }
04394
04395 if (IsPrinting())
04396 {
04397 if (CurrentColContext->GetColourPlate() == NULL ||
04398 CurrentColContext->GetColourPlate()->IsDisabled())
04399 {
04400 PORTNOTE("other", "No StretchDIBits call in OSRenderRegion::RenderBitmapFill")
04401 #ifndef EXCLUDE_FROM_XARALX
04402
04403 const LPBITMAPINFO bmInfo = WxBM->BMInfo;
04404
04405 #if 1
04406
04407 const BOOL SendDirectToPrinter = true;
04408 #else
04409
04410 const BOOL SendDirectToPrinter = RFlags.Metafile;
04411 #endif
04412
04413 if (SendDirectToPrinter)
04414 {
04415
04416
04417
04418 StretchDIBits( RenderDC->m_hDC,
04419 BottomLeft.x, TopLeft.y,
04420 DestWidth, DestHeight,
04421 0,0,
04422 bmInfo->bmiHeader.biWidth,
04423 bmInfo->bmiHeader.biHeight,
04424 WinBM->BMBytes,
04425 bmInfo,
04426 DIB_RGB_COLORS,
04427 SRCCOPY );
04428
04429 return TRUE;
04430 }
04431 #endif
04432
04433
04434
04435
04436
04437
04438 }
04439 }
04440
04441
04442
04443 GMATRIX GMatrix;
04444
04445 GMatrix.AX = 1<<(16 + FX);
04446 GMatrix.AY = 0;
04447 GMatrix.BX = 0;
04448 GMatrix.BY = 1<<(16 + FX);
04449
04450 GMatrix.CX = 0;
04451 GMatrix.CY = 0;
04452
04453
04454
04455 LPBITMAPINFO TempInfo;
04456 LPBYTE TempBits;
04457 INT32 DeviceDepth;
04458
04459 if (IsPrinting())
04460 {
04461
04462
04463 DeviceDepth = 32;
04464 }
04465 else
04466 {
04467 PORTNOTE("other", "Assume 24 bit output device in OSRenderRegion::RenderBitmapFill")
04468 #ifndef EXCLUDE_FROM_XARALX
04469 DeviceDepth = GetDeviceCaps( RenderDC->m_hDC, BITSPIXEL ) *
04470 GetDeviceCaps( RenderDC->m_hDC, PLANES );
04471 #else
04472 DeviceDepth=24;
04473 #endif
04474
04475 if (DeviceDepth ==24)
04476 DeviceDepth = 32;
04477 }
04478
04479 TempInfo = AllocDIB(DestWidth, DestHeight, DeviceDepth, &TempBits);
04480
04481 if (TempInfo==NULL)
04482 {
04483 TRACEALL( _T("Out of memory during OSRenderRegion::RenderBitmapFill") );
04484 return FALSE;
04485 }
04486
04487
04488
04489 UINT32 DIBPal = DIB_RGB_COLORS;
04490
04491 if (DeviceDepth <= 8)
04492 {
04493 DIBPal = GRenderRegion::SetPaletteEntries( TempInfo, RenderDC );
04494 }
04495
04496
04497
04498 GD->SetupBitmap(TempInfo->bmiHeader.biWidth,
04499 TempInfo->bmiHeader.biHeight,
04500 TempInfo->bmiHeader.biBitCount,
04501 TempBits );
04502
04503 GD->SetMatrix( &GMatrix );
04504
04505 COLORREF DefaultColour = 0xFFFFFFFF;
04506
04507
04508 RGBQUAD *Palette = NULL;
04509
04510
04511
04512 ColourCorrectBitmap(Fill, WxBM->BMInfo, &Palette);
04513
04514
04515 if (pGreyTable != NULL)
04516 {
04517 ERROR3IF(bpp != 8, "Greytable should only be here when rendering an 8bpp bitmap");
04518 RGBQUAD *OldPalette = Palette;
04519
04520
04521 Palette = (RGBQUAD *) CCMalloc(256 * sizeof(RGBQUAD));
04522 if (Palette == NULL)
04523 {
04524 ERROR3("No memory for palette");
04525 return FALSE;
04526 }
04527
04528
04529
04530 for (INT32 i=0; i<256; i++)
04531 {
04532 Palette[i] = OldPalette[pGreyTable[i]];
04533 }
04534
04535 if (OldPalette != WxBM->BMInfo->bmiColors)
04536 CCFree(OldPalette);
04537 }
04538
04539
04540 if (Palette == NULL)
04541 Palette = WxBM->BMInfo->bmiColors;
04542
04543
04544 if (bpp <= 8)
04545 {
04546 INT32 NumCols;
04547 switch (bpp)
04548 {
04549 case 1:
04550 NumCols = 2;
04551 break;
04552
04553 case 2:
04554 NumCols = 4;
04555 break;
04556
04557 case 4:
04558 NumCols = 16;
04559 break;
04560
04561 case 8:
04562 NumCols = 256;
04563 break;
04564
04565 default:
04566 NumCols = 256;
04567 break;
04568 }
04569
04570 for (INT32 i=0; i<NumCols; i++)
04571 {
04572 if (Palette[i].rgbReserved == 0xFF)
04573 {
04574 RGBQUAD* TempPalette = (RGBQUAD*)CCMalloc(NumCols * sizeof(RGBQUAD));
04575 if (TempPalette)
04576 {
04577
04578 memcpy(TempPalette, Palette, NumCols*sizeof(RGBQUAD));
04579
04580
04581 TempPalette[i].rgbRed = 0xFF;
04582 TempPalette[i].rgbGreen = 0xFF;
04583 TempPalette[i].rgbBlue = 0xFF;
04584
04585 Palette = TempPalette;
04586 break;
04587 }
04588 }
04589 }
04590 }
04591
04592
04593
04594 POINT PGram[3];
04595 PGram[0].x = 0; PGram[0].y = 0;
04596 PGram[1].x = DestWidth; PGram[1].y = 0;
04597 PGram[2].x = 0; PGram[2].y = DestHeight;
04598
04599 DWORD Style = 1;
04600 BOOL bDoBitmapFill = TRUE;
04601 BYTE* pSepTables = NULL;
04602 BGR *pCyanSepTable = NULL;
04603 BGR *pMagentaSepTable = NULL;
04604 BGR *pYellowSepTable = NULL;
04605 BGR *pBlackSepTable = NULL;
04606 BYTE *pUnderColourRemovalTable = NULL;
04607 BYTE *pBlackGenerationTable = NULL;
04608 CWxBitmap* pNewBitmap = NULL;
04609
04610 PORTNOTE("other", "No colour separation OSRenderRegion::RenderBitmapFill")
04611 #ifndef EXCLUDE_FROM_XARALX
04612
04613 if (bpp > 8)
04614 {
04615
04616 if (CurrentColContext->GetColourPlate() != NULL &&
04617 !CurrentColContext->GetColourPlate()->IsDisabled())
04618 {
04619 if (CurrentColContext->GetColourPlate()->GetType() == COLOURPLATE_COMPOSITE)
04620 {
04621
04622 }
04623 else if (CurrentColContext->GetColourPlate()->GetType() == COLOURPLATE_SPOT)
04624 {
04625 GD->SetColour(0xFFFFFF);
04626 bDoBitmapFill = FALSE;
04627 }
04628 else if (CurrentColContext->GetColourPlate()->GetType() != COLOURPLATE_NONE)
04629 {
04630
04631 pSepTables = (BYTE *) CCMalloc(5 * 256 * sizeof(BYTE));
04632 if (pSepTables != NULL)
04633 {
04634 XaraCMS* lpCMSMan = GetApplication()->GetCMSManager();
04635 String_256 PrintProfile;
04636 if (lpCMSMan)
04637 lpCMSMan->GetPrinterProfile(&PrintProfile);
04638 ColourContextCMYK *cc = new ColourContextCMYK(RenderView, &PrintProfile);
04639 if (cc->GetProfileTables(pSepTables))
04640 {
04641
04642 pNewBitmap = (CWxBitmap*)WxBM->MakeSeparatedCopy(RenderView->GetColourPlate(), pSepTables);
04643 OrigWxBM = WxBM;
04644 WxBM = pNewBitmap;
04645 }
04646 delete cc;
04647 }
04648 }
04649 }
04650 }
04651 #endif
04652
04653
04654
04655 GD->SetDefaultBitmapParameters();
04656
04657 GD->SetTileSmoothingFlag(TRUE);
04658 GD->SetTileFilteringFlag(TRUE);
04659
04660 if (bDoBitmapFill)
04661 {
04662 GD->SetBitmapFill( &(WxBM->BMInfo->bmiHeader),
04663 WxBM->BMBytes,
04664 Style,
04665 PGram,
04666 DefaultColour,
04667 Palette,
04668 NULL, NULL, NULL,
04669 NULL,
04670 0
04671 );
04672 }
04673
04674
04675
04676 RECT BmpRect;
04677 BmpRect.left = 0;
04678 BmpRect.top = DestHeight;
04679 BmpRect.right = DestWidth;
04680 BmpRect.bottom = 0;
04681
04682 GD->FillRectangle(&BmpRect);
04683
04684
04685 if (IsPrinting())
04686 {
04687
04688
04689
04690
04691 DIBUtil::PlotDeepDIB( RenderDC, TempInfo, TempBits,
04692 BottomLeft.x, TopLeft.y,
04693 DestWidth,DestHeight,
04694 0,0,
04695 CONVHINT_PRINTER );
04696 }
04697 else
04698 {
04699
04700 wxPalette * hPal = NULL;
04701 if (RFlags.UsePalette)
04702 hPal = PaletteManager::GetPalette();
04703
04704
04705
04706
04707
04708 GRenderRegion::StaticPlotBitmap( RenderDC,
04709 DIBPal,
04710 TempInfo,
04711 TempBits,
04712 BottomLeft.x,
04713 TopLeft.y,
04714 DestWidth,
04715 DestHeight,
04716 hPal,
04717 0,0
04718 );
04719 }
04720
04721 FreeDIB(TempInfo, TempBits);
04722
04723 if (pNewBitmap)
04724 {
04725 WxBM = OrigWxBM;
04726 delete pNewBitmap;
04727 }
04728
04729
04730
04731
04732 if (Palette != WxBM->BMInfo->bmiColors)
04733 CCFree(Palette);
04734
04735 if (pSepTables)
04736 {
04737 GD->SetSeparationTables();
04738 CCFree(pSepTables);
04739 }
04740
04741 if (pCyanSepTable)
04742 CCFree(pCyanSepTable);
04743 if (pMagentaSepTable)
04744 CCFree(pMagentaSepTable);
04745 if (pYellowSepTable)
04746 CCFree(pYellowSepTable);
04747 if (pBlackSepTable)
04748 CCFree(pBlackSepTable);
04749 if (pUnderColourRemovalTable)
04750 CCFree(pUnderColourRemovalTable);
04751 if (pBlackGenerationTable)
04752 CCFree(pBlackGenerationTable);
04753
04754 return TRUE;
04755 }
04756
04757
04758 MILLIPOINT OSRenderRegion::CalcDistance(DocCoord a, DocCoord b)
04759 {
04760 const double Width = (double) a.x - b.x;
04761 const double Height = (double) a.y - b.y;
04762 double Diag = Width * Width + Height * Height;
04763 const INT32 Distance = (INT32) sqrt(Diag);
04764 return Distance;
04765 }
04766
04767 void OSRenderRegion::MakeEllipticalPath(Path *pPath, DocCoord Parallel[4])
04768 {
04769
04770 DocCoord NewCoords[12];
04771
04772
04773 NodeEllipse::CalcEllipseEdge(Parallel[0], Parallel[1], &NewCoords[11], &NewCoords[0], &NewCoords[1]);
04774 NodeEllipse::CalcEllipseEdge(Parallel[1], Parallel[2], &NewCoords[2], &NewCoords[3], &NewCoords[4]);
04775 NodeEllipse::CalcEllipseEdge(Parallel[2], Parallel[3], &NewCoords[5], &NewCoords[6], &NewCoords[7]);
04776 NodeEllipse::CalcEllipseEdge(Parallel[3], Parallel[0], &NewCoords[8], &NewCoords[9], &NewCoords[10]);
04777
04778
04779 pPath->ClearPath();
04780 pPath->FindStartOfPath();
04781
04782
04783 PathFlags NewFlags;
04784 NewFlags.IsRotate = TRUE;
04785 pPath->InsertMoveTo(NewCoords[0], &NewFlags);
04786 pPath->InsertCurveTo(NewCoords[1], NewCoords[2], NewCoords[3], &NewFlags);
04787 pPath->InsertCurveTo(NewCoords[4], NewCoords[5], NewCoords[6], &NewFlags);
04788 pPath->InsertCurveTo(NewCoords[7], NewCoords[8], NewCoords[9], &NewFlags);
04789 pPath->InsertCurveTo(NewCoords[10], NewCoords[11], NewCoords[0], &NewFlags);
04790
04791
04792 pPath->CloseSubPath();
04793 }
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810 BOOL OSRenderRegion::RenderGradFillPath(Path *PathToDraw, GradFillAttribute* Fill)
04811 {
04812 CCRuntimeClass *FillType = Fill->GetRuntimeClass();
04813
04814 if (FillType == CC_RUNTIME_CLASS(RadialFillAttribute))
04815 return RenderRadialFill(PathToDraw, (RadialFillAttribute *) Fill);
04816 else if (FillType == CC_RUNTIME_CLASS(LinearFillAttribute))
04817 return RenderLinearFill(PathToDraw, (LinearFillAttribute *) Fill);
04818 else if (FillType == CC_RUNTIME_CLASS(ConicalFillAttribute))
04819 return RenderConicalFill(PathToDraw, (ConicalFillAttribute *) Fill);
04820 else if (FillType == CC_RUNTIME_CLASS(SquareFillAttribute))
04821 return RenderSquareFill(PathToDraw, (SquareFillAttribute *) Fill);
04822 else if (FillType == CC_RUNTIME_CLASS(FourColFillAttribute))
04823 return RenderFourColFill(PathToDraw, (FourColFillAttribute *) Fill);
04824 else
04825 return FALSE;
04826 }
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848 static INT32 ColDifference(DocColour &Start, DocColour &End, INT32 Depth, EFFECTTYPE EffectType)
04849 {
04850
04851 INT32 StartRed, StartGreen, StartBlue;
04852 Start.GetRGBValue(&StartRed, &StartGreen, &StartBlue);
04853
04854 INT32 EndRed, EndGreen, EndBlue;
04855 End.GetRGBValue(&EndRed, &EndGreen, &EndBlue);
04856
04857
04858 INT32 Diff = Abs(StartRed-EndRed);
04859 INT32 Tmp = StartGreen - EndGreen;
04860 Diff = max(Abs(Tmp), Diff);
04861 Tmp = StartBlue - EndBlue;
04862 Diff = max(Abs(Tmp), Diff);
04863
04864
04865 if (Start.GetSpotParent() != NULL || End.GetSpotParent() != NULL)
04866 EffectType = EFFECT_RGB;
04867
04868
04869 if (EffectType == EFFECT_HSV_SHORT || EffectType == EFFECT_HSV_LONG)
04870 {
04871
04872 ColourContext *pContext = ColourContext::GetGlobalDefault(COLOURMODEL_HSVT);
04873 ERROR3IF(pContext == NULL, "No HSV context?!");
04874
04875 ColourHSVT StartDef;
04876 pContext->ConvertColour(&Start, (ColourGeneric *) &StartDef);
04877
04878 ColourHSVT EndDef;
04879 pContext->ConvertColour(&End, (ColourGeneric *) &EndDef);
04880
04881
04882 BOOL BlendNormally = TRUE;
04883
04884
04885 const double StartHue = StartDef.Hue.MakeDouble();
04886 const double EndHue = EndDef.Hue.MakeDouble();
04887
04888 double SimpleDist = StartHue - EndHue;
04889 if (SimpleDist < 0.0)
04890 SimpleDist = -SimpleDist;
04891
04892
04893 if (SimpleDist <= 0.5)
04894 BlendNormally = !(EffectType == EFFECT_HSV_LONG);
04895 else
04896 BlendNormally = (EffectType == EFFECT_HSV_LONG);
04897
04898
04899 INT32 HSVDiff = (INT32) (360.0 * SimpleDist);
04900 if (!BlendNormally)
04901 HSVDiff = 360 - HSVDiff;
04902
04903 if (HSVDiff > Diff)
04904 Diff = HSVDiff;
04905 }
04906
04907 return((Depth >= 24) ? Diff : Diff / 3);
04908 }
04909
04910
04911
04912 const INT32 MAX_FILL_STEPS = 128;
04913 const BOOL USE_GDI_CLIPPING = FALSE;
04914
04915 typedef enum
04916 {
04917 GF_USE_GDICLIPPING,
04918 GF_USE_GDIEOR,
04919 GF_USE_GAVINCLIPPING
04920 } GradFillMethodType;
04921
04922
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936 BOOL OSRenderRegion::RenderRadialFill(Path *PathToDraw, RadialFillAttribute *Fill)
04937 {
04938 GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
04939
04940 INT32 Radius1 = CalcDistance(Fill->StartPoint, Fill->EndPoint);
04941 INT32 Radius2 = CalcDistance(Fill->StartPoint, Fill->EndPoint2);
04942
04943
04944 SaveContext();
04945
04946
04947 SetLineColour(COLOUR_TRANS);
04948
04949
04950 FIXED16 PixelSize = 0;
04951 GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
04952 INT32 FillSteps = INT32( max( Radius1, Radius2 ) / PixelSize.MakeDouble() );
04953
04954
04955 FillSteps /= 4;
04956
04957
04958 EFFECTTYPE EffectType = GetFillEffect();
04959 FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour,
04960 IsPrinting() ? 24 : 8,
04961 EffectType ),
04962 FillSteps);
04963
04964
04965 FillSteps = min(FillSteps, INT32(MAX_FILL_STEPS));
04966
04967
04968 FillSteps = FillSteps / (1 << GradFillQuality);
04969 FillSteps = max(FillSteps, 10);
04970
04971
04972
04973
04974
04975 INT32 ClipFlatness = PixelSize.MakeLong() / 16;
04976 INT32 ClipTolerance = 0;
04977
04978 RGBQUAD ColourSteps[MAX_FILL_STEPS];
04979 GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
04980 GetRenderView(), EffectType,
04981 FillSteps, ColourSteps);
04982
04983
04984 if (RFlags.Metafile)
04985 {
04986 RenderMethod = GF_USE_GAVINCLIPPING;
04987 }
04988 else
04989 {
04990 if (!SetClipToPathTemporary(PathToDraw))
04991 {
04992
04993 RenderMethod = GF_USE_GDIEOR;
04994 }
04995 }
04996
04997 INT32 RenderCount = 1;
04998
04999 if (RenderMethod == GF_USE_GDIEOR)
05000 {
05001 SetDrawingMode(DM_EORDITHER);
05002 RenderCount = 2;
05003 }
05004
05005 DocColour TempFillColour;
05006
05007 while (RenderCount > 0)
05008 {
05009 COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed,
05010 ColourSteps[FillSteps - 1].rgbGreen,
05011 ColourSteps[FillSteps - 1].rgbBlue);
05012
05013
05014
05015 TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed,
05016 ColourSteps[FillSteps - 1].rgbGreen,
05017 ColourSteps[FillSteps - 1].rgbBlue);
05018 TempFillColour.SetSeparable(FALSE);
05019
05020 SetFillColour(TempFillColour);
05021
05022 GetValidBrush();
05023 GetValidPen();
05024
05025
05026
05027 Path PreviousPath;
05028 PreviousPath.Initialise(PathToDraw->GetNumCoords() + 2, 12);
05029 PreviousPath.CopyPathDataFrom(PathToDraw);
05030
05031
05032 DocCoord Steps[2];
05033 Steps[0].x = Fill->StartPoint.x - Fill->EndPoint.x;
05034 Steps[0].y = Fill->StartPoint.y - Fill->EndPoint.y;
05035 Steps[1].x = Fill->StartPoint.x - Fill->EndPoint2.x;
05036 Steps[1].y = Fill->StartPoint.y - Fill->EndPoint2.y;
05037
05038
05039
05040 DocCoord Parallel[4];
05041 Parallel[0].x = Fill->StartPoint.x + (Steps[0].x + Steps[1].x);
05042 Parallel[0].y = Fill->StartPoint.y + (Steps[0].y + Steps[1].y);
05043 Parallel[1].x = Fill->StartPoint.x + (Steps[0].x - Steps[1].x);
05044 Parallel[1].y = Fill->StartPoint.y + (Steps[0].y - Steps[1].y);
05045 Parallel[2].x = Fill->StartPoint.x - (Steps[0].x + Steps[1].x);
05046 Parallel[2].y = Fill->StartPoint.y - (Steps[0].y + Steps[1].y);
05047 Parallel[3].x = Fill->StartPoint.x + (Steps[1].x - Steps[0].x);
05048 Parallel[3].y = Fill->StartPoint.y + (Steps[1].y - Steps[0].y);
05049
05050
05051
05052 Steps[0].x /= (FillSteps + 1);
05053 Steps[0].y /= (FillSteps + 1);
05054 Steps[1].x /= (FillSteps + 1);
05055 Steps[1].y /= (FillSteps + 1);
05056
05057
05058 Path RadialFill;
05059 RadialFill.Initialise(50,12);
05060 Path EllipsePath;
05061 EllipsePath.Initialise(15,12);
05062
05063
05064 Path ClippedPath;
05065 ClippedPath.Initialise(12, 12);
05066
05067
05068
05069 for (INT32 i = FillSteps; i > 0;)
05070 {
05071 MakeEllipticalPath(&EllipsePath, Parallel);
05072 EllipsePath.IsFilled = TRUE;
05073
05074
05075 RadialFill.ClearPath(FALSE);
05076 RadialFill.MakeSpaceInPath(PreviousPath.GetNumCoords() + EllipsePath.GetNumCoords() + 2);
05077 RadialFill.CopyPathDataFrom(&PreviousPath);
05078 RadialFill.IsFilled = TRUE;
05079 if (i > 1)
05080 {
05081
05082
05083 ERROR2IF(!RadialFill.MergeTwoPaths(EllipsePath), FALSE, "could not merge paths");
05084 }
05085
05086
05087 PreviousPath.ClearPath(FALSE);
05088 PreviousPath.MakeSpaceInPath(EllipsePath.GetNumCoords() + 2);
05089 PreviousPath.CopyPathDataFrom(&EllipsePath);
05090
05091 if (RenderMethod != GF_USE_GAVINCLIPPING)
05092 {
05093 RenderPath(&RadialFill);
05094 }
05095 else
05096 {
05097 PathToDraw->ClipPathToPath(RadialFill, &ClippedPath, 2,
05098 ClipTolerance, ClipFlatness, ClipFlatness);
05099 ClippedPath.IsFilled = TRUE;
05100 RenderPath(&ClippedPath);
05101 }
05102
05103
05104 i--;
05105
05106 if (i > 0)
05107 {
05108
05109 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05110 ColourSteps[i].rgbBlue);
05111 if (NewFill != CurrentCol)
05112 {
05113
05114 CurrentCol = NewFill;
05115
05116
05117
05118 TempFillColour.SetRGBValue(ColourSteps[i].rgbRed,
05119 ColourSteps[i].rgbGreen,
05120 ColourSteps[i].rgbBlue);
05121 TempFillColour.SetSeparable(FALSE);
05122
05123 SetFillColour(TempFillColour);
05124 GetValidBrush();
05125 GetValidPen();
05126 }
05127
05128
05129 Parallel[0].x -= (Steps[0].x + Steps[1].x);
05130 Parallel[0].y -= (Steps[0].y + Steps[1].y);
05131 Parallel[1].x -= (Steps[0].x - Steps[1].x);
05132 Parallel[1].y -= (Steps[0].y - Steps[1].y);
05133 Parallel[2].x += (Steps[0].x + Steps[1].x);
05134 Parallel[2].y += (Steps[0].y + Steps[1].y);
05135 Parallel[3].x -= (Steps[1].x - Steps[0].x);
05136 Parallel[3].y -= (Steps[1].y - Steps[0].y);
05137 }
05138 }
05139
05140 if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05141 {
05142
05143 SetDrawingMode(DM_COPYPEN);
05144 SetFillColour(COLOUR_BLACK);
05145 SetLineColour(COLOUR_TRANS);
05146 GetValidBrush();
05147 GetValidPen();
05148 RenderPath(PathToDraw);
05149
05150
05151 SetDrawingMode(DM_EORDITHER);
05152 }
05153
05154 RenderCount--;
05155 }
05156
05157
05158 RestoreContext();
05159 GetValidBrush();
05160 GetValidPen();
05161
05162
05163 if (RenderMethod == GF_USE_GDICLIPPING)
05164 RenderDC->SetClippingRegion( *OSClipRegion );
05165
05166 return TRUE;
05167 }
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182
05183 BOOL OSRenderRegion::RenderLinearFill(Path *PathToDraw, LinearFillAttribute *Fill)
05184 {
05185 GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05186
05187
05188
05189
05190
05191
05192 DocRect BoundsRect = PathToDraw->GetBoundingRect();
05193
05194 DocCoord TestPoint = BoundsRect.lo;
05195 INT32 Distance = CalcDistance(Fill->StartPoint, TestPoint);
05196 TestPoint.x = BoundsRect.hi.x;
05197 INT32 NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05198 Distance = max(Distance, NewDistance);
05199 TestPoint = BoundsRect.hi;
05200 NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05201 Distance = max(Distance, NewDistance);
05202 TestPoint.x = BoundsRect.lo.x;
05203 NewDistance = CalcDistance(Fill->StartPoint, TestPoint);
05204 Distance = max(Distance, NewDistance);
05205
05206
05207
05208
05209
05210 SaveContext();
05211
05212
05213 SetLineColour(COLOUR_TRANS);
05214
05215
05216 FIXED16 PixelSize = 0;
05217 GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05218
05219
05220 INT32 FillLength = CalcDistance(Fill->StartPoint, Fill->EndPoint);
05221
05222
05223 INT32 FillSteps = (INT32) ((FillLength / PixelSize.MakeDouble()) / 4);
05224
05225
05226 EFFECTTYPE EffectType = GetFillEffect();
05227 FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour,
05228 IsPrinting() ? 24 : 8,
05229 EffectType),
05230 FillSteps);
05231
05232
05233 FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05234
05235
05236 FillSteps = FillSteps / (1 << GradFillQuality);
05237
05238 FillSteps = max(FillSteps, 10);
05239
05240
05241
05242
05243
05244 INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05245 INT32 ClipTolerance = 0;
05246
05247 RGBQUAD ColourSteps[MAX_FILL_STEPS];
05248 GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05249 GetRenderView(), EffectType,
05250 FillSteps, ColourSteps);
05251 INT32 RenderCount = 1;
05252
05253
05254 if (RFlags.Metafile)
05255 {
05256 RenderMethod = GF_USE_GAVINCLIPPING;
05257 }
05258 else
05259 {
05260 if (!SetClipToPathTemporary(PathToDraw))
05261 {
05262
05263 RenderMethod = GF_USE_GDIEOR;
05264 SetDrawingMode(DM_EORDITHER);
05265 RenderCount = 2;
05266 }
05267 }
05268
05269 DocColour TempFillColour;
05270
05271 while (RenderCount > 0)
05272 {
05273 COLORREF CurrentCol = RGB(ColourSteps[0].rgbRed, ColourSteps[0].rgbGreen, ColourSteps[0].rgbBlue);
05274
05275
05276
05277 TempFillColour.SetRGBValue(ColourSteps[0].rgbRed,
05278 ColourSteps[0].rgbGreen,
05279 ColourSteps[0].rgbBlue);
05280 TempFillColour.SetSeparable(FALSE);
05281
05282 SetFillColour(TempFillColour);
05283 GetValidBrush();
05284 GetValidPen();
05285
05286
05287 Path LinearFill;
05288 LinearFill.Initialise(12,12);
05289
05290
05291 Path ClippedPath;
05292 ClippedPath.Initialise(12, 12);
05293
05294
05295 double FillStepX = ((double) (Fill->EndPoint.x - Fill->StartPoint.x)) / (double) FillSteps;
05296 double FillStepY = ((double) (Fill->EndPoint.y - Fill->StartPoint.y)) / (double) FillSteps;
05297
05298 double FillAngle = atan2((double)(Fill->EndPoint.x - Fill->StartPoint.x),
05299 (double)(Fill->EndPoint.y - Fill->StartPoint.y));
05300
05301
05302 const double HalfPI = PI/2.0;
05303
05304 DocCoord FillPoint = Fill->StartPoint;
05305 DocCoord RectPoint[2];
05306
05307
05308 RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05309 RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05310 RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05311 RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05312
05313
05314
05315
05316
05317 TestPoint = BoundsRect.lo;
05318 INT32 LastDistance = CalcDistance(Fill->EndPoint, TestPoint);
05319 TestPoint.x = BoundsRect.hi.x;
05320 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05321 LastDistance = max(LastDistance, NewDistance);
05322 TestPoint = BoundsRect.hi;
05323 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05324 LastDistance = max(LastDistance, NewDistance);
05325 TestPoint.x = BoundsRect.lo.x;
05326 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05327 LastDistance = max(LastDistance, NewDistance);
05328
05329
05330 LinearFill.ClearPath();
05331 LinearFill.FindStartOfPath();
05332
05333
05334 PathFlags NewFlags;
05335 NewFlags.IsRotate = TRUE;
05336
05337
05338 LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05339 LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05340
05341
05342 FillPoint.x = Fill->EndPoint.x - (MILLIPOINT) (LastDistance * sin(FillAngle));
05343 FillPoint.y = Fill->EndPoint.y - (MILLIPOINT) (LastDistance * cos(FillAngle));
05344
05345
05346 DocCoord EndPoint[2];
05347 EndPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05348 EndPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05349 EndPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05350 EndPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05351
05352
05353 LinearFill.InsertLineTo(EndPoint[1], &NewFlags);
05354 LinearFill.InsertLineTo(EndPoint[0], &NewFlags);
05355
05356
05357 LinearFill.CloseSubPath();
05358
05359 LinearFill.IsFilled = TRUE;
05360 if (RenderMethod != GF_USE_GAVINCLIPPING)
05361 {
05362 RenderPath(&LinearFill);
05363 }
05364 else
05365 {
05366 PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05367 ClipTolerance, ClipFlatness, ClipFlatness);
05368 ClippedPath.IsFilled = TRUE;
05369 RenderPath(&ClippedPath);
05370 }
05371
05372
05373
05374 for (INT32 i = 0; i < FillSteps;)
05375 {
05376 LinearFill.ClearPath();
05377 LinearFill.FindStartOfPath();
05378
05379
05380 PathFlags NewFlags;
05381 NewFlags.IsRotate = TRUE;
05382
05383
05384 LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05385 LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05386
05387
05388 i++;
05389
05390
05391 FillPoint.x = Fill->StartPoint.x + (MILLIPOINT) (i * FillStepX);
05392 FillPoint.y = Fill->StartPoint.y + (MILLIPOINT) (i * FillStepY);
05393
05394
05395 RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05396 RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05397 RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05398 RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05399
05400
05401 LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05402 LinearFill.InsertLineTo(RectPoint[0], &NewFlags);
05403
05404
05405 LinearFill.CloseSubPath();
05406
05407 LinearFill.IsFilled = TRUE;
05408 if (RenderMethod != GF_USE_GAVINCLIPPING)
05409 {
05410 RenderPath(&LinearFill);
05411 }
05412 else
05413 {
05414 PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05415 ClipTolerance, ClipFlatness, ClipFlatness);
05416 ClippedPath.IsFilled = TRUE;
05417 RenderPath(&ClippedPath);
05418 }
05419
05420 if (i != FillSteps)
05421 {
05422
05423 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05424 ColourSteps[i].rgbBlue);
05425 if (NewFill != CurrentCol)
05426 {
05427
05428 CurrentCol = NewFill;
05429
05430
05431
05432 TempFillColour.SetRGBValue(ColourSteps[i].rgbRed,
05433 ColourSteps[i].rgbGreen,
05434 ColourSteps[i].rgbBlue);
05435 TempFillColour.SetSeparable(FALSE);
05436
05437 SetFillColour(TempFillColour);
05438 GetValidBrush();
05439 GetValidPen();
05440 }
05441 }
05442 }
05443
05444
05445
05446 TestPoint = BoundsRect.lo;
05447 LastDistance = CalcDistance(Fill->EndPoint, TestPoint);
05448 TestPoint.x = BoundsRect.hi.x;
05449 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05450 LastDistance = max(LastDistance, NewDistance);
05451 TestPoint = BoundsRect.hi;
05452 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05453 LastDistance = max(LastDistance, NewDistance);
05454 TestPoint.x = BoundsRect.lo.x;
05455 NewDistance = CalcDistance(Fill->EndPoint, TestPoint);
05456 LastDistance = max(LastDistance, NewDistance);
05457
05458
05459 LinearFill.ClearPath();
05460 LinearFill.FindStartOfPath();
05461
05462
05463 NewFlags.IsRotate = TRUE;
05464
05465
05466 LinearFill.InsertMoveTo(RectPoint[0], &NewFlags);
05467 LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05468
05469
05470 FillPoint.x = Fill->EndPoint.x + (MILLIPOINT) (LastDistance * sin(FillAngle));
05471 FillPoint.y = Fill->EndPoint.y + (MILLIPOINT) (LastDistance * cos(FillAngle));
05472
05473
05474 RectPoint[0].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle - HalfPI));
05475 RectPoint[0].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle - HalfPI));
05476 RectPoint[1].x = FillPoint.x + (INT32) (((double) Distance) * sin(FillAngle + HalfPI));
05477 RectPoint[1].y = FillPoint.y + (INT32) (((double) Distance) * cos(FillAngle + HalfPI));
05478
05479
05480 LinearFill.InsertLineTo(RectPoint[1], &NewFlags);
05481 LinearFill.InsertLineTo(RectPoint[0], &NewFlags);
05482
05483
05484 LinearFill.CloseSubPath();
05485
05486 LinearFill.IsFilled = TRUE;
05487 if (RenderMethod != GF_USE_GAVINCLIPPING)
05488 {
05489 RenderPath(&LinearFill);
05490 }
05491 else
05492 {
05493 PathToDraw->ClipPathToPath(LinearFill, &ClippedPath, 2,
05494 ClipTolerance, ClipFlatness, ClipFlatness);
05495 ClippedPath.IsFilled = TRUE;
05496 RenderPath(&ClippedPath);
05497 }
05498
05499 if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05500 {
05501
05502 SetDrawingMode(DM_COPYPEN);
05503 SetFillColour(COLOUR_BLACK);
05504 SetLineColour(COLOUR_TRANS);
05505 GetValidBrush();
05506 GetValidPen();
05507 RenderPath(PathToDraw);
05508
05509
05510 SetDrawingMode(DM_EORDITHER);
05511 }
05512
05513 RenderCount--;
05514 }
05515
05516
05517 RestoreContext();
05518 GetValidBrush();
05519 GetValidPen();
05520
05521
05522 if (RenderMethod == GF_USE_GDICLIPPING)
05523 RenderDC->SetClippingRegion(*OSClipRegion);
05524
05525 return TRUE;
05526 }
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542 BOOL OSRenderRegion::RenderConicalFill(Path *PathToDraw, ConicalFillAttribute *Fill)
05543 {
05544 GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05545
05546
05547
05548
05549
05550 DocRect BoundsRect = PathToDraw->GetBoundingRect();
05551
05552 DocCoord TestPoint = BoundsRect.lo;
05553 INT32 Radius = CalcDistance(Fill->StartPoint, TestPoint);
05554 TestPoint.x = BoundsRect.hi.x;
05555 INT32 NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05556 Radius = max(Radius, NewRadius);
05557 TestPoint = BoundsRect.hi;
05558 NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05559 Radius = max(Radius, NewRadius);
05560 TestPoint.x = BoundsRect.lo.x;
05561 NewRadius = CalcDistance(Fill->StartPoint, TestPoint);
05562 Radius = max(Radius, NewRadius);
05563
05564
05565
05566
05567 SaveContext();
05568
05569
05570 SetLineColour(COLOUR_TRANS);
05571
05572
05573 FIXED16 PixelSize = 0;
05574 GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05575 INT32 FillSteps = (INT32) ((Radius * 2 * PI) / PixelSize.MakeDouble());
05576
05577
05578 FillSteps /= 4;
05579
05580
05581 EFFECTTYPE EffectType = GetFillEffect();
05582 FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour,
05583 IsPrinting() ? 24 : 8,
05584 EffectType),
05585 FillSteps);
05586
05587
05588 FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05589
05590
05591 FillSteps = FillSteps / (1 << GradFillQuality);
05592
05593
05594
05595
05596 FillSteps /= 2;
05597
05598
05599 FillSteps = max(FillSteps, 10);
05600
05601
05602
05603
05604
05605 INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05606 INT32 ClipTolerance = 0;
05607
05608 RGBQUAD ColourSteps[MAX_FILL_STEPS];
05609 GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05610 GetRenderView(), EffectType,
05611 FillSteps, ColourSteps);
05612
05613
05614
05615 if (RFlags.Metafile)
05616 {
05617 RenderMethod = GF_USE_GAVINCLIPPING;
05618 }
05619 else
05620 {
05621 if (!SetClipToPathTemporary(PathToDraw))
05622 {
05623
05624 RenderMethod = GF_USE_GDIEOR;
05625 }
05626 }
05627
05628 INT32 RenderCount = 1;
05629
05630 if (RenderMethod == GF_USE_GDIEOR)
05631 {
05632 SetDrawingMode(DM_EORDITHER);
05633 RenderCount = 2;
05634 }
05635
05636 DocColour TempFillColour;
05637
05638 while (RenderCount > 0)
05639 {
05640 COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed,
05641 ColourSteps[FillSteps - 1].rgbGreen,
05642 ColourSteps[FillSteps - 1].rgbBlue);
05643
05644
05645
05646 TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed,
05647 ColourSteps[FillSteps - 1].rgbGreen,
05648 ColourSteps[FillSteps - 1].rgbBlue);
05649 TempFillColour.SetSeparable(FALSE);
05650
05651 SetFillColour(TempFillColour);
05652 GetValidBrush();
05653 GetValidPen();
05654
05655
05656 Path ConicalFill;
05657 ConicalFill.Initialise(12,12);
05658
05659
05660 Path ClippedPath;
05661 ClippedPath.Initialise(12, 12);
05662
05663 double FillAngle = atan2((double)(Fill->EndPoint.x - Fill->StartPoint.x),
05664 (double)(Fill->EndPoint.y - Fill->StartPoint.y));
05665
05666 double AngleInc = PI / FillSteps;
05667
05668 TestPoint.x = Fill->StartPoint.x + (INT32) (((double) Radius) * sin(FillAngle));
05669 TestPoint.y = Fill->StartPoint.y + (INT32) (((double) Radius) * cos(FillAngle));
05670
05671
05672 INT32 FillInc = -1;
05673
05674
05675
05676 for (INT32 i = FillSteps - 1; i <= FillSteps; i += FillInc)
05677 {
05678 ConicalFill.ClearPath();
05679 ConicalFill.FindStartOfPath();
05680
05681
05682 PathFlags NewFlags;
05683 NewFlags.IsRotate = TRUE;
05684 ConicalFill.InsertMoveTo(Fill->StartPoint, &NewFlags);
05685 ConicalFill.InsertLineTo(TestPoint, &NewFlags);
05686 FillAngle += AngleInc;
05687 TestPoint.x = Fill->StartPoint.x + (INT32) (((double) Radius) * sin(FillAngle));
05688 TestPoint.y = Fill->StartPoint.y + (INT32) (((double) Radius) * cos(FillAngle));
05689 ConicalFill.InsertLineTo(TestPoint, &NewFlags);
05690
05691
05692 ConicalFill.CloseSubPath();
05693
05694 ConicalFill.IsFilled = TRUE;
05695
05696 if (RenderMethod != GF_USE_GAVINCLIPPING)
05697 {
05698 RenderPath(&ConicalFill);
05699 }
05700 else
05701 {
05702 PathToDraw->ClipPathToPath(ConicalFill, &ClippedPath, 2,
05703 ClipTolerance, ClipFlatness, ClipFlatness);
05704 ClippedPath.IsFilled = TRUE;
05705 RenderPath(&ClippedPath);
05706 }
05707
05708
05709
05710 if (i <= 0)
05711
05712 FillInc = 1;
05713
05714
05715 if (i != FillSteps)
05716 {
05717 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed,
05718 ColourSteps[i].rgbGreen,
05719 ColourSteps[i].rgbBlue);
05720 if (NewFill != CurrentCol)
05721 {
05722
05723 CurrentCol = NewFill;
05724
05725
05726
05727 TempFillColour.SetRGBValue(ColourSteps[i].rgbRed,
05728 ColourSteps[i].rgbGreen,
05729 ColourSteps[i].rgbBlue);
05730 TempFillColour.SetSeparable(FALSE);
05731
05732 SetFillColour(TempFillColour);
05733 GetValidBrush();
05734 GetValidPen();
05735 }
05736 }
05737 }
05738
05739 if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05740 {
05741
05742 SetDrawingMode(DM_COPYPEN);
05743 SetFillColour(COLOUR_BLACK);
05744 SetLineColour(COLOUR_TRANS);
05745 GetValidBrush();
05746 GetValidPen();
05747 RenderPath(PathToDraw);
05748
05749
05750 SetDrawingMode(DM_EORDITHER);
05751 }
05752
05753 RenderCount--;
05754 }
05755
05756
05757 RestoreContext();
05758 GetValidBrush();
05759 GetValidPen();
05760
05761
05762 if (RenderMethod == GF_USE_GDICLIPPING)
05763 RenderDC->SetClippingRegion(*OSClipRegion);
05764
05765 return TRUE;
05766 }
05767
05768
05769
05770
05771
05772
05773
05774
05775
05776
05777
05778
05779
05780
05781
05782 BOOL OSRenderRegion::RenderSquareFill(Path *PathToDraw, SquareFillAttribute *Fill)
05783 {
05784 GradFillMethodType RenderMethod = GF_USE_GDICLIPPING;
05785
05786 INT32 Radius1 = CalcDistance(Fill->StartPoint, Fill->EndPoint);
05787 INT32 Radius2 = CalcDistance(Fill->StartPoint, Fill->EndPoint2);
05788
05789
05790 SaveContext();
05791
05792
05793 SetLineColour(COLOUR_TRANS);
05794
05795
05796 FIXED16 PixelSize = 0;
05797 GetRenderView()->GetScaledPixelSize(&PixelSize,&PixelSize);
05798 INT32 FillSteps = (INT32) (max(Radius1, Radius2) / PixelSize.MakeDouble());
05799
05800
05801 FillSteps /= 4;
05802
05803
05804 EFFECTTYPE EffectType = GetFillEffect();
05805 FillSteps = min(ColDifference(Fill->Colour, Fill->EndColour,
05806 IsPrinting() ? 24 : 8,
05807 EffectType),
05808 FillSteps);
05809
05810
05811 FillSteps = min( FillSteps, INT32(MAX_FILL_STEPS) );
05812
05813
05814 FillSteps = FillSteps / (1 << GradFillQuality);
05815 FillSteps = max(FillSteps, 10);
05816
05817
05818
05819
05820
05821 INT32 ClipFlatness = PixelSize.MakeLong() / 16;
05822 INT32 ClipTolerance = 0;
05823
05824 RGBQUAD ColourSteps[MAX_FILL_STEPS];
05825 GradTable32::BuildGraduatedPalette(Fill->Colour, Fill->EndColour,
05826 GetRenderView(), EffectType,
05827 FillSteps, ColourSteps);
05828
05829
05830 if (RFlags.Metafile)
05831 {
05832 RenderMethod = GF_USE_GAVINCLIPPING;
05833 }
05834 else
05835 {
05836 if (!SetClipToPathTemporary(PathToDraw))
05837 {
05838
05839 RenderMethod = GF_USE_GDIEOR;
05840 }
05841 }
05842
05843 INT32 RenderCount = 1;
05844
05845 if (RenderMethod == GF_USE_GDIEOR)
05846 {
05847 SetDrawingMode(DM_EORDITHER);
05848 RenderCount = 2;
05849 }
05850
05851 DocColour TempFillColour;
05852
05853 while (RenderCount > 0)
05854 {
05855 COLORREF CurrentCol = RGB(ColourSteps[FillSteps - 1].rgbRed,
05856 ColourSteps[FillSteps - 1].rgbGreen,
05857 ColourSteps[FillSteps - 1].rgbBlue);
05858
05859
05860
05861 TempFillColour.SetRGBValue(ColourSteps[FillSteps - 1].rgbRed,
05862 ColourSteps[FillSteps - 1].rgbGreen,
05863 ColourSteps[FillSteps - 1].rgbBlue);
05864 TempFillColour.SetSeparable(FALSE);
05865
05866 SetFillColour(TempFillColour);
05867
05868 GetValidBrush();
05869 GetValidPen();
05870
05871
05872
05873 Path PreviousPath;
05874 PreviousPath.Initialise(PathToDraw->GetNumCoords() + 2, 12);
05875 PreviousPath.CopyPathDataFrom(PathToDraw);
05876
05877
05878 DocCoord Steps[2];
05879 Steps[0].x = Fill->StartPoint.x - Fill->EndPoint.x;
05880 Steps[0].y = Fill->StartPoint.y - Fill->EndPoint.y;
05881 Steps[1].x = Fill->StartPoint.x - Fill->EndPoint2.x;
05882 Steps[1].y = Fill->StartPoint.y - Fill->EndPoint2.y;
05883
05884
05885 DocCoord Parallel[4];
05886 Parallel[0].x = Fill->StartPoint.x + (Steps[0].x + Steps[1].x);
05887 Parallel[0].y = Fill->StartPoint.y + (Steps[0].y + Steps[1].y);
05888 Parallel[1].x = Fill->StartPoint.x + (Steps[0].x - Steps[1].x);
05889 Parallel[1].y = Fill->StartPoint.y + (Steps[0].y - Steps[1].y);
05890 Parallel[2].x = Fill->StartPoint.x - (Steps[0].x + Steps[1].x);
05891 Parallel[2].y = Fill->StartPoint.y - (Steps[0].y + Steps[1].y);
05892 Parallel[3].x = Fill->StartPoint.x + (Steps[1].x - Steps[0].x);
05893 Parallel[3].y = Fill->StartPoint.y + (Steps[1].y - Steps[0].y);
05894
05895
05896
05897 Steps[0].x /= (FillSteps + 1);
05898 Steps[0].y /= (FillSteps + 1);
05899 Steps[1].x /= (FillSteps + 1);
05900 Steps[1].y /= (FillSteps + 1);
05901
05902
05903 Path SquareFill;
05904 SquareFill.Initialise(50,12);
05905 Path ParallelogramPath;
05906 ParallelogramPath.Initialise(15,12);
05907
05908
05909 Path ClippedPath;
05910 ClippedPath.Initialise(12, 12);
05911
05912
05913 for (INT32 i = FillSteps; i > 0;)
05914 {
05915
05916 ParallelogramPath.ClearPath();
05917 ParallelogramPath.FindStartOfPath();
05918 ParallelogramPath.InsertMoveTo(Parallel[0]);
05919 ParallelogramPath.InsertLineTo(Parallel[1]);
05920 ParallelogramPath.InsertLineTo(Parallel[2]);
05921 ParallelogramPath.InsertLineTo(Parallel[3]);
05922 ParallelogramPath.InsertLineTo(Parallel[0]);
05923 ParallelogramPath.IsFilled = TRUE;
05924
05925
05926 SquareFill.ClearPath(FALSE);
05927 SquareFill.MakeSpaceInPath(PreviousPath.GetNumCoords() + ParallelogramPath.GetNumCoords() + 2);
05928 SquareFill.CopyPathDataFrom(&PreviousPath);
05929 SquareFill.IsFilled = TRUE;
05930 if (i > 1)
05931 {
05932
05933
05934 ERROR2IF(!SquareFill.MergeTwoPaths(ParallelogramPath), FALSE, "could not merge paths");
05935 }
05936
05937
05938 PreviousPath.ClearPath(FALSE);
05939 PreviousPath.MakeSpaceInPath(ParallelogramPath.GetNumCoords() + 2);
05940 PreviousPath.CopyPathDataFrom(&ParallelogramPath);
05941
05942 if (RenderMethod != GF_USE_GAVINCLIPPING)
05943 {
05944 RenderPath(&SquareFill);
05945 }
05946 else
05947 {
05948 PathToDraw->ClipPathToPath(SquareFill, &ClippedPath, 2,
05949 ClipTolerance, ClipFlatness, ClipFlatness);
05950 ClippedPath.IsFilled = TRUE;
05951 RenderPath(&ClippedPath);
05952 }
05953
05954
05955 i--;
05956
05957 if (i > 0)
05958 {
05959
05960 const COLORREF NewFill = RGB(ColourSteps[i].rgbRed, ColourSteps[i].rgbGreen,
05961 ColourSteps[i].rgbBlue);
05962 if (NewFill != CurrentCol)
05963 {
05964
05965 CurrentCol = NewFill;
05966
05967
05968
05969 TempFillColour.SetRGBValue(ColourSteps[i].rgbRed,
05970 ColourSteps[i].rgbGreen,
05971 ColourSteps[i].rgbBlue);
05972 TempFillColour.SetSeparable(FALSE);
05973
05974 SetFillColour(TempFillColour);
05975 GetValidBrush();
05976 GetValidPen();
05977 }
05978
05979
05980 Parallel[0].x -= (Steps[0].x + Steps[1].x);
05981 Parallel[0].y -= (Steps[0].y + Steps[1].y);
05982 Parallel[1].x -= (Steps[0].x - Steps[1].x);
05983 Parallel[1].y -= (Steps[0].y - Steps[1].y);
05984 Parallel[2].x += (Steps[0].x + Steps[1].x);
05985 Parallel[2].y += (Steps[0].y + Steps[1].y);
05986 Parallel[3].x -= (Steps[1].x - Steps[0].x);
05987 Parallel[3].y -= (Steps[1].y - Steps[0].y);
05988 }
05989 }
05990
05991 if ((RenderMethod == GF_USE_GDIEOR) && (RenderCount > 1))
05992 {
05993
05994 SetDrawingMode(DM_COPYPEN);
05995 SetFillColour(COLOUR_BLACK);
05996 SetLineColour(COLOUR_TRANS);
05997 GetValidBrush();
05998 GetValidPen();
05999 RenderPath(PathToDraw);
06000
06001
06002 SetDrawingMode(DM_EORDITHER);
06003 }
06004
06005 RenderCount--;
06006 }
06007
06008
06009 RestoreContext();
06010 GetValidBrush();
06011 GetValidPen();
06012
06013
06014 if (RenderMethod == GF_USE_GDICLIPPING)
06015 RenderDC->SetClippingRegion(*OSClipRegion);
06016
06017 return TRUE;
06018 }
06019
06020
06021
06022
06023
06024
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035 BOOL OSRenderRegion::RenderThreeColFill ( Path *PathToDraw,
06036 ThreeColFillAttribute *Fill )
06037 {
06038
06039 DocCoord EndPoint ( *( Fill->GetEndPoint () ) + *( Fill->GetEndPoint2 () )
06040 - *( Fill->GetStartPoint () ) );
06041 DocColour EndColour;
06042 LinearFillAttribute LinearFill;
06043
06044
06045 EndColour.Mix ( Fill->GetEndColour (), Fill->GetEndColour2 (),
06046 0.5f, NULL, FALSE, NULL );
06047
06048
06049 LinearFill.SetStartPoint ( Fill->GetStartPoint () );
06050 LinearFill.SetEndPoint ( &EndPoint );
06051 LinearFill.SetStartColour ( Fill->GetStartColour () );
06052 LinearFill.SetEndColour ( &EndColour );
06053
06054
06055 RenderLinearFill ( PathToDraw, &LinearFill );
06056
06057 return TRUE;
06058 }
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075
06076
06077
06078
06079 BOOL OSRenderRegion::RenderFourColFill ( Path *PathToDraw,
06080 FourColFillAttribute *Fill )
06081 {
06082
06083 LinearFillAttribute LinearFill;
06084
06085
06086 LinearFill.SetStartPoint ( Fill->GetStartPoint () );
06087 LinearFill.SetEndPoint ( Fill->GetEndPoint3 () );
06088 LinearFill.SetStartColour ( Fill->GetStartColour () );
06089 LinearFill.SetEndColour ( Fill->GetEndColour3 () );
06090
06091
06092 RenderLinearFill ( PathToDraw, &LinearFill );
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106
06107
06108
06109
06110
06111
06112
06113
06114
06115
06116
06117
06118
06119
06120
06121
06122
06123
06124
06125
06126
06127
06128
06129
06130
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142
06143
06144
06145
06146
06147
06148
06149
06150
06151
06152
06153
06154
06155
06156
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182
06183
06184
06185
06186
06187
06188
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213
06214
06215
06216
06217
06218
06219
06220
06221
06222
06223
06224
06225
06226
06227
06228
06229
06230
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256
06257
06258
06259
06260
06261
06262
06263
06264
06265
06266
06267
06268
06269
06270
06271
06272
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299
06300
06301
06302
06303
06304
06305
06306
06307
06308
06309
06310
06311
06312
06313
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343
06344 return TRUE;
06345 }
06346
06347 BOOL OSRenderRegion::RawRenderPath32( Path *const DrawPath )
06348 {
06349 PORTNOTETRACE("other","OSRenderRegion::RawRenderPath32 - do nothing");
06350 #ifndef EXCLUDE_FROM_XARALX
06351 BOOL Worked;
06352
06353
06354 INT32 NumCoords = DrawPath->GetNumCoords();
06355 ENSURE(NumCoords>0, "Tried to draw a path with no elements in it in OSRenderRegion::RawRenderPath32");
06356 if (NumCoords==0)
06357 return FALSE;
06358
06359
06360 DocCoord* Coords = DrawPath->GetCoordArray();
06361
06362
06363 POINT* NTCoords = (POINT*)CCMalloc( sizeof(POINT)*NumCoords );
06364
06365 if (NTCoords==NULL)
06366 {
06367 TRACE( _T("No memory to convert curve\n") );
06368 return FALSE;
06369 }
06370
06371
06372 for (INT32 i=0; i<NumCoords; i++)
06373 NTCoords[i] = DocCoordToWin(Coords[i]);
06374
06375
06376 Worked = BeginPath( RenderDC );
06377 if (Worked)
06378 {
06379 Worked = NewPolyDraw( NTCoords, DrawPath->GetVerbArray(), NumCoords );
06380 if (Worked)
06381 Worked = EndPath( RenderDC );
06382 }
06383
06384 CCFree( NTCoords );
06385
06386 if (!Worked)
06387 TRACE( _T("Raw render32 failed"));
06388
06389 return Worked;
06390 #else
06391 ENSURE(FALSE, "Raw32 cannot work on win16");
06392 return FALSE;
06393 #endif
06394 }
06395
06396
06397
06398
06399
06400
06401
06402
06403
06404
06405
06406
06407
06408
06409 void OSRenderRegion::RenderPath32( Path *DrawPath )
06410 {
06411 PORTNOTETRACE("other","OSRenderRegion::RenderPath32 - do nothing");
06412 #ifndef EXCLUDE_FROM_XARALX
06413 const wxDC* dc = RenderDC;
06414
06415
06416
06417 BOOL ExtendedFill = FALSE;
06418
06419
06420 FillGeometryAttribute *pFillProvider =
06421 (FillGeometryAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
06422
06423 if (pFillProvider->GetRuntimeClass() != CC_RUNTIME_CLASS(FlatFillAttribute))
06424 ExtendedFill = TRUE;
06425
06426
06427 if (RRQuality.GetFillQuality() < Quality::Graduated)
06428 ExtendedFill = FALSE;
06429
06430
06431
06432
06433
06434
06435
06436
06437 if (ExtendedFill)
06438 {
06439 if (!pFillProvider->RenderFill(this, DrawPath))
06440
06441 ExtendedFill = FALSE;
06442 }
06443
06444
06445 BOOL Result = RawRenderPath32( DrawPath );
06446
06447 if (!Result)
06448 {
06449 TRACE( _T("RawRenderPath failed"));
06450 return;
06451 }
06452
06453
06454
06455 if (DrawPath->IsFilled && !ExtendedFill)
06456 StrokeAndFillPath( dc );
06457 else
06458 StrokePath( dc );
06459
06460 #endif
06461 }
06462
06463
06464
06465
06466
06467
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479 void OSRenderRegion::GetRenderRegionCaps(RRCaps* pCaps)
06480 {
06481
06482 pCaps->CanDoNothing();
06483
06484
06485 pCaps->GradFills = TRUE;
06486 pCaps->LineAttrs = TRUE;
06487 pCaps->ArrowHeads = TRUE;
06488 pCaps->DashPatterns = TRUE;
06489
06490
06491 pCaps->SimpleBitmaps = IsPrinting();
06492
06493
06494 }
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513 SlowJobResult OSRenderRegion::DrawMaskedBitmap(const DocRect &Rect, KernelBitmap* pBitmap,
06514 MaskedRenderRegion* pMask, ProgressDisplay *Progress)
06515 {
06516 PORTNOTETRACE("other","OSRenderRegion::DrawMaskedBitmap - do nothing");
06517 #if !defined(STANDALONE) && !defined(EXCLUDE_FROM_XARALX)
06518 if (RenderView->GetColourPlate() != NULL &&
06519 !RenderView->GetColourPlate()->IsDisabled())
06520 {
06521
06522
06523 return(DrawSeparatedMaskedBitmap(Rect, pBitmap, pMask, Progress));
06524 }
06525
06526
06527
06528 if ((pBitmap==NULL) || (pMask==NULL))
06529 return SLOWJOB_FAILURE;
06530
06531
06532
06533
06534 if (pMask->FindCoverage(TRUE) == 0)
06535 return SLOWJOB_SUCCESS;
06536
06537
06538 if (pBitmap->ActualBitmap == NULL)
06539 return SLOWJOB_FAILURE;
06540
06541
06542 WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
06543
06544
06545 if ((WinBM->BMInfo==NULL) || (WinBM->BMBytes==NULL))
06546 return SLOWJOB_FAILURE;
06547
06548
06549 INT32 Width = WinBM->GetWidth();
06550 INT32 Height = WinBM->GetHeight();
06551
06552 if ((Width == 0) || (Height == 0))
06553
06554 return SLOWJOB_FAILURE;
06555
06556
06557 INT32 BitmapDepth = WinBM->GetBPP();
06558 if (BitmapDepth == 32)
06559 {
06560
06561
06562
06563
06564 const INT32 ScanlineBytes = WinBM->GetScanlineSize();
06565
06566
06567 const INT32 DestlineBytes = DIBUtil::ScanlineSize(Width, 24);
06568
06569
06570 LPBYTE OriginalBuffer = WinBM->BMBytes;
06571 LPBYTE ConvertedBuffer = WinBM->BMBytes;
06572
06573 for (INT32 i=0; i<Height; i++)
06574 {
06575 DIBUtil::Convert32to24(Width, OriginalBuffer, ConvertedBuffer);
06576 OriginalBuffer += ScanlineBytes;
06577 ConvertedBuffer += DestlineBytes;
06578 }
06579
06580
06581 WinBM->BMInfo->bmiHeader.biSizeImage = DestlineBytes * Height;
06582 WinBM->BMInfo->bmiHeader.biBitCount = 24;
06583 BitmapDepth = 24;
06584 }
06585
06586
06587 ERROR3IF(BitmapDepth!=24, "Non 24bpp bitmap found in DrawMaskedBitmap");
06588
06589
06590
06591 INT32 SrcDpi = pMask->FindMaskDpi();
06592 INT32 DestDpi = SrcDpi;
06593 if (RenderDC!=NULL)
06594 DestDpi = RenderDC->GetDeviceCaps(LOGPIXELSY);
06595
06596
06597 double Ratio = DestDpi;
06598 Ratio = Ratio/SrcDpi;
06599
06600
06601 DocRect ClipRect = pMask->GetClipRect();
06602 WinRect WinClipRect = DocRectToWin(RenderMatrix, ClipRect, DestDpi);
06603 POINT Origin;
06604 Origin.x = WinClipRect.left;
06605 Origin.y = WinClipRect.bottom;
06606
06607
06608 if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06609 {
06610 if (Progress!=NULL)
06611 Progress->StartBitmapPhaseBand(Height);
06612 }
06613
06614
06615 LPBITMAPINFO TempBitmapInfo = NULL;
06616 LPBYTE TempBitmapBytes = NULL;
06617
06618
06619 TempBitmapInfo = AllocDIB(Width, 1, BitmapDepth, &TempBitmapBytes);
06620 if (TempBitmapInfo==NULL)
06621 return SLOWJOB_FAILURE;
06622
06623
06624 INT32 ScanLineBytes = DIBUtil::ScanlineSize(Width, BitmapDepth);
06625 INT32 BytesPerPixel = 3;
06626
06627
06628 LPBYTE SrcBuffer = WinBM->BMBytes;
06629 LPBYTE DestBuffer = TempBitmapBytes;
06630
06631
06632 INT32 OldMode = SetStretchBltMode(RenderDC->GetSafeHdc(), HALFTONE);
06633
06634
06635
06636 POINT OldOrg;
06637 SetBrushOrgEx(RenderDC->m_hDC, 0, 0, &OldOrg);
06638
06639
06640
06641
06642 if (PrintMonitor::PrintMaskType!=PrintMonitor::MASK_SIMPLE)
06643 {
06644 MaskRegion MaskInfo;
06645 pMask->GetFirstMaskRegion(&MaskInfo);
06646 while (MaskInfo.Length!=0)
06647 {
06648
06649 SrcBuffer = WinBM->BMBytes;
06650 SrcBuffer += ScanLineBytes * MaskInfo.y;
06651 SrcBuffer += MaskInfo.x*BytesPerPixel;
06652 INT32 RegionWidth = MaskInfo.Length;
06653
06654
06655 TempBitmapInfo->bmiHeader.biWidth = RegionWidth;
06656 TempBitmapInfo->bmiHeader.biSizeImage = (RegionWidth*BytesPerPixel);
06657
06658 memcpy(DestBuffer, SrcBuffer, RegionWidth*BytesPerPixel);
06659
06660
06661 INT32 DestX = Origin.x + INT32(ceil(MaskInfo.x*Ratio));
06662 INT32 DestY = Origin.y - INT32(ceil((MaskInfo.y+1)*Ratio));
06663 INT32 DestWidth = INT32(ceil(RegionWidth*Ratio));
06664 INT32 DestHeight = INT32(ceil(1*Ratio));
06665
06666
06667 StretchDIBits( RenderDC->GetSafeHdc(),
06668 DestX, DestY, DestWidth, DestHeight,
06669 0, 0,
06670 RegionWidth, 1,
06671 TempBitmapBytes, TempBitmapInfo,
06672 DIB_RGB_COLORS, SRCCOPY);
06673
06674
06675 if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06676 {
06677 if ((Progress!=NULL) && (!Progress->BitmapPhaseBandRenderedTo(MaskInfo.y)))
06678 {
06679
06680 SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06681 SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06682
06683
06684 FreeDIB(TempBitmapInfo, TempBitmapBytes);
06685
06686 return SLOWJOB_USERABORT;
06687 }
06688 }
06689
06690
06691 pMask->GetNextMaskRegion(&MaskInfo);
06692 }
06693 }
06694 else
06695 {
06696
06697
06698
06699 INT32 DestX = Origin.x;
06700 INT32 DestY = Origin.y - INT32(ceil(Height * Ratio));
06701 INT32 DestWidth = INT32(ceil(Width * Ratio));
06702 INT32 DestHeight = INT32(ceil(Height * Ratio));
06703
06704
06705 StretchDIBits( RenderDC->GetSafeHdc(),
06706 DestX, DestY, DestWidth, DestHeight,
06707 0, 0,
06708 Width, Height,
06709 WinBM->BMBytes, WinBM->BMInfo,
06710 DIB_RGB_COLORS, SRCCOPY);
06711
06712
06713 if ((Progress!=NULL) && (!Progress->BitmapPhaseBandRenderedTo(Height)))
06714 {
06715
06716 SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06717 SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06718
06719
06720 FreeDIB(TempBitmapInfo, TempBitmapBytes);
06721
06722 return SLOWJOB_USERABORT;
06723 }
06724 }
06725
06726
06727 SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06728 SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06729
06730
06731 TempBitmapInfo->bmiHeader.biSizeImage = (Width*3);
06732 TempBitmapInfo->bmiHeader.biWidth = Width;
06733
06734
06735 FreeDIB(TempBitmapInfo, TempBitmapBytes);
06736
06737 #endif
06738
06739
06740 return SLOWJOB_SUCCESS;
06741 }
06742
06743
06744
06745
06746
06747
06748
06749
06750
06751
06752
06753
06754
06755
06756
06757
06758
06759
06760
06761
06762
06763
06764
06765
06766
06767
06768
06769 SlowJobResult OSRenderRegion::DrawSeparatedMaskedBitmap(const DocRect &Rect, KernelBitmap* pBitmap,
06770 MaskedRenderRegion* pMask, ProgressDisplay *Progress)
06771 {
06772 PORTNOTETRACE("other","OSRenderRegion::DrawSeparatedMaskedBitmap - do nothing");
06773 #ifndef EXCLUDE_FROM_XARALX
06774 #ifndef STANDALONE
06775 SlowJobResult Result = SLOWJOB_SUCCESS;
06776
06777
06778 if ((pBitmap==NULL) || (pMask==NULL))
06779 return SLOWJOB_FAILURE;
06780
06781
06782
06783
06784 if (pMask->FindCoverage(TRUE) == 0)
06785 return SLOWJOB_SUCCESS;
06786
06787
06788 WinBitmap *WinBM = (WinBitmap*)pBitmap->ActualBitmap;
06789
06790
06791 if (WinBM == NULL || WinBM->BMInfo == NULL || WinBM->BMBytes == NULL)
06792 return SLOWJOB_FAILURE;
06793
06794
06795
06796
06797 if (SepTables == NULL && RenderView->GetColourPlate() != NULL)
06798 {
06799 ColourContextCMYK *cc = (ColourContextCMYK *)RenderView->GetColourContext(COLOURMODEL_CMYK);
06800 if (cc != NULL)
06801 {
06802 SepTables = (BYTE *) CCMalloc(5 * 256 * sizeof(BYTE));
06803 if (SepTables != NULL)
06804 {
06805 if (!cc->GetProfileTables(SepTables))
06806 {
06807 CCFree(SepTables);
06808 SepTables = NULL;
06809 }
06810 }
06811 }
06812
06813 ERROR3IF(SepTables == NULL, "Can't generate separation tables in OSRenderRegion");
06814 if (SepTables == NULL)
06815 return(SLOWJOB_FAILURE);
06816 }
06817
06818
06819
06820 INT32 Width = WinBM->GetWidth();
06821 INT32 Height = WinBM->GetHeight();
06822 INT32 BitmapDepth = WinBM->GetBPP();
06823
06824 if (Width == 0 || Height == 0)
06825 return SLOWJOB_FAILURE;
06826
06827
06828
06829 INT32 SrcDpi = pMask->FindMaskDpi();
06830 INT32 DestDpi = SrcDpi;
06831 if (RenderDC!=NULL)
06832 DestDpi = RenderDC->GetDeviceCaps(LOGPIXELSY);
06833
06834
06835 double Ratio = DestDpi;
06836 Ratio = Ratio/SrcDpi;
06837
06838
06839 DocRect ClipRect = pMask->GetClipRect();
06840 WinRect WinClipRect = DocRectToWin(RenderMatrix, ClipRect, DestDpi);
06841 POINT Origin;
06842 Origin.x = WinClipRect.left;
06843 Origin.y = WinClipRect.bottom;
06844
06845
06846 if (PrintMonitor::PrintMaskType==PrintMonitor::MASK_MASKED)
06847 {
06848 if (Progress!=NULL)
06849 Progress->StartBitmapPhaseBand(Height);
06850 }
06851
06852
06853 Pixel32bpp *pScanline = (Pixel32bpp *) CCMalloc(Width * sizeof(Pixel32bpp));
06854 if (pScanline == NULL)
06855 return(SLOWJOB_FAILURE);
06856
06857
06858
06859 LPBITMAPINFO pScanlineInfo = AllocDIB(Width, 1, 8, NULL);
06860 if (pScanlineInfo == NULL)
06861 return SLOWJOB_FAILURE;
06862
06863
06864 for (INT32 i = 0; i < 256; i++)
06865 {
06866 pScanlineInfo->bmiColors[i].rgbRed =
06867 pScanlineInfo->bmiColors[i].rgbGreen =
06868 pScanlineInfo->bmiColors[i].rgbBlue = i;
06869 pScanlineInfo->bmiColors[i].rgbReserved = 0;
06870 }
06871
06872
06873 INT32 OldMode = SetStretchBltMode(RenderDC->GetSafeHdc(), HALFTONE);
06874
06875
06876
06877 POINT OldOrg;
06878 SetBrushOrgEx(RenderDC->m_hDC, 0, 0, &OldOrg);
06879
06880 ColourContext *OutputContext = RenderView->GetColourContext(COLOURMODEL_RGBT);
06881 ERROR3IF(OutputContext == NULL, "Where's me RGB colour context gone then?");
06882
06883
06884
06885 MaskRegion MaskInfo;
06886 pMask->GetFirstMaskRegion(&MaskInfo);
06887 while (MaskInfo.Length != 0)
06888 {
06889
06890 pScanlineInfo->bmiHeader.biWidth = MaskInfo.Length;
06891 pScanlineInfo->bmiHeader.biSizeImage = MaskInfo.Length * sizeof(BYTE);
06892
06893
06894
06895 WinBM->GetScanline32bpp(MaskInfo.y, TRUE, pScanline);
06896
06897
06898
06899 WinBM->ColourSeparateScanline32to8(OutputContext, SepTables,
06900 (BYTE *) pScanline,
06901 pScanline + MaskInfo.x,
06902 MaskInfo.Length);
06903
06904
06905 const INT32 DestX = Origin.x + INT32(ceil(MaskInfo.x * Ratio));
06906 const INT32 DestY = Origin.y - INT32(ceil((MaskInfo.y + 1) * Ratio));
06907 const INT32 DestWidth = INT32(ceil(MaskInfo.Length * Ratio));
06908 const INT32 DestHeight = INT32(ceil(1 * Ratio));
06909
06910
06911 StretchDIBits( RenderDC->GetSafeHdc(),
06912 DestX, DestY, DestWidth, DestHeight,
06913 0, 0,
06914 MaskInfo.Length, 1,
06915 (BYTE *) pScanline, pScanlineInfo,
06916 DIB_RGB_COLORS, SRCCOPY);
06917
06918
06919 if (PrintMonitor::PrintMaskType == PrintMonitor::MASK_MASKED &&
06920 Progress != NULL && !Progress->BitmapPhaseBandRenderedTo(MaskInfo.y))
06921 {
06922 Result = SLOWJOB_USERABORT;
06923 break;
06924 }
06925
06926
06927 pMask->GetNextMaskRegion(&MaskInfo);
06928 }
06929
06930
06931 SetStretchBltMode(RenderDC->GetSafeHdc(), OldMode);
06932 SetBrushOrgEx(RenderDC->m_hDC, OldOrg.x, OldOrg.y, NULL);
06933
06934
06935 FreeDIB(pScanlineInfo, NULL);
06936 CCFree(pScanline);
06937
06938 return(Result);
06939 #else
06940 return SLOWJOB_FAILURE;
06941 #endif
06942 #else
06943 return SLOWJOB_SUCCESS;
06944 #endif
06945 }
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963 BOOL OSRenderRegion::RenderChar(WCHAR ch, Matrix* pMatrix)
06964 {
06965 PORTNOTETRACE("text","OSRenderRegion::RenderChar - do nothing");
06966 #ifndef EXCLUDE_FROM_XARALX
06967
06968
06969 BOOL FlatFill = IS_A(CurrentAttrs[ATTR_FILLGEOMETRY].pAttr, FlatFillAttribute);
06970
06971 if (!FlatFill ||
06972 !RR_STROKECOLOUR().IsTransparent() ||
06973 (FlatFill & RR_FILLCOLOUR().IsTransparent()))
06974 return RenderRegion::RenderChar(ch, pMatrix);
06975
06976 if (IsPrinting())
06977 {
06978
06979 PrintControl *pPrintCtl;
06980 View *pView = GetRenderView();
06981 if (pView && (pPrintCtl=pView->GetPrintControl()))
06982 {
06983 if (pPrintCtl->GetTypesetInfo()->PrintEmulsionDown())
06984 return RenderRegion::RenderChar(ch, pMatrix);
06985 }
06986 }
06987
06988
06989 Matrix matrix;
06990 if (GetCharAttributeMatrix(&matrix)==FALSE)
06991 return NULL;
06992 if (pMatrix)
06993 matrix*=*pMatrix;
06994
06995
06996
06997 FIXED16 abcd[4];
06998 INT32 ef[2];
06999 matrix.GetComponents(abcd, ef);
07000
07001
07002
07003 if ((abcd[0] < FIXED16(0)) || (abcd[3] < FIXED16(0)))
07004 {
07005
07006 return RenderRegion::RenderChar(ch, pMatrix);
07007 }
07008
07009
07010 FIXED16 ScaleX = 0;
07011 FIXED16 ScaleY = 0;
07012 ANGLE Rotation = 0;
07013 ANGLE Shear = 0;
07014
07015 if ((abcd[1] == FIXED16(0)) && (abcd[2] == FIXED16(0)) &&
07016 (abcd[0] >= FIXED16(0)) && (abcd[3] >= FIXED16(0)))
07017 {
07018
07019 ScaleX = abcd[0];
07020 ScaleY = abcd[3];
07021 Rotation = FIXED16(0);
07022 Shear = FIXED16(0);
07023 }
07024 else
07025 {
07026
07027
07028 FIXED16 Aspect;
07029 BOOL Result = matrix.Decompose(&ScaleY, &Aspect, &Rotation, &Shear, NULL);
07030
07031 if (!Result || (Shear != FIXED16(0)))
07032
07033
07034 return RenderRegion::RenderChar(ch, pMatrix);
07035
07036
07037 ScaleX = ScaleY * Aspect;
07038 }
07039
07040
07041
07042 FIXED16 RenderABCD[4];
07043 INT32 RenderEF[2];
07044 RenderMatrix.GetComponents(RenderABCD, RenderEF);
07045 if ((RenderABCD[1] != FIXED16(0)) || (RenderABCD[2] != FIXED16(0)))
07046
07047 Rotation += FIXED16(1.5 * PI);
07048
07049
07050 MILLIPOINT ReferenceSize = TextManager::GetDefaultHeight();
07051 MILLIPOINT Width = ReferenceSize * ScaleX;
07052 MILLIPOINT Height = ReferenceSize * ScaleY;
07053
07054 if (!SelectNewFont(RR_TXTFONTTYPEFACE(), RR_TXTBOLD(), RR_TXTITALIC(),
07055 Width, Height, Rotation))
07056 {
07057
07058 return RenderRegion::RenderChar(ch, pMatrix);
07059 }
07060
07061
07062 UINT32 OldTextAlign = RenderDC->SetTextAlign(TA_BASELINE);
07063 INT32 OldBKMode = RenderDC->SetBkMode(TRANSPARENT);
07064 COLORREF OldTextColor =
07065 RenderDC->SetTextColor(ConvertColourToScreenWord(CurrentColContext, &RR_FILLCOLOUR()));
07066
07067
07068 DocCoord DocPos(ef[0], ef[1]);
07069 WinCoord WinPos = DocCoordToWin(DocPos);
07070
07071
07072
07073
07074
07075
07076 UINT32 uiCharNumber = UnicodeManager::UnicodeToMultiByte(ch);
07077
07078
07079
07080
07081 BYTE bCharArray[2];
07082
07083 UnicodeManager::DecomposeMultiBytes(uiCharNumber, &bCharArray[0], &bCharArray[1]);
07084
07085
07086
07087 if (bCharArray[0]==0)
07088
07089
07090
07091 RenderDC->TextOut(WinPos.x, WinPos.y, (CHAR*) &bCharArray[1], 1);
07092 else
07093
07094
07095
07096
07097 RenderDC->TextOut(WinPos.x, WinPos.y, (CHAR*) &bCharArray[0], 2);
07098
07099
07100 RenderDC->SetTextAlign(OldTextAlign);
07101 RenderDC->SetBkMode(OldBKMode);
07102 RenderDC->SetTextColor(OldTextColor);
07103 #elif !defined(DISABLE_TEXT_RENDERING)
07104 return RenderRegion::RenderChar(ch, pMatrix);
07105 #endif
07106 return TRUE;
07107 }
07108
07109
07110
07111
07112
07113
07114
07115
07116
07117
07118
07119
07120
07121
07122
07123
07124
07125 PaperRenderRegion::PaperRenderRegion(DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale)
07126 : OSRenderRegion(ClipRect, ConvertMatrix, ViewScale)
07127 {
07128 }
07129
07130
07131
07132
07133
07134
07135
07136
07137
07138
07139
07140
07141
07142 PaperRenderRegion::~PaperRenderRegion()
07143 {
07144 }
07145
07146
07147
07148
07149
07150
07151
07152
07153
07154
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166 BOOL PaperRenderRegion::AttachDevice(View *pView, Spread *pSpread, wxDC* pDC,
07167 Matrix& ViewMatrix, FIXED16 ViewScale,
07168 DocRect& ClipRect, bool fOwned )
07169 {
07170 if (!OSRenderRegion::AttachDevice(pView, pDC, pSpread))
07171 return(FALSE);
07172
07173
07174
07175 CurrentClipRect = ClipRect;
07176 RenderMatrix = ViewMatrix;
07177 ScaleFactor = ViewScale;
07178
07179
07180 SaveContext();
07181
07182
07183
07184 return(TRUE);
07185 }
07186
07187
07188
07189
07190
07191
07192
07193
07194
07195
07196
07197
07198
07199 void PaperRenderRegion::DetachDevice()
07200 {
07201
07202 RestoreContext();
07203
07204
07205 CCFree(CurrentAttrs);
07206 CurrentAttrs = NULL;
07207
07208
07209 RenderDC = NULL;
07210 RenderView = NULL;
07211 RenderSpread = NULL;
07212 RenderFlags.ValidDevice = FALSE;
07213
07214 }
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244 BOOL PaperRenderRegion::InitDevice()
07245 {
07246
07247
07248
07249 RFlags.UsePalette = (WantGDIPalette && PaletteManager::UsePalette()) ? TRUE : FALSE;
07250
07251
07252 if (!OSRenderRegion::InitDevice())
07253 return FALSE;
07254
07255
07256 return TRUE;
07257 }
07258
07259
07260
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271
07272
07273
07274
07275
07276
07277
07278
07279
07280
07281
07282
07283 wxSize OSRenderRegion::GetFixedDCPPI(wxDC &DC)
07284 {
07285
07286 PORTNOTE("MacPort", "We should allow the user to configure this value on the mac, maybe on all platforms")
07287 #ifdef __WXMAC__
07288 wxSize PPI(96,96);
07289 #else
07290 wxSize PPI(96,96);
07291 #endif
07292
07293
07294 if (! ( DC.IsKindOf(CLASSINFO(wxScreenDC)) || DC.IsKindOf(CLASSINFO(wxPaintDC)) ))
07295 PPI=DC.GetPPI();
07296
07297 return PPI;
07298 }