00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdexcept>
00013 #include <memory>
00014 #include <vector>
00015
00016 #include "TAttMarker.h"
00017 #include "TVirtualX.h"
00018 #include "TError.h"
00019 #include "TImage.h"
00020 #include "TROOT.h"
00021 #include "TPad.h"
00022
00023 #include "TGLPadPainter.h"
00024 #include "TGLIncludes.h"
00025 #include "TGLUtil.h"
00026 #include "TError.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 ClassImp(TGLPadPainter)
00038
00039
00040 TGLPadPainter::TGLPadPainter()
00041 : fIsHollowArea(kFALSE),
00042 fLocked(kTRUE)
00043 {
00044 fVp[0] = fVp[1] = fVp[2] = fVp[3] = 0;
00045 }
00046
00047
00048
00049 Color_t TGLPadPainter::GetLineColor() const
00050 {
00051
00052 return gVirtualX->GetLineColor();
00053 }
00054
00055
00056 Style_t TGLPadPainter::GetLineStyle() const
00057 {
00058
00059 return gVirtualX->GetLineStyle();
00060 }
00061
00062
00063 Width_t TGLPadPainter::GetLineWidth() const
00064 {
00065
00066 return gVirtualX->GetLineWidth();
00067 }
00068
00069
00070 void TGLPadPainter::SetLineColor(Color_t lcolor)
00071 {
00072
00073 gVirtualX->SetLineColor(lcolor);
00074 }
00075
00076
00077 void TGLPadPainter::SetLineStyle(Style_t lstyle)
00078 {
00079
00080 gVirtualX->SetLineStyle(lstyle);
00081 }
00082
00083
00084 void TGLPadPainter::SetLineWidth(Width_t lwidth)
00085 {
00086
00087 gVirtualX->SetLineWidth(lwidth);
00088 }
00089
00090
00091 Color_t TGLPadPainter::GetFillColor() const
00092 {
00093
00094 return gVirtualX->GetFillColor();
00095 }
00096
00097
00098 Style_t TGLPadPainter::GetFillStyle() const
00099 {
00100
00101 return gVirtualX->GetFillStyle();
00102 }
00103
00104
00105 Bool_t TGLPadPainter::IsTransparent() const
00106 {
00107
00108
00109 return gVirtualX->IsTransparent();
00110 }
00111
00112
00113 void TGLPadPainter::SetFillColor(Color_t fcolor)
00114 {
00115
00116 gVirtualX->SetFillColor(fcolor);
00117 }
00118
00119
00120 void TGLPadPainter::SetFillStyle(Style_t fstyle)
00121 {
00122
00123 gVirtualX->SetFillStyle(fstyle);
00124 }
00125
00126
00127 void TGLPadPainter::SetOpacity(Int_t percent)
00128 {
00129
00130 gVirtualX->SetOpacity(percent);
00131 }
00132
00133
00134 Short_t TGLPadPainter::GetTextAlign() const
00135 {
00136
00137 return gVirtualX->GetTextAlign();
00138 }
00139
00140
00141 Float_t TGLPadPainter::GetTextAngle() const
00142 {
00143
00144 return gVirtualX->GetTextAngle();
00145 }
00146
00147
00148 Color_t TGLPadPainter::GetTextColor() const
00149 {
00150
00151 return gVirtualX->GetTextColor();
00152 }
00153
00154
00155 Font_t TGLPadPainter::GetTextFont() const
00156 {
00157
00158 return gVirtualX->GetTextFont();
00159 }
00160
00161
00162 Float_t TGLPadPainter::GetTextSize() const
00163 {
00164
00165 return gVirtualX->GetTextSize();
00166 }
00167
00168
00169 Float_t TGLPadPainter::GetTextMagnitude() const
00170 {
00171
00172 return gVirtualX->GetTextMagnitude();
00173 }
00174
00175
00176 void TGLPadPainter::SetTextAlign(Short_t align)
00177 {
00178
00179 gVirtualX->SetTextAlign(align);
00180 }
00181
00182
00183 void TGLPadPainter::SetTextAngle(Float_t tangle)
00184 {
00185
00186 gVirtualX->SetTextAngle(tangle);
00187 }
00188
00189
00190 void TGLPadPainter::SetTextColor(Color_t tcolor)
00191 {
00192
00193 gVirtualX->SetTextColor(tcolor);
00194 }
00195
00196
00197 void TGLPadPainter::SetTextFont(Font_t tfont)
00198 {
00199
00200 gVirtualX->SetTextFont(tfont);
00201 }
00202
00203
00204 void TGLPadPainter::SetTextSize(Float_t tsize)
00205 {
00206
00207 gVirtualX->SetTextSize(tsize);
00208 }
00209
00210
00211 void TGLPadPainter::SetTextSizePixels(Int_t npixels)
00212 {
00213
00214 gVirtualX->SetTextSizePixels(npixels);
00215 }
00216
00217
00218
00219
00220
00221
00222 Int_t TGLPadPainter::CreateDrawable(UInt_t, UInt_t)
00223 {
00224
00225 return 0;
00226 }
00227
00228
00229 void TGLPadPainter::ClearDrawable()
00230 {
00231
00232 }
00233
00234
00235 void TGLPadPainter::CopyDrawable(Int_t , Int_t , Int_t )
00236 {
00237
00238 }
00239
00240
00241 void TGLPadPainter::DestroyDrawable()
00242 {
00243
00244 }
00245
00246
00247 void TGLPadPainter::SelectDrawable(Int_t )
00248 {
00249
00250
00251
00252
00253 if (fLocked)
00254 return;
00255
00256 if (TPad *pad = dynamic_cast<TPad *>(gPad)) {
00257 Int_t px = 0, py = 0;
00258
00259 pad->XYtoAbsPixel(pad->GetX1(), pad->GetY1(), px, py);
00260
00261 py = gPad->GetWh() - py;
00262
00263 glViewport(px, py, GLsizei(gPad->GetWw() * pad->GetAbsWNDC()), GLsizei(gPad->GetWh() * pad->GetAbsHNDC()));
00264
00265 glMatrixMode(GL_PROJECTION);
00266 glLoadIdentity();
00267 glOrtho(pad->GetX1(), pad->GetX2(), pad->GetY1(), pad->GetY2(), -10., 10.);
00268
00269 glMatrixMode(GL_MODELVIEW);
00270 glLoadIdentity();
00271 glTranslated(0., 0., -1.);
00272 } else {
00273 Error("TGLPadPainter::SelectDrawable", "function was called not from TPad or TCanvas code\n");
00274 throw std::runtime_error("");
00275 }
00276 }
00277
00278
00279 void TGLPadPainter::InitPainter()
00280 {
00281
00282
00283
00284
00285
00286
00287
00288
00289 glDisable(GL_DEPTH_TEST);
00290 glDisable(GL_CULL_FACE);
00291 glDisable(GL_LIGHTING);
00292
00293
00294 glViewport(0, 0, GLsizei(gPad->GetWw()), GLsizei(gPad->GetWh()));
00295
00296 glDepthMask(GL_TRUE);
00297 glClearColor(1.,1.,1.,1.);
00298 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00299 glDepthMask(GL_FALSE);
00300
00301 glMatrixMode(GL_PROJECTION);
00302 glLoadIdentity();
00303
00304 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
00305
00306 glMatrixMode(GL_MODELVIEW);
00307 glLoadIdentity();
00308 glTranslated(0., 0., -1.);
00309
00310 fLocked = kFALSE;
00311 }
00312
00313
00314 void TGLPadPainter::InvalidateCS()
00315 {
00316
00317
00318 if (fLocked)
00319 return;
00320
00321 glMatrixMode(GL_PROJECTION);
00322 glLoadIdentity();
00323
00324 glOrtho(gPad->GetX1(), gPad->GetX2(), gPad->GetY1(), gPad->GetY2(), -10., 10.);
00325
00326 glMatrixMode(GL_MODELVIEW);
00327 }
00328
00329
00330 void TGLPadPainter::LockPainter()
00331 {
00332
00333
00334
00335 if (fLocked)
00336 return;
00337
00338 glFinish();
00339 fLocked = kTRUE;
00340 }
00341
00342
00343
00344
00345
00346 const Double_t lineWidthTS = 3.;
00347
00348
00349 void TGLPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
00350 {
00351
00352 if (fLocked) {
00353
00354
00355
00356
00357
00358 if (gVirtualX->GetDrawMode() == TVirtualX::kInvert) {
00359 gVirtualX->DrawLine(gPad->XtoAbsPixel(x1), gPad->YtoAbsPixel(y1),
00360 gPad->XtoAbsPixel(x2), gPad->YtoAbsPixel(y2));
00361 }
00362
00363 return;
00364 }
00365
00366 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, gVirtualX->GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE);
00367
00368 glBegin(GL_LINES);
00369 glVertex2d(x1, y1);
00370 glVertex2d(x2, y2);
00371 glEnd();
00372
00373 if (gVirtualX->GetLineWidth() > lineWidthTS) {
00374 Double_t pointSize = gVirtualX->GetLineWidth();
00375 if (pointSize > fLimits.GetMaxPointSize())
00376 pointSize = fLimits.GetMaxPointSize();
00377 glPointSize((GLfloat)pointSize);
00378 const TGLEnableGuard pointSmooth(GL_POINT_SMOOTH);
00379 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
00380 glBegin(GL_POINTS);
00381
00382 glVertex2d(x1, y1);
00383 glVertex2d(x2, y2);
00384
00385 glEnd();
00386 glPointSize(1.f);
00387 }
00388
00389 }
00390
00391
00392 void TGLPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
00393 {
00394
00395 if (fLocked)
00396 return;
00397
00398 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, gVirtualX->GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE);
00399 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
00400 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
00401
00402 glBegin(GL_LINES);
00403 glVertex2d(gPad->GetX1() + u1 * xRange, gPad->GetY1() + v1 * yRange);
00404 glVertex2d(gPad->GetX1() + u2 * xRange, gPad->GetY1() + v2 * yRange);
00405 glEnd();
00406 }
00407
00408
00409 void TGLPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode)
00410 {
00411
00412 if (fLocked)
00413 return;
00414
00415 if (mode == kHollow) {
00416 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, 0, fLimits.GetMaxLineWidth(), kTRUE);
00417
00418 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00419 glRectd(x1, y1, x2, y2);
00420 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00421 glLineWidth(1.f);
00422 } else {
00423 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);
00424 glRectd(x1, y1, x2, y2);
00425 }
00426 }
00427
00428
00429 void TGLPadPainter::DrawFillArea(Int_t n, const Double_t *x, const Double_t *y)
00430 {
00431
00432 if (fLocked)
00433 return;
00434
00435 if (!gVirtualX->GetFillStyle()) {
00436 fIsHollowArea = kTRUE;
00437 return DrawPolyLine(n, x, y);
00438 }
00439
00440 fVs.resize(n * 3);
00441
00442 for (Int_t i = 0; i < n; ++i) {
00443 fVs[i * 3] = x[i];
00444 fVs[i * 3 + 1] = y[i];
00445 fVs[i * 3 + 2] = 0.;
00446 }
00447
00448 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);
00449
00450 GLUtesselator *t = (GLUtesselator *)fTess.GetTess();
00451 gluBeginPolygon(t);
00452 gluNextContour(t, (GLenum)GLU_UNKNOWN);
00453
00454 for (Int_t i = 0; i < n; ++i)
00455 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
00456
00457
00458 gluEndPolygon(t);
00459 }
00460
00461
00462 void TGLPadPainter::DrawFillArea(Int_t n, const Float_t *x, const Float_t *y)
00463 {
00464
00465
00466 if (fLocked)
00467 return;
00468
00469 if (!gVirtualX->GetFillStyle()) {
00470 fIsHollowArea = kTRUE;
00471 return DrawPolyLine(n, x, y);
00472 }
00473
00474 fVs.resize(n * 3);
00475
00476 for (Int_t i = 0; i < n; ++i) {
00477 fVs[i * 3] = x[i];
00478 fVs[i * 3 + 1] = y[i];
00479 }
00480
00481 const Rgl::Pad::FillAttribSet fillAttribs(fSSet, kFALSE);
00482
00483 GLUtesselator *t = (GLUtesselator *)fTess.GetTess();
00484 gluBeginPolygon(t);
00485 gluNextContour(t, (GLenum)GLU_UNKNOWN);
00486
00487 for (Int_t i = 0; i < n; ++i)
00488 gluTessVertex(t, &fVs[i * 3], &fVs[i * 3]);
00489
00490
00491 gluEndPolygon(t);
00492 }
00493
00494
00495 void TGLPadPainter::DrawPolyLine(Int_t n, const Double_t *x, const Double_t *y)
00496 {
00497
00498 if (fLocked)
00499 return;
00500
00501 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, gVirtualX->GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE);
00502
00503 glBegin(GL_LINE_STRIP);
00504
00505 for (Int_t i = 0; i < n; ++i)
00506 glVertex2d(x[i], y[i]);
00507
00508 if (fIsHollowArea) {
00509 glVertex2d(x[0], y[0]);
00510 fIsHollowArea = kFALSE;
00511 }
00512 glEnd();
00513
00514 if (gVirtualX->GetLineWidth() > lineWidthTS) {
00515 Double_t pointSize = gVirtualX->GetLineWidth();
00516 if (pointSize > fLimits.GetMaxPointSize())
00517 pointSize = fLimits.GetMaxPointSize();
00518 glPointSize((GLfloat)pointSize);
00519 const TGLEnableGuard pointSmooth(GL_POINT_SMOOTH);
00520 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
00521 glBegin(GL_POINTS);
00522
00523 for (Int_t i = 0; i < n; ++i)
00524 glVertex2d(x[i], y[i]);
00525
00526 glEnd();
00527 glPointSize(1.f);
00528 }
00529 }
00530
00531
00532 void TGLPadPainter::DrawPolyLine(Int_t n, const Float_t *x, const Float_t *y)
00533 {
00534
00535 if (fLocked)
00536 return;
00537
00538 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, gVirtualX->GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE);
00539
00540 glBegin(GL_LINE_STRIP);
00541
00542 for (Int_t i = 0; i < n; ++i)
00543 glVertex2f(x[i], y[i]);
00544
00545 if (fIsHollowArea) {
00546 glVertex2f(x[0], y[0]);
00547 fIsHollowArea = kFALSE;
00548 }
00549
00550 glEnd();
00551 }
00552
00553
00554 void TGLPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v)
00555 {
00556
00557 if (fLocked)
00558 return;
00559
00560 const Rgl::Pad::LineAttribSet lineAttribs(kTRUE, gVirtualX->GetLineStyle(), fLimits.GetMaxLineWidth(), kTRUE);
00561 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
00562 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
00563 const Double_t x1 = gPad->GetX1(), y1 = gPad->GetY1();
00564
00565 glBegin(GL_LINE_STRIP);
00566
00567 for (Int_t i = 0; i < n; ++i)
00568 glVertex2d(x1 + u[i] * xRange, y1 + v[i] * yRange);
00569
00570 glEnd();
00571 }
00572
00573 namespace {
00574
00575
00576 template<class ValueType>
00577 void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst);
00578
00579 }
00580
00581
00582 void TGLPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y)
00583 {
00584
00585 if (fLocked)
00586 return;
00587
00588 ConvertMarkerPoints(n, x, y, fPoly);
00589 DrawPolyMarker();
00590 }
00591
00592
00593 void TGLPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y)
00594 {
00595
00596 if (fLocked)
00597 return;
00598
00599 ConvertMarkerPoints(n, x, y, fPoly);
00600 DrawPolyMarker();
00601 }
00602
00603
00604 void TGLPadPainter::DrawPolyMarker()
00605 {
00606
00607 if (fLocked)
00608 return;
00609
00610 SaveProjectionMatrix();
00611 glLoadIdentity();
00612
00613 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
00614
00615 glMatrixMode(GL_MODELVIEW);
00616
00617 Float_t rgba[3] = {};
00618 Rgl::Pad::ExtractRGB(gVirtualX->GetMarkerColor(), rgba);
00619 glColor3fv(rgba);
00620
00621 const TPoint *xy = &fPoly[0];
00622 const Style_t markerStyle = gVirtualX->GetMarkerStyle();
00623 const UInt_t n = UInt_t(fPoly.size());
00624 switch (markerStyle) {
00625 case kDot:
00626 fMarker.DrawDot(n, xy);
00627 break;
00628 case kPlus:
00629 fMarker.DrawPlus(n, xy);
00630 break;
00631 case kStar:
00632 fMarker.DrawStar(n, xy);
00633 break;
00634 case kCircle:
00635 case kOpenCircle:
00636 fMarker.DrawCircle(n, xy);
00637 break;
00638 case kMultiply:
00639 fMarker.DrawX(n, xy);
00640 break;
00641 case kFullDotSmall:
00642 fMarker.DrawFullDotSmall(n, xy);
00643 break;
00644 case kFullDotMedium:
00645 fMarker.DrawFullDotMedium(n, xy);
00646 break;
00647 case kFullDotLarge:
00648 case kFullCircle:
00649 fMarker.DrawFullDotLarge(n, xy);
00650 break;
00651 case kFullSquare:
00652 fMarker.DrawFullSquare(n, xy);
00653 break;
00654 case kFullTriangleUp:
00655 fMarker.DrawFullTrianlgeUp(n, xy);
00656 break;
00657 case kFullTriangleDown:
00658 fMarker.DrawFullTrianlgeDown(n, xy);
00659 break;
00660 case kOpenSquare:
00661 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00662 fMarker.DrawFullSquare(n, xy);
00663 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00664 break;
00665 case kOpenTriangleUp:
00666 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00667 fMarker.DrawFullTrianlgeUp(n, xy);
00668 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00669 break;
00670 case kOpenDiamond:
00671 fMarker.DrawDiamond(n, xy);
00672 break;
00673 case kOpenCross:
00674 fMarker.DrawCross(n, xy);
00675 break;
00676 case kFullStar:
00677 fMarker.DrawFullStar(n, xy);
00678 break;
00679 case kOpenStar:
00680 fMarker.DrawOpenStar(n, xy);
00681 }
00682
00683 RestoreProjectionMatrix();
00684 glMatrixMode(GL_MODELVIEW);
00685 }
00686
00687
00688 void TGLPadPainter::DrawText(Double_t x, Double_t y, const char *text, ETextMode )
00689 {
00690
00691
00692
00693
00694 if (fLocked)
00695 return;
00696
00697 SaveProjectionMatrix();
00698 glLoadIdentity();
00699
00700 glOrtho(0, gPad->GetAbsWNDC() * gPad->GetWw(), 0, gPad->GetAbsHNDC() * gPad->GetWh(), -10., 10.);
00701
00702 glMatrixMode(GL_MODELVIEW);
00703
00704 Float_t rgba[3] = {};
00705 Rgl::Pad::ExtractRGB(gVirtualX->GetTextColor(), rgba);
00706 glColor3fv(rgba);
00707
00708 fFM.RegisterFont(Int_t(gVirtualX->GetTextSize()) - 1,
00709 TGLFontManager::GetFontNameFromId(gVirtualX->GetTextFont()),
00710 TGLFont::kTexture, fF);
00711 fF.PreRender();
00712
00713 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
00714 fF.Render(text, gPad->XtoPixel(x), padH - gPad->YtoPixel(y), GetTextAngle(), GetTextMagnitude());
00715
00716 fF.PostRender();
00717 RestoreProjectionMatrix();
00718 glMatrixMode(GL_MODELVIEW);
00719 }
00720
00721
00722 void TGLPadPainter::DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode)
00723 {
00724
00725
00726
00727
00728 if (fLocked)
00729 return;
00730
00731 const Double_t xRange = gPad->GetX2() - gPad->GetX1();
00732 const Double_t yRange = gPad->GetY2() - gPad->GetY1();
00733 DrawText(gPad->GetX1() + u * xRange, gPad->GetY1() + v * yRange, text, mode);
00734 }
00735
00736
00737 void TGLPadPainter::SaveProjectionMatrix()const
00738 {
00739
00740
00741
00742 glMatrixMode(GL_PROJECTION);
00743 glPushMatrix();
00744 }
00745
00746
00747 void TGLPadPainter::RestoreProjectionMatrix()const
00748 {
00749
00750
00751
00752 glMatrixMode(GL_PROJECTION);
00753 glPopMatrix();
00754 }
00755
00756
00757 void TGLPadPainter::SaveModelviewMatrix()const
00758 {
00759
00760
00761
00762 glMatrixMode(GL_MODELVIEW);
00763 glPushMatrix();
00764 }
00765
00766
00767 void TGLPadPainter::RestoreModelviewMatrix()const
00768 {
00769
00770
00771
00772 glMatrixMode(GL_MODELVIEW);
00773 glPopMatrix();
00774 }
00775
00776
00777 void TGLPadPainter::SaveViewport()
00778 {
00779
00780 glGetIntegerv(GL_VIEWPORT, fVp);
00781 }
00782
00783
00784 void TGLPadPainter::RestoreViewport()
00785 {
00786
00787 glViewport(fVp[0], fVp[1], fVp[2], fVp[3]);
00788 }
00789
00790
00791 void TGLPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
00792 {
00793
00794
00795 TVirtualPad *canvas = (TVirtualPad *)pad->GetCanvas();
00796 if (!canvas) return;
00797 gROOT->ProcessLine(Form("((TCanvas *)0x%lx)->Flush();", (ULong_t)canvas));
00798
00799 std::vector<unsigned> buff(canvas->GetWw() * canvas->GetWh());
00800 glPixelStorei(GL_PACK_ALIGNMENT, 1);
00801 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00802
00803
00804 glReadPixels(0, 0, canvas->GetWw(), canvas->GetWh(), GL_RGBA, GL_UNSIGNED_BYTE, (char *)&buff[0]);
00805
00806 std::auto_ptr<TImage> image(TImage::Create());
00807 if (!image.get()) {
00808 Error("TGLPadPainter::SaveImage", "TImage creation failed");
00809 return;
00810 }
00811
00812 image->DrawRectangle(0, 0, canvas->GetWw(), canvas->GetWh());
00813 UInt_t *argb = image->GetArgbArray();
00814
00815 if (!argb) {
00816 Error("TGLPadPainter::SaveImage", "null argb array in TImage object");
00817 return;
00818 }
00819
00820 const Int_t nLines = canvas->GetWh();
00821 const Int_t nPixels = canvas->GetWw();
00822
00823 for (Int_t i = 0; i < nLines; ++i) {
00824 Int_t base = (nLines - 1 - i) * nPixels;
00825 for (Int_t j = 0; j < nPixels; ++j, ++base) {
00826
00827
00828 const UInt_t pix = buff[base];
00829 const UInt_t bgra = ((pix & 0xff) << 16) | (pix & 0xff00) |
00830 ((pix & 0xff0000) >> 16) | (pix & 0xff000000);
00831
00832
00833 argb[i * nPixels + j] = bgra;
00834 }
00835 }
00836
00837 image->WriteImage(fileName, (TImage::EImageFileTypes)type);
00838 }
00839
00840
00841
00842 namespace {
00843
00844 template<class ValueType>
00845 void ConvertMarkerPoints(Int_t n, const ValueType *x, const ValueType *y, std::vector<TPoint> & dst)
00846 {
00847 const UInt_t padH = UInt_t(gPad->GetAbsHNDC() * gPad->GetWh());
00848
00849 dst.resize(n);
00850 for (Int_t i = 0; i < n; ++i) {
00851 dst[i].fX = gPad->XtoPixel(x[i]);
00852 dst[i].fY = padH - gPad->YtoPixel(y[i]);
00853 }
00854 }
00855
00856 }