source: trunk/MagicSoft/Mars/mtools/MCalendar.cc@ 7470

Last change on this file since 7470 was 7451, checked in by tbretz, 19 years ago
*** empty log message ***
File size: 42.1 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 12/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2005
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MCalendar
28//
29//
30// Resource files
31// --------------
32//
33// A calendar sheet is bets setup via a resource file with the
34// following contants:
35//
36// The day shown in the first column. (Sun=0, Mon=1, ...)
37// FirstDay: 0
38//
39// The Number of blocks the calendar sheet is made of:
40// NumBlocks: 2
41//
42// Set the position a graphic of the moon. The alignment is
43// coded as described in TAttText (0=off):
44// Moon.Graf.Align: 11
45//
46// Set the position a text describing the moon phase. The alignment is
47// coded as described in TAttText (0=off):
48// Moon.Text.Align: 11
49//
50// Set the text type: 0=MoonPhase, 1=MoonPeriod, 2=MagicPeriod
51// Moon.Text.Type: 0
52//
53// Determin whether the text should be continous or only at
54// new moon (only valid if both alignments identical)
55// Moon.Text.Continous: Yes
56//
57// Radius of the moon graphics in units of the pave height:
58// Moon.Graf.Radius: 0.08
59//
60// Horizontal and vertical margin in units of the pave height
61// between the pave border and the text:
62// MarginX: 0.05
63//
64// Space between the cells in units of the cell height:
65// CellSpace: 0.01
66//
67// Space between the blocks in units of the cell height:
68// BlockSpace: 0.1
69//
70// Local to determin the language to be used. For more details see
71// for example MTime::GetStringFmt or strftime (eg. de_DE, es_ES, it_IT)
72// The empty default is the system default (eg as if you call "date")
73// Language:
74//
75// The file name of a file containing the setup for holidays and birthdays:
76// HolidayFile:
77//
78// The setup of the pave in your calendar is done by the style defined
79// by a pave. For more details see TPave or MEnv::GetEnvPave:
80// Date.{PaveStyle}
81//
82// The contents of each pave in your calendar.
83// Contents: Date Day Holiday Easter Birthday
84//
85// You can setup the contents by their names individually. The possible
86// Style is defined by a TLatex object. For more details see TLatex or
87// MEnv::GetAttText.
88//
89// To setup the position in the pave use:
90// Holiday.TextAlign: center
91// Holiday.TextAlign: center top
92// Holiday.TextAlign: right center
93// Holiday.TextAlign: right top
94//
95// The text style can be setup by:
96// Holiday.TextSize: 0.13
97// Holiday.TextColor: Blue
98//
99// To setup a day-dependant string, in addition to the three resources
100// above, a format string as defined in MTime::GetStringFmt or strftime.
101// Holiday.Format: %a
102//
103// Contents for which a format was setup are build using MTime::GetStringFmt.
104// Contents without a format set are searched in the holiday resource.
105//
106// For the 1.1. and 25.12. the setup could be:
107// Holiday.01/01: New year
108// Holiday.12/25: Christmas
109//
110// If the contents name is "Easter" the search is done relative to Easter:
111// Easter.-1: Easter Saturday
112// Easter.0: Easter
113// Easter.1: Easter Monday
114//
115// In addition to this you can overwrite the this default for the active
116// and/or inactivedays by:
117// Date.Active.{PaveStyle}
118// Holiday.Active.TextColor: Blue
119// Holiday.Inactive.TextColor: Gray1
120//
121// To define a special setup for only one day (Sun=0, Mon=1, ...) use:
122// Date.Active.0.{PaveStyle}
123// Holiday.Active.0.TextColor: Red
124// Holiday.Inactive.0.TextColor: White
125//
126// To get a resource file describing the default layout draw a calendar
127// sheet and choose "SaveResourceFile" from the context menu. By using
128// the context menu you can change the layout and also save it to a
129// resource file. Read such a resource file using ReadResourceFile.
130//
131//
132// Context Menu
133// ------------
134//
135// void SetDate(UInt_t Month, Int_t Year=-1)
136// Used to set new year and month. Use Year=-1 to keep the year
137//
138// void SetLocal(const char *Locale="")
139// Set new Localization. For more details see MTime::GetStringFmt or
140// strftime
141//
142// void SetFirstDay(Int_t FirstDay)
143// Define the WeekDay in the first column (Son=0, Mon=1, ...)
144//
145// void SetLayout(Byte_t NumberOfBlocks, Double_t MarginX, Double_t MarginY, Double_t CellSpace, Double_t BlockSpace)
146// change the Layout. For more details see section "Resource Files"
147//
148// void ResetLayout()
149// Remove everything from the layout
150//
151// void ResetHolidays()
152// remove all holidays.
153//
154// void SetDefaultLayout()
155// set the layout to the default layout
156//
157// void SetDefaultHolidays()
158// set the default holidays
159//
160// void ReadResourceFile(const char *FileName=0)
161// read layout from a resource file. (also the holidays are reread)
162//
163// void ReadHolidayFile(const char *FileName=0)
164// read holidays from a file
165//
166// void SaveResourceFile(const char *FileName=0)
167// save current layout to a file
168//
169// void SaveHolidayFile(const char *FileName=0)
170// save current holidays to a file
171//
172// void Add(const char *Name, Int_t Align, const char *Format, Float_t FontSize=0.3, Int_t FontColor=1); //*MENU
173// add contents to the pave (for more details see section
174// "resource files")
175//
176// void SetDay(const char *Format="%a", Float_t FontSize=0.3, Int_t Color=kBlack)
177// void SetDate(const char *Format="%e", Float_t FontSize=0.3, Int_t Color=kBlack) { Remove(GetAlign()); Add("Date", GetAlign(), Format, FontSize, Color); } //*MENU*
178// set the current position in the pave to a format defined by Format.
179// with FontSize and FontColor. For more details see MTime::GetStringFmt
180// or the man-page of strftime. The name of the corrsponding resources
181// is set to "Day" or "Date".
182//
183// void SetHoliday(Float_t FontSize=0.13, Int_t Color=kBlue)
184// void SetBirthday(Float_t FontSize=0.13, Int_t Color=kBlue)
185// void SetEaster(Float_t FontSize=0.13, Int_t Color=kBlue)
186// set the current position in the pave to a holiday with name
187// "Holiday", "Birthday" or "Easter". The holidays are read from the
188// holiday resource file. For more details see section "Resource files"
189//
190// void AddHoliday(const char *text)
191// void AddBirthday(const char *text)
192// void AddEaster(const char *text)
193// Add a holiday ("Holiday.mm/dd", "Birthday.mm/dd" or "Easter.%d")
194// for the current date (for easter the offset to easter is used instead)
195// to the holiday resources.
196//
197// void Remove()
198// Remove the contents from the edge you are pointing to.
199//
200// void PrintEnv()
201// Print the current resources.
202//
203// void SetEnv(const char *VariableName, const char *Value)
204// Set a new resource.
205//
206// void RemoveEnv(const char *VariableName)
207// Remove a resource and all subsequent resources
208//
209// void SetMoonGraf(Int_t Align, Float_t Radius)
210// void SetMoonText(Int_t Align, Int_t Type, Int_t Continous)
211// change the setup of the moon. For more details see the
212// section "Resource Files"
213//
214//
215// Format
216// ------
217//
218// For convinience here is a copy from MTime of the most important
219// format string to be used in the "Format" resource, GetStringFmt
220// or DrawDate:
221//
222// %a The abbreviated weekday name according to the current locale.
223// %A The full weekday name according to the current locale.
224// %b The abbreviated month name according to the current locale.
225// %B The full month name according to the current locale.
226// %d The day of the month as a decimal number (range 01 to 31).
227// %e Like %d, the day of the month as a decimal number,
228// but a leading zero is replaced by a space.
229// %H The hour as a decimal number using a 24-hour clock (range 00 to 23)
230// %k The hour (24-hour clock) as a decimal number (range 0 to 23);
231// single digits are preceded by a blank.
232// %m The month as a decimal number (range 01 to 12).
233// %x The preferred date representation for the current locale w/o time.
234// %y The year as a decimal number without a century (range 00 to 99).
235// %Y The year as a decimal number including the century.
236
237/////////////////////////////////////////////////////////////////////////////
238#include "MCalendar.h"
239
240#include <TStyle.h>
241#include <TLatex.h>
242#include <TArrayD.h>
243#include <TCanvas.h>
244#include <TSystem.h>
245#include <TEllipse.h>
246#include <TASImage.h>
247#include <TPaveText.h>
248
249#include "MEnv.h"
250#include "MTime.h"
251
252ClassImp(MCalendar);
253
254using namespace std;
255
256//---------------------------------------------------------------------------
257//
258// Convert Umlauts and other exotic characters to TLatex readable characters
259//
260void MCalendar::Convert2Latex(TString &str)
261{
262 str.ReplaceAll("\xe4", "\\ddot{a}");
263 str.ReplaceAll("\xf6", "\\ddot{o}");
264 str.ReplaceAll("\xfc", "\\ddot{u}");
265 str.ReplaceAll("\xc4", "\\ddot{A}");
266 str.ReplaceAll("\xd6", "\\ddot{O}");
267 str.ReplaceAll("\xdc", "\\ddot{U}");
268 str.ReplaceAll("\xdf", "\\beta");
269 str.ReplaceAll("\xe1", "\\acute{a}");
270 str.ReplaceAll("\xe9", "\\acute{e}");
271 str.ReplaceAll("\xec", "\\grave{i}");
272
273 str.ReplaceAll("\xc3\xa4", "\\ddot{a}");
274 str.ReplaceAll("\xc3\xb6", "\\ddot{o}");
275 str.ReplaceAll("\xc3\xbc", "\\ddot{u}");
276 str.ReplaceAll("\xc3\x84", "\\ddot{A}");
277 str.ReplaceAll("\xc3\x96", "\\ddot{O}");
278 str.ReplaceAll("\xc3\x9c", "\\ddot{U}");
279 str.ReplaceAll("\xc3\x9f", "\\beta");
280 str.ReplaceAll("\xc3\xa1", "\\acute{a}");
281 str.ReplaceAll("\xc3\xa9", "\\acute{e}");
282 str.ReplaceAll("\xc3\xac", "\\grave{i}");
283}
284
285void MCalendar::ConvertUTF8(TString &str, Bool_t fwd)
286{
287 if (fwd)
288 {
289 str.ReplaceAll("\xe4", "\xc3\xa4");
290 str.ReplaceAll("\xf6", "\xc3\xb6");
291 str.ReplaceAll("\xfc", "\xc3\xbc");
292 str.ReplaceAll("\xc4", "\xc3\x84");
293 str.ReplaceAll("\xd6", "\xc3\x96");
294 str.ReplaceAll("\xdc", "\xc3\x9c");
295 str.ReplaceAll("\xdf", "\xc3\x9f");
296 str.ReplaceAll("\xe1", "\xc3\xa1");
297 str.ReplaceAll("\xe9", "\xc3\xa9");
298 str.ReplaceAll("\xec", "\xc3\xac");
299 }
300 else
301 {
302 str.ReplaceAll("\xc3\xa4", "\xe4");
303 str.ReplaceAll("\xc3\xb6", "\xf6");
304 str.ReplaceAll("\xc3\xbc", "\xfc");
305 str.ReplaceAll("\xc3\x84", "\xc4");
306 str.ReplaceAll("\xc3\x96", "\xd6");
307 str.ReplaceAll("\xc3\x9c", "\xdc");
308 str.ReplaceAll("\xc3\x9f", "\xdf");
309 str.ReplaceAll("\xc3\xa1", "\xe1");
310 str.ReplaceAll("\xc3\xa9", "\xe9");
311 str.ReplaceAll("\xc3\xac", "\xec");
312 }
313}
314
315
316//---------------------------------------------------------------------------
317//
318// TEnv doesn't have a streamer so we have to make sure that the
319// resources get corretly cloned.
320//
321TObject *MCalendar::Clone(const char *newname) const
322{
323 MCalendar *cal = (MCalendar*)TObject::Clone(newname);
324
325 if (cal->fEnv)
326 delete cal->fEnv;
327 if (cal->fEnvHolidays)
328 delete cal->fEnvHolidays;
329
330 cal->fEnv = (MEnv*)fEnv->Clone();
331 cal->fEnvHolidays = (MEnv*)fEnvHolidays->Clone();
332
333 return cal;
334}
335
336//---------------------------------------------------------------------------
337//
338// return the StringFmt (see MTime::GetStringFmt or strftime)
339// corresponding to the Format fmt (Default="%B", LongMonthName).
340// For more complicated formatings day, hour, minutes and sec can
341// be given.
342//
343TString MCalendar::GetStringFmt(const char *fmt, Int_t day, Int_t h, Int_t m, Int_t s) const
344{
345 MTime t;
346 t.Set(fYear, fMonth, day, h, m, s);
347 return t.GetStringFmt(fmt, GetLanguage());
348}
349
350//---------------------------------------------------------------------------
351//
352// Get the Pave setup for the given condition from the resources
353//
354void MCalendar::GetPave(TPave &pave, Bool_t active, Int_t n)
355{
356 // ----- Default ----
357 TPave def;
358 def.SetName(pave.GetName());
359 def.SetLineStyle(kSolid);
360 def.SetLineColor(kBlack);
361 def.SetLineWidth(1);
362 def.SetFillColor(18);
363 def.SetFillStyle(1001);
364 def.SetCornerRadius(0);
365 def.SetBorderSize(1);
366
367 fEnv->GetAttPave("", def);
368
369 def.Copy(pave);
370
371 pave.SetCornerRadius(def.GetCornerRadius());
372 pave.SetLineColor(active ? kBlack : 15);
373
374 const char *fmt1 = active ? "Active" : "Inactive";
375 const char *fmt2 = active ? "Active.%d" : "Inactive.%d";
376
377 fEnv->GetAttributes( fmt1, &pave);
378 fEnv->GetAttributes(Form(fmt2, n), &pave);
379}
380
381//---------------------------------------------------------------------------
382//
383// Get the Moon setup for the given condition from the resources
384//
385void MCalendar::GetMoon(TAttText &text, TAttFill &fill, Bool_t active, Int_t n)
386{
387 TAttText txt(11, 0, gStyle->GetTextColor(), gStyle->GetTextFont(), 0.13);
388 TAttFill fil(0, 1001);
389
390 fEnv->GetAttText("Moon", txt);
391 fEnv->GetAttFill("Moon", fil);
392
393 txt.Copy(text);
394 fil.Copy(fill);
395
396 text.SetTextColor(active ? kRed : 15);
397 fill.SetFillColor(active ? kBlack : 15);
398
399 const char *fmt1 = active ? "Moon.Active" : "Moon.Inactive";
400 const char *fmt2 = active ? "Moon.Active.%d" : "Moon.Inactive.%d";
401
402 fEnv->GetAttText(fmt1, text);
403 fEnv->GetAttFill(fmt1, fill);
404
405 fEnv->GetAttText(Form(fmt2, n), text);
406 fEnv->GetAttFill(Form(fmt2, n), fill);
407}
408
409//---------------------------------------------------------------------------
410//
411// Get the Text setup for the given condition from the resources
412//
413void MCalendar::GetLatex(TLatex &latex, Bool_t active, Int_t n)
414{
415 const TString fmt = fEnv->GetValue(Form("%s.Format", latex.GetName()), "");
416 latex.SetTitle(fmt);
417
418 TAttText(0, 0, kBlack, gStyle->GetTextFont(), 0.3).Copy(latex);
419 fEnv->GetAttText(latex.GetName(), latex);
420
421 if (!active)
422 latex.SetTextColor(15);
423
424 const char *fmt1 = active ? "%s.Active" : "%s.Inactive";
425 const char *fmt2 = active ? "%s.Active.%d" : "%s.Inactive.%d";
426
427 fEnv->GetAttText(Form(fmt1, latex.GetName()), latex);
428 fEnv->GetAttText(Form(fmt2, latex.GetName(), n), latex);
429}
430
431//---------------------------------------------------------------------------
432//
433// Add a text. The name determins the identifier for which the resources
434// are searched, align the position in the pave (the convention is the same
435// as in TAttText). If a format fmt is given the date corresponding to the
436// pave is converted to a string using MTime::GetStringFmt. See MTime
437// for more details. If the format is empty the Holiday resources are
438// searched for an entry with the name. size defines the default height
439// of the text in units of the pave-height and color the default color in
440// case of active days.
441// eg.
442// Add("Day", 13, "%a", 0.3, kRed);
443// would produce a short WeekDay-name (%a) at the top left edge with
444// with a default height of 0.3*pave-height in Red. You can change
445// the behaviour from the resource file by:
446// Day.{TextAttribute}
447// Day.Active.{TextAttribute}
448// Day.Inctive.{TextAttribute}
449// Day.Active.i.{TextAttribute}
450// Day.Inctive.i.{TextAttribute}
451// for more details about TextAttribute see MEnv::GetAttText and TAttText.
452// i is a placeholder for the WeekDay number (starting with sunday=0)
453//
454void MCalendar::Add(const char *name, Int_t align, const char *fmt, Float_t size, Int_t col)
455{
456 TAttText att(align, 0, col, gStyle->GetTextFont(), size);
457 Add(name, fmt, att);
458}
459
460void MCalendar::Add(const char *name, const char *fmt, const TAttText &att)
461{
462 fEnv->SetAttText(name, att);
463 fEnv->SetValue(Form("%s.Format", name), fmt);
464
465 const TString cont = Form(" %s ", fEnv->GetValue("Contents", ""));
466 const TString form = Form(" %s ", name);
467 if (!cont.Contains(form))
468 fEnv->SetValue("Contents", Form("%s %s", cont.Strip(TString::kBoth).Data(), name));
469}
470
471//---------------------------------------------------------------------------
472//
473// Save the current layout to a resource file. If no filename is given
474// the filename of the current open resource file is used.
475//
476void MCalendar::SaveResourceFile(const char *fname)
477{
478 const TString name = fname ? fname : fEnv->GetName();
479
480 gSystem->Unlink(name);
481
482 MEnv env(name);
483
484 env.SetValue("FirstDay", fFirstDay);
485 env.SetValue("NumBlocks", fNumBlocks);
486
487 env.SetValue("Orientation", fOrientation);
488
489 env.SetValue("Moon.Graf.Align", fMoonAlignGraf);
490 env.SetValue("Moon.Text.Align", fMoonAlignText);
491 env.SetValue("Moon.Text.Type", fMoonTextType);
492 env.SetValue("Moon.Text.Continous", fMoonTextCont);
493 env.SetValue("Moon.Graf.Radius", fMoonRadius);
494
495 env.SetValue("MarginX", fMarginX);
496 env.SetValue("MarginY", fMarginY);
497 env.SetValue("CellSpace", fCellSpace);
498 env.SetValue("BlockSpace", fBlockSpace);
499
500 env.SetValue("Language", GetLanguage());
501
502 env.SetValue("HolidayFile", fEnvHolidays->GetName());
503
504 env.AddEnv(*fEnv);
505 env.Save();
506}
507
508//---------------------------------------------------------------------------
509//
510// Save the current holidays to a resource file. If no filename is given
511// the filename of the current open holiday file is used.
512//
513void MCalendar::SaveHolidayFile(const char *fname)
514{
515 const TString name = fname ? fname : fEnvHolidays->GetName();
516
517 gSystem->Unlink(name);
518
519 MEnv env(name);
520 env.AddEnv(*fEnvHolidays);
521 env.Save();
522}
523
524//---------------------------------------------------------------------------
525//
526// The Layout will be resetted and than restored from the specified
527// resource file. If no filename is given the filename of the current
528// open resource file is used.
529//
530void MCalendar::ReadResourceFile(const char *fname)
531{
532 const TString name = fname ? fname : fEnv->GetName();
533
534 ResetLayout();
535
536 delete fEnv;
537 fEnv = new MEnv(name);
538
539 fFirstDay = fEnv->GetValue("FirstDay", fFirstDay);
540 fNumBlocks = fEnv->GetValue("NumBlocks", fNumBlocks);
541
542 fOrientation = fEnv->GetValue("Orientation", fOrientation);
543
544 fMoonAlignGraf = fEnv->GetValue("Moon.Graf.Align", fMoonAlignGraf);
545 fMoonAlignText = fEnv->GetValue("Moon.Text.Align", fMoonAlignText);
546 fMoonTextType = fEnv->GetValue("Moon.Text.Type", fMoonTextType);
547 fMoonTextCont = fEnv->GetValue("Moon.Text.Continous", fMoonTextCont);
548 fMoonRadius = fEnv->GetValue("Moon.Graf.Radius", fMoonRadius);
549
550 fMarginX = fEnv->GetValue("MarginX", fMarginX);
551 fMarginY = fEnv->GetValue("MarginY", fMarginY);
552 fCellSpace = fEnv->GetValue("CellSpace", fCellSpace);
553 fBlockSpace = fEnv->GetValue("BlockSpace", fBlockSpace);
554
555 SetLocal(fEnv->GetValue("Language", ""));
556 ReadHolidayFile();
557}
558
559//---------------------------------------------------------------------------
560//
561// The Holidays will be resetted and than restored from the specified
562// holiday file. If no filename is given the filename of the current
563// open holiday file is used.
564//
565void MCalendar::ReadHolidayFile(const char *fname)
566{
567 const TString name = fname ? fname : fEnvHolidays->GetName();
568
569 if (fEnvHolidays)
570 delete fEnvHolidays;
571 fEnvHolidays = new MEnv(name);
572}
573
574//---------------------------------------------------------------------------
575//
576// Reset the layout (remove everything)
577//
578void MCalendar::ResetLayout()
579{
580 fOrientation = kFALSE;
581
582 fFirstDay = 1;
583 fNumBlocks = 2;
584
585 fMoonAlignGraf = 0;
586 fMoonAlignText = 0;
587 fMoonTextType = 0;
588 fMoonTextCont = kFALSE;
589 fMoonRadius = 0.08;
590
591 fMarginX = 0.05;
592 fMarginY = 0.05;
593
594 fCellSpace = 0.01;
595 fBlockSpace = 0.1;
596
597 if (fEnv)
598 delete fEnv;
599
600 fEnv = new MEnv("/dev/null");
601}
602
603//---------------------------------------------------------------------------
604//
605// Reset the holidays (remove everything)
606//
607void MCalendar::ResetHolidays()
608{
609 if (fEnvHolidays)
610 delete fEnvHolidays;
611
612 fEnvHolidays = new MEnv("/dev/null");
613}
614
615//---------------------------------------------------------------------------
616//
617// Set the holidays to the default holidays
618//
619void MCalendar::SetDefaultHolidays()
620{
621 ResetHolidays();
622
623 fEnvHolidays->SetValue("Easter.0", "Easter");
624 fEnvHolidays->SetValue("Holiday.01/01", "New Year");
625 fEnvHolidays->SetValue("Holiday.12/25", "Christmas");
626 fEnvHolidays->SetValue("Holiday.12/26", "Christmas");
627}
628
629//---------------------------------------------------------------------------
630//
631// Set the layout to the default layout
632//
633void MCalendar::SetDefaultLayout()
634{
635 ResetLayout();
636
637 fMoonAlignGraf = 11;
638 fMoonAlignText = 11;
639
640 fEnv->SetValue("Contents", "Day Date Holiday Birthday Easter");
641
642 fEnv->SetValue("Day.TextAlign", "top left");
643 fEnv->SetValue("Day.Format", "%e");
644
645 fEnv->SetValue("Date.TextAlign", "bottom right");
646 fEnv->SetValue("Date.Format", "%a");
647
648 fEnv->SetValue("Holiday.TextAlign", "center");
649 fEnv->SetValue("Holiday.TextSize", 0.13);
650 fEnv->SetValue("Holiday.TextColor", kBlue);
651
652 fEnv->SetValue("Birthday.TextAlign", "center");
653 fEnv->SetValue("Birthday.TextSize", 0.13);
654 fEnv->SetValue("Birthday.TextColor", kBlue);
655
656 fEnv->SetValue("Easter.TextAlign", "center");
657 fEnv->SetValue("Easter.TextSize", 0.13);
658 fEnv->SetValue("Easter.TextColor", kBlue);
659
660 fEnv->SetValue("Date.Active.0.TextColor", kRed);
661
662 fEnv->SetValue("Date.Active.TextFont", 22);
663 fEnv->SetValue("Day.Active.TextFont", 22);
664 fEnv->SetValue("Date.Inactive.TextFont", 132);
665 fEnv->SetValue("Day.Inactive.TextFont", 132);
666
667 // fEnv->SetValue("Date.Inactive.LineStyle", kDashed);
668 // fEnv->SetValue("Date.Inactive.FillColor", kWhite);
669}
670
671//---------------------------------------------------------------------------
672//
673// Create a calendar piece for the given year and month. If a filename
674// is given the corresponding resource file is read. If no month and/or
675// no year is given the current date is used instead.
676//
677MCalendar::MCalendar(UShort_t y, Byte_t m, const char *fname)
678 : fYear(y==0?MTime(-1).Year():y), fMonth(m==0?MTime(-1).Month():m)
679{
680 fEnv =0;
681 fEnvHolidays=0;
682
683 //fUpdate = kFALSE;
684
685 SetDefaultLayout();
686 SetDefaultHolidays();
687
688 if (fname)
689 ReadResourceFile(fname);
690}
691
692//---------------------------------------------------------------------------
693//
694// Delete the two resource files
695//
696MCalendar::~MCalendar()
697{
698 delete fEnv;
699 delete fEnvHolidays;
700}
701
702//---------------------------------------------------------------------------
703//
704// Take the pave edges and the margin and calculate the new x and y
705// coordinates from it for the given alignment (as in TAttText),
706//
707TArrayD MCalendar::ConvertAlign(Int_t align, Double_t x[2], Double_t y[2], Double_t m[2]) const
708{
709 align = Rotate(align);
710
711 TArrayD p(2);
712 switch (align/10)
713 {
714 case 1: p[0] = x[0]+m[0]; break;
715 case 2: p[0] = (x[0]+x[1])/2; break;
716 case 3: p[0] = x[1]-m[0]; break;
717 }
718 switch (align%10)
719 {
720 case 1: p[1] = y[0]+m[1]; break;
721 case 2: p[1] = (y[0]+y[1])/2; break;
722 case 3: p[1] = y[1]-m[1]; break;
723 }
724 return p;
725}
726
727//---------------------------------------------------------------------------
728//
729// Rotate the aligment if the orientation is changed.
730//
731Int_t MCalendar::Rotate(Int_t align, Bool_t fwd) const
732{
733 if (!fOrientation)
734 return align;
735
736 static const Int_t a[4] = { 11, 31, 33, 13 };
737 static const Int_t b[4] = { 11, 13, 33, 31 };
738
739 const Int_t *c = fwd ? a :b;
740
741 for (int i=0; i<4; i++)
742 if (align==c[i])
743 return c[(i+1)%4];
744
745 return align;
746}
747
748//---------------------------------------------------------------------------
749//
750// Paint the text str at the position indirectly given by alignement, x and
751// y (see ConvertAlign for more details) with the attributes from TAttText.
752//
753void MCalendar::PaintLatex(TAttText &att, Int_t align, Double_t x[2], Double_t y[2], Double_t ratio[2], /*Double_t height,*/ TString str)
754{
755 TLatex tex;
756 att.Copy(tex);
757
758 Double_t m[2] = {
759 fMarginX*ratio[0],
760 fMarginY*ratio[1]
761 };
762
763 const TArrayD p = ConvertAlign(align, x, y, m);
764 /*
765 tex.SetText(p[0], p[1], str);
766 tex.SetTextAngle(0);
767 tex.SetTextSize(att.GetTextSize()*height);
768
769 while (1)
770 {
771 Double_t w = tex.GetXsize();
772 Double_t h = tex.GetYsize();
773 if (w<width-2*m[0] && h<height-2*m[1])
774 break;
775
776 tex.SetTextSize(tex.GetTextSize()*0.99);
777 }
778
779 tex.Paint();
780 */
781
782 const Double_t scale = fOrientation ? x[1]-x[0] : y[1]-y[0];
783 const Double_t phi = fOrientation ? 90 : 0;
784
785 Convert2Latex(str);
786
787 tex.SetTextAlign(align);
788 tex.PaintLatex(p[0], p[1], phi, att.GetTextSize()*scale, str);
789}
790
791//---------------------------------------------------------------------------
792//
793// Check the holiday resources for a holiday matching the the resource name:
794// name.mm/dd
795// while name is the name of the TObject, mm and dd are month and day
796// of the MTime.
797//
798// If the name is "Easter" the format of the resource searched for is
799// Easter.o
800// while o is the offset from Easter (eg. Easter.-5, Easter.0 or Easter.22)
801//
802TString MCalendar::GetHoliday(const TObject &o, const MTime &tm)
803{
804 const Int_t easter = (Int_t)MTime::GetEaster(fYear).GetMjd();
805
806 const TString fmt = o.GetTitle();
807
808 if (!fmt.IsNull())
809 return tm.GetStringFmt(fmt, GetLanguage());
810
811 TString env(o.GetName());
812
813 const TString post = env=="Easter" ?
814 Form(".%d", (Int_t)tm.GetMjd()-easter) :
815 Form(".%02d/%02d", tm.Month(), tm.Day());
816
817 return fEnvHolidays->GetValue(env+post, "");
818}
819
820//#include <iostream>
821void MCalendar::Paint(Option_t *o)
822{
823 /*
824 if (fUpdate)
825 {
826 fEnv->SetAttLine(fActive?"Date.Active":"Date.Inactive", *this);
827 fUpdate = kFALSE;
828 }
829 */
830
831 // How should this be done?
832 fOrientation = gPad->PixeltoX(1)>-gPad->PixeltoY(1);
833
834 MTime t;
835 t.Set(fYear, fMonth, 1);
836
837 Int_t n = t.WeekDay();
838
839 Int_t diff = (7-fFirstDay)%7;
840 n += diff;
841 n %= 7;
842
843 t.SetMjd(t.GetMjd()-n);
844 n = 0;
845
846 for (; n<99; n++)
847 {
848 const MTime tm(t.GetMjd()+n);
849
850 const Bool_t active = tm.Month()==(UInt_t)fMonth;
851
852 Double_t x[2], y[2], ratio[2];
853 const Bool_t rc = GetBox(n, x, y, ratio);
854
855 if (!active && rc)
856 break;
857
858 // Get part of string for this day
859 const Int_t day = (n+7-diff)%7;
860
861 TPave pave;
862 pave.SetName("Date");
863 GetPave(pave, active, day);
864
865 // ---------- Paint Border and fill area ----------
866 pave.SetX1NDC(x[0]);
867 pave.SetY1NDC(y[0]);
868 pave.SetX2NDC(x[1]);
869 pave.SetY2NDC(y[1]);
870 pave.Paint(pave.GetOption());
871
872 // ---------- Paint Text ----------
873 const TString contents = fEnv->GetValue("Contents", "");
874 TObjArray *arr = contents.Tokenize(" ");
875
876 TIter Next(arr);
877 TObject *o=0;
878 while ((o=Next()))
879 {
880 TLatex latex;
881 latex.SetName(o->GetName());
882
883 GetLatex(latex, active, day);
884
885 const TString text = GetHoliday(latex, tm);
886
887 if (!text.IsNull())
888 PaintLatex(latex, latex.GetTextAlign(), x, y, ratio, text);
889
890 }
891
892 delete arr;
893
894 // ---------- Paint Moon Phase -----------
895 Double_t r[2] = {
896 fMoonRadius*ratio[0],
897 fMoonRadius*ratio[1]
898 };
899 Double_t m[2] = {
900 fMarginX*ratio[0] + r[0],
901 fMarginY*ratio[1] + r[1]
902 };
903
904 TAttText text;
905 TAttFill fill;
906 GetMoon(text, fill, active, day);
907
908 // Shift if grafic and moon should be displayed at the same
909 // location, the text is a discrete number and it is
910 // switched to continous.
911 const Float_t phi = fOrientation ? 90 : 0;
912 const Int_t dx = fOrientation;
913 const Int_t dy = (fOrientation+1)%2;
914 const Bool_t cont = fMoonTextType==0 || fMoonTextCont;
915 if (fMoonAlignGraf)
916 {
917 TArrayD p = ConvertAlign(fMoonAlignGraf, x, y, m);
918
919 if (fMoonAlignGraf==fMoonAlignText && cont && fMoonAlignGraf==22)
920 p[dy] += m[dy]/2;
921
922 TEllipse e(p[0], p[1], r[0], r[1], -90+phi, 90+phi, 0);
923 fill.Copy(e);
924 e.SetLineStyle(0);
925 e.Paint();
926 if (tm.GetMoonPhase()<0.5)
927 {
928 e.SetLineStyle(kSolid);
929 e.SetLineColor(pave.GetFillColor());
930 e.SetFillColor(pave.GetFillColor());
931 }
932 else
933 {
934 e.SetPhimin(90+phi); // bug in PaintEllipse!
935 e.SetPhimax(270+phi); // bug in PaintEllipse!
936 }
937 const Double_t R = tm.GetMoonPhase()<0.5 ? 1-tm.GetMoonPhase() : tm.GetMoonPhase();
938 const Double_t r0 = 1.0-TMath::Sqrt(2.0-2.0*R);
939 if (fOrientation)
940 e.SetR2(r[1]*r0); // bug in PaintEllipse!
941 else
942 e.SetR1(r[0]*r0); // bug in PaintEllipse!
943 e.Paint();
944 }
945
946 if (fMoonAlignGraf==fMoonAlignText && !cont && tm.GetMoonPhase()>0.004)
947 continue;
948
949 // ---------- Paint Moon Text -----------
950 if (fMoonAlignText)
951 {
952 if (fMoonAlignGraf!=fMoonAlignText || (fMoonAlignGraf==fMoonAlignText && !cont))
953 m[dx] -= r[dx];
954
955 TArrayD p = ConvertAlign(fMoonAlignText, x, y, m);
956
957 if (fMoonAlignGraf==fMoonAlignText && cont)
958 {
959 switch (fMoonAlignGraf/10)
960 {
961 case 1: p[dx] += m[dx]; break;
962 case 2: p[dy] += fMoonAlignGraf%10==1 ? m[dy]*1.25 : -m[dy]*1.25; break;
963 case 3: p[dx] -= m[dx]; break;
964 }
965 }
966
967 TString num;
968 switch (fMoonTextType)
969 {
970 case 0:// kMoonPhase:
971 num = Form("%d%%", TMath::Nint(tm.GetMoonPhase()*100));
972 break;
973 case 1://kMoonPeriod:
974 num = Form("%d", (Int_t)tm.GetMoonPeriod());
975 break;
976 case 2://kMagicPeriod:
977 num = Form("%d", tm.GetMagicPeriod());
978 break;
979 }
980
981 const Double_t scale = fOrientation ? x[1]-x[0] : y[1]-y[0];
982
983 TLatex tex;
984 text.Copy(tex);
985 tex.SetTextAlign(10*(fMoonAlignText/10)+2); // 12
986 tex.PaintLatex(p[0], p[1], phi, text.GetTextSize()*scale, num);
987 }
988 }
989
990 /*
991 TASImage img;
992 img.FromPad(gPad);
993 img.Flip(90);
994 img.Paint();
995 */
996}
997
998Bool_t MCalendar::GetBox(Int_t n, Double_t x[2], Double_t y[2], Double_t *ratio)
999{
1000 const Int_t maxrows = 28/(7*fNumBlocks) + 1;
1001 const Float_t addrows = 0;
1002
1003 const Float_t ratio0 = -gPad->PixeltoX(1)/gPad->PixeltoY(1);
1004
1005 // Cellspace
1006 const Float_t celly = fCellSpace;
1007 const Float_t cellx = fOrientation ? fCellSpace/ratio0 : fCellSpace*ratio0;
1008
1009 // Blockspace
1010 //Float_t blockspacey = fBlockSpace;
1011 const Float_t blockx = fOrientation ? fBlockSpace/ratio0 : fBlockSpace*ratio0;
1012
1013 const Float_t w = (0.98-cellx*(7*fNumBlocks-1)-(fNumBlocks-1)*blockx)/(fNumBlocks*7);
1014 const Float_t h = (0.98-celly*(maxrows-1)/*-blockspacey*/)/(maxrows+addrows);
1015
1016
1017 const Int_t ix = n%(7*fNumBlocks);
1018 const Int_t iy = n/(7*fNumBlocks);
1019
1020 const Int_t col = ix/7;
1021
1022 const Double_t p0 = 0.01 - col*(cellx - blockx);
1023
1024 TArrayD a(2), b(2);
1025
1026 a[0] = p0 + ix*(cellx + w);
1027 a[1] = p0 + ix*(cellx + w) + w;
1028
1029 b[0] = 0.99 - iy*(celly + h) - h;
1030 b[1] = 0.99 - iy*(celly + h);
1031
1032 if (ratio)
1033 {
1034 ratio[0] = ratio0>1 ? h : h*ratio0;
1035 ratio[1] = ratio0>1 ? h/ratio0 : h;
1036 }
1037
1038 if (fOrientation)
1039 {
1040 x[0] = 1-b[1];
1041 x[1] = 1-b[0];
1042 y[0] = a[0];
1043 y[1] = a[1];
1044 }
1045 else
1046 {
1047 x[0] = a[0];
1048 x[1] = a[1];
1049 y[0] = b[0];
1050 y[1] = b[1];
1051 }
1052 return ix==0 && iy>0;
1053}
1054
1055//---------------------------------------------------------------------------
1056//
1057// Determine the absolute number of the day from the event (mouse)
1058// position.
1059//
1060Int_t MCalendar::GetN(Double_t x[2], Double_t y[2])
1061{
1062 if (!gPad)
1063 return 0;
1064
1065 const Double_t px = gPad->AbsPixeltoX(gPad->GetEventX());
1066 const Double_t py = gPad->AbsPixeltoY(gPad->GetEventY());
1067
1068 int n=0;
1069 for (n=0; n<99; n++)
1070 {
1071 GetBox(n, x, y);
1072 if (x[0]<px && px<x[1] && y[0]<py && py<y[1])
1073 break;
1074 }
1075
1076 return n==99 ? -1 : n;
1077}
1078
1079//---------------------------------------------------------------------------
1080//
1081// Determine the date of the day from the event (mouse) position.
1082//
1083MTime MCalendar::GetDate()
1084{
1085 const Int_t n = GetN();
1086 if (n<0)
1087 return MTime();
1088
1089 MTime t;
1090 t.Set(fYear, fMonth, 1);
1091
1092 Int_t k = t.WeekDay();
1093
1094 k += (7-fFirstDay)%7;
1095 k %= 7;
1096
1097 return MTime(t.GetMjd()-k+n);
1098}
1099
1100//---------------------------------------------------------------------------
1101//
1102// Determin the alignment of the event (mouse) position.
1103//
1104Int_t MCalendar::GetAlign()
1105{
1106 Double_t x[2], y[2];
1107 if (GetN(x, y)<0)
1108 return 0;
1109
1110 const Double_t px = gPad->AbsPixeltoX(gPad->GetEventX());
1111 const Double_t py = gPad->AbsPixeltoY(gPad->GetEventY());
1112
1113 const Int_t alignx = (Int_t)(3*(px-x[0])/(x[1]-x[0]))+1;
1114 const Int_t aligny = (Int_t)(3*(py-y[0])/(y[1]-y[0]))+1;
1115
1116 return Derotate(alignx*10+aligny);
1117}
1118
1119//---------------------------------------------------------------------------
1120//
1121// Remove the text entry at the event (mouse) position.
1122//
1123void MCalendar::Remove(Int_t align)
1124{
1125 const TString cont = fEnv->GetValue("Contents", "");
1126 TObjArray *arr = cont.Tokenize(" ");
1127
1128 TIter Next(arr);
1129 TObject *o=0;
1130 while ((o=Next()))
1131 {
1132 TAttText att;
1133 fEnv->GetAttText(o->GetName(), att);
1134
1135 if (att.GetTextAlign()!=align)
1136 continue;
1137
1138 TString cont = Form(" %s ", fEnv->GetValue("Contents", ""));
1139 cont.ReplaceAll(Form(" %s ", o->GetName()), " ");
1140 fEnv->SetValue("Contents", cont.Strip(TString::kBoth).Data());
1141
1142 RemoveEnv(o->GetName());
1143 }
1144
1145 delete arr;
1146}
1147
1148Int_t MCalendar::DistancetoPrimitive(Int_t x, Int_t y)
1149{
1150 const Double_t px = gPad->AbsPixeltoX(x);
1151 const Double_t py = gPad->AbsPixeltoY(y);
1152
1153 return px>0.01 && px<0.99 && py>0.01 && py<0.99 ? 0 : 99999;
1154}
1155
1156//---------------------------------------------------------------------------
1157//
1158// Add a holiday named "text" at the event (mouse) position.
1159//
1160void MCalendar::AddHoliday(const char *text)
1161{
1162 MTime t = GetDate();
1163 if (!t)
1164 return;
1165
1166 const TString str = Form("Holiday.%02d/%02d", t.Month(), t.Day());
1167
1168 fEnvHolidays->SetValue(str, text);
1169}
1170
1171//---------------------------------------------------------------------------
1172//
1173// Add a birthday named "text" at the event (mouse) position.
1174//
1175void MCalendar::AddBirthday(const char *text)
1176{
1177 MTime t = GetDate();
1178 if (!t)
1179 return;
1180
1181 const TString str = Form("Birthday.%02d/%02d", t.Month(), t.Day());
1182
1183 fEnvHolidays->SetValue(str, text);
1184}
1185
1186//---------------------------------------------------------------------------
1187//
1188// Add a easterday named "text" at the event (mouse) position. The special
1189// thing is that the holiday is relative to easter and will shift with
1190// easter for other years.
1191//
1192void MCalendar::AddEaster(const char *text)
1193{
1194 MTime t = GetDate();
1195 if (!t)
1196 return;
1197
1198 const Int_t easter = (Int_t)MTime::GetEaster(fYear).GetMjd();
1199
1200 const TString str = Form("Easter.%d", (Int_t)t.GetMjd()-easter);
1201
1202 fEnvHolidays->SetValue(str, text);
1203}
1204
1205//---------------------------------------------------------------------------
1206//
1207// Print the current resources.
1208//
1209void MCalendar::PrintEnv() const
1210{
1211 fEnv->Print();
1212}
1213
1214//---------------------------------------------------------------------------
1215//
1216// Set a new resource.
1217//
1218void MCalendar::SetEnv(const char *VariableName, const char *Value) const
1219{
1220 fEnv->SetValue(VariableName, Value);
1221}
1222
1223//---------------------------------------------------------------------------
1224//
1225// Remove a resource and all subsequent resources
1226//
1227void MCalendar::RemoveEnv(const char *name) const
1228{
1229 const TString n1 = name;
1230 const TString n2 = Form("%s.", name);
1231
1232 TCollection *table = fEnv->GetTable();
1233
1234 TIter Next(table);
1235 TObject *o=0;
1236 while ((o=Next()))
1237 if (n1==o->GetName() || TString(o->GetName()).BeginsWith(n2))
1238 delete table->Remove(o);
1239}
1240
1241//---------------------------------------------------------------------------
1242//
1243// Create a pad with the given coordinates, Draw a clone of the image
1244// into it and resize the pad to the image properties such that it is
1245// centered in the original area.
1246//
1247// DrawImage cd()'s to the new pad.
1248//
1249TASImage *MCalendar::DrawImage(const TASImage &img, Float_t x1, Float_t y1, Float_t x2, Float_t y2) const
1250{
1251 TPad *pad=new TPad("Img", "Image", x1, y1,x2, y2);
1252 pad->SetBorderMode(0);
1253 pad->SetFillColor(gPad?gPad->GetFillColor():kWhite);
1254 pad->SetBit(kCanDelete);
1255 pad->SetTopMargin(0);
1256 pad->SetRightMargin(0);
1257 pad->SetLeftMargin(0);
1258 pad->SetBottomMargin(0);
1259 pad->Draw();
1260
1261 gROOT->SetSelectedPad(0);
1262
1263 pad->cd();
1264
1265 TASImage *clone = (TASImage*)img.DrawClone();
1266 clone->SetBit(kCanDelete);
1267
1268 pad->Modified();
1269 pad->Update();
1270
1271 const Int_t w = clone->GetScaledWidth();
1272 const Int_t h = clone->GetScaledHeight();
1273
1274 TCanvas *c = pad->GetCanvas();
1275
1276 const Float_t ml = (1-c->PixeltoX(w))/2;
1277 const Float_t mb = (1+c->PixeltoY(h))/2;
1278
1279 pad->SetPad(ml, 2*mb, 1-ml, 1);
1280
1281 return clone;
1282}
1283
1284//---------------------------------------------------------------------------
1285//
1286// Small helper for GetImage: Allocate a new TASImage. If it is valid
1287// return the pointer, if not delete the object and return NULL.
1288//
1289TASImage *MCalendar::ReturnFile(const char *file) const
1290{
1291 TASImage *img = new TASImage(file);
1292 if (img->IsValid())
1293 return img;
1294
1295 delete img;
1296 return NULL;
1297}
1298
1299//---------------------------------------------------------------------------
1300//
1301// Get a TASImage from a TEnv (if no TEnv is given as argument the
1302// default resource file os used). The TEnv is searched for the following
1303// tags in the following order:
1304//
1305// %B: The month name as defined by the local (try GetStringFmt("%B"))
1306// %b: The abbreviation of the month name as defined by the local (try GetStringFmt("%b"))
1307// %02d: The number of the month with leading zeros.
1308//
1309// If no tag could be found or the image read is invalid NULL is returned.
1310// Otherwise a newly allocated TASImage is returned (the used is responsible
1311// of deleting it)
1312//
1313TASImage *MCalendar::GetImage(TEnv *env)
1314{
1315 if (!env)
1316 env = fEnv;
1317
1318 TString fStrMonth = GetStringFmt("%B");
1319 TString fStrMonth3 = GetStringFmt("%b");
1320
1321 ConvertUTF8(fStrMonth3, kFALSE);
1322 ConvertUTF8(fStrMonth, kFALSE);
1323
1324 TString file = env->GetValue(fStrMonth, "");
1325 if (!file.Strip(TString::kBoth).IsNull())
1326 return ReturnFile(file);
1327
1328 file = env->GetValue(fStrMonth3, "");
1329 if (!file.Strip(TString::kBoth).IsNull())
1330 return ReturnFile(file);
1331
1332 file = env->GetValue(Form("%02d", fMonth), "");
1333 if (!file.Strip(TString::kBoth).IsNull())
1334 return ReturnFile(file);
1335
1336 return NULL;
1337}
1338
1339//---------------------------------------------------------------------------
1340//
1341// Draw a Latex (after conversion with Convert2Latex, to support Umlauts,
1342// etc) text text at the coordinates x and y with the attributes att.
1343//
1344// To use a date format string (see GetStringFmt()) instead of a plain
1345// text use DrawDate instead.
1346//
1347void MCalendar::DrawLatex(Float_t x, Float_t y, const char *text, const TAttText &att)
1348{
1349 TString str(text);
1350 Convert2Latex(str);
1351
1352 TLatex *latex = new TLatex(x, y, text);
1353 att.Copy(*latex);
1354 latex->SetBit(kCanDelete);
1355 latex->Draw();
1356}
1357
1358const char *MCalendar::GetTTFontPath(const char *file) const
1359{
1360 const TString p1 = gEnv->GetValue("Root.TTFontPath", "");
1361 const TString p2 = "/usr/X11R6/lib/X11/fonts/truetype";
1362 // const TString p3 = path;
1363
1364 TString n(file);
1365
1366 if (n.First('.')<0 && n.First('/')<0)
1367 n.Append(".ttf");
1368
1369 return gSystem->Which(p1+":"+p2/*+":"+p3*/, n, kReadPermission);
1370}
1371
1372//---------------------------------------------------------------------------
1373//
1374// Draw a Text text into your image. For more details see TASImage::DrawText.
1375//
1376// This is a wrapper to simplify access to TrueType Fonts.
1377//
1378// You can just skip the path and the extension, eg "comic" is enough for
1379// the TTF "comic.ttf".
1380//
1381// The search path is "*.*.Root.TTFontPath" from gEnv (.rootrc),
1382// "/usr/X11R6/lib/X11/fonts/truetype" and path.
1383//
1384// For available fonts see eg. $ROOTSYS/fonts
1385//
1386void MCalendar::DrawText(TASImage &img, Int_t x, Int_t y, const char *txt,
1387 Int_t size, const char *color, const char *font,
1388 TImage::EText3DType type, const char *path)
1389{
1390 const char *file = GetTTFontPath(font);
1391 if (!file)
1392 return;
1393
1394 img.DrawText(x, y, txt, size, color, file, type);
1395
1396 delete file;
1397}
1398
1399#define __CINT__
1400#include <TTF.h>
1401
1402TASImage *MCalendar::DrawTTF(Float_t x1, Float_t x2, Float_t y1, Float_t y2,
1403 const char *text, Int_t size, const char *font)
1404{
1405 const char *file = GetTTFontPath(font);
1406 if (!file)
1407 return NULL;
1408
1409 TTF::SetTextFont(file);
1410
1411 delete file;
1412
1413 TTF::SetRotationMatrix(0);
1414 TTF::SetTextSize(size);
1415 TTF::PrepareString(text);
1416 TTF::LayoutGlyphs();
1417
1418 const FT_BBox &box = TTF::GetBox();
1419
1420 TASImage img(3*box.xMax/2, 3*box.yMax/2);
1421 img.FillRectangle();
1422
1423 // gROOT->GetColor(kBlack)->AsHexString()
1424 DrawDate(img, 0, 0, text, size, "#00000000", font);
1425 return DrawImage(img, x1, y1, x2, y2);
1426}
Note: See TracBrowser for help on using the repository browser.