25#include "../../../graf2d/mathtext/inc/mathtext.h"
26#include "../../../graf2d/mathtext/inc/mathrender.h"
56 public mathtext::math_text_renderer_t {
63 float _pad_pixel_transform[6];
67 float _pad_scale_x_relative;
68 float _pad_scale_y_relative;
69 float _current_font_size[mathtext::math_text_renderer_t::NFAMILY];
70 inline size_t root_face_number(
71 const unsigned int family,
const bool serif =
false)
const
73 static const int precision = 2;
75 if (family >= mathtext::math_text_renderer_t::
77 family <= mathtext::math_text_renderer_t::
79 const unsigned int offset = family -
80 mathtext::math_text_renderer_t::FAMILY_REGULAR;
82 ((offset == 0 ? 13 : offset) * 10 + precision) :
83 ((offset + 4) * 10 + precision);
84 }
else if (family >= mathtext::math_text_renderer_t::
85 FAMILY_STIX_REGULAR) {
86 const unsigned int offset = family -
87 mathtext::math_text_renderer_t::FAMILY_STIX_REGULAR;
88 return (offset + 16) * 10 + precision;
93 inline bool is_cyrillic_or_cjk(
const wchar_t c)
const
95 return mathtext::math_text_renderer_t::is_cyrillic(
c) ||
96 mathtext::math_text_renderer_t::is_cjk(
c);
98 inline size_t root_cjk_face_number(
99 const bool serif =
false)
const
101 return (serif ? 28 : 29) * 10 + 2;
104 inline mathtext::affine_transform_t
105 transform_logical_to_pixel(
void)
const
107 return mathtext::affine_transform_t::identity;
109 inline mathtext::affine_transform_t
110 transform_pixel_to_logical(
void)
const
112 return mathtext::affine_transform_t::identity;
115 inline TMathTextRenderer(
TMathText *parent)
117 _parent(parent), _font_size(0), _angle_degree(0)
124 for (i = 0; i<6; i++) _pad_pixel_transform[i] = 0;
128 _pad_scale_x_relative = 0;
129 _pad_scale_y_relative = 0;
130 for (i = 0; i < mathtext::math_text_renderer_t::NFAMILY; i++) _current_font_size[i] = 0;
133 font_size(
const unsigned int family = FAMILY_PLAIN)
const
135 return _current_font_size[family];
138 point(
const float ,
const float )
142 set_font_size(
const float size,
const unsigned int family)
144 _current_font_size[family] = size;
147 set_font_size(
const float size)
150 std::fill(_current_font_size,
151 _current_font_size + NFAMILY, size);
154 reset_font_size(
const unsigned int )
158 set_parameter(
const float x,
const float y,
const float size,
159 const float angle_degree)
161 _x0 =
gPad->XtoAbsPixel(
x);
162 _y0 =
gPad->YtoAbsPixel(
y);
169 _pad_scale = std::min(_pad_scale_x, _pad_scale_y);
171 _angle_degree = angle_degree;
173 const float angle_radiant = _angle_degree * (
kPI / 180.0);
176 _pad_pixel_transform[0] = _pad_scale * cosf(angle_radiant);
177 _pad_pixel_transform[1] = -_pad_scale * sinf(angle_radiant);
178 _pad_pixel_transform[2] = _x0;
179 _pad_pixel_transform[3] = _pad_pixel_transform[1];
180 _pad_pixel_transform[4] = -_pad_pixel_transform[0];
181 _pad_pixel_transform[5] = _y0;
188 transform_pad(
double &xt,
double &yt,
189 const float x,
const float y)
const
192 x * _pad_pixel_transform[0] +
193 y * _pad_pixel_transform[1] + _pad_pixel_transform[2]));
195 x * _pad_pixel_transform[3] +
196 y * _pad_pixel_transform[4] + _pad_pixel_transform[5]));
199 filled_rectangle(
const mathtext::bounding_box_t &bounding_box_0)
208 transform_pad(xt[0], yt[0],
209 bounding_box_0.left(),
210 bounding_box_0.bottom());
211 transform_pad(xt[1], yt[1],
212 bounding_box_0.right(),
213 bounding_box_0.bottom());
214 transform_pad(xt[2], yt[2],
215 bounding_box_0.right(),
216 bounding_box_0.top());
217 transform_pad(xt[3], yt[3],
218 bounding_box_0.left(),
219 bounding_box_0.top());
220 gPad->PaintFillArea(4, xt, yt);
223 rectangle(
const mathtext::bounding_box_t &)
226 inline mathtext::bounding_box_t
227 bounding_box(
const wchar_t character,
float ¤t_x,
228 const unsigned int family)
231 const bool cyrillic_or_cjk = is_cyrillic_or_cjk(character);
233 if (cyrillic_or_cjk) {
244 const float scale = _current_font_size[family] /
246 const FT_Glyph_Metrics metrics =
248 const float lower_left_x = metrics.horiBearingX;
249 const float lower_left_y =
250 metrics.horiBearingY - metrics.height;
251 const float upper_right_x =
252 metrics.horiBearingX + metrics.width;
253 const float upper_right_y = metrics.horiBearingY;
254 const float advance = metrics.horiAdvance;
255 const float margin = std::max(0.0F, lower_left_x);
256 const float italic_correction =
257 upper_right_x <= advance ? 0.0F :
258 std::max(0.0F, upper_right_x + margin - advance);
259 const mathtext::bounding_box_t ret =
260 mathtext::bounding_box_t(
261 lower_left_x, lower_left_y,
262 upper_right_x, upper_right_y,
263 advance, italic_correction) * scale;
265 current_x += ret.advance();
270 inline mathtext::bounding_box_t
271 bounding_box(
const std::wstring
string,
272 const unsigned int family = FAMILY_PLAIN)
277 return mathtext::bounding_box_t(0, 0, 0, 0, 0, 0);
280 std::wstring::const_iterator iterator =
string.begin();
282 mathtext::bounding_box_t ret =
283 bounding_box(*iterator, current_x, family);
286 for (; iterator !=
string.end(); ++iterator) {
287 const mathtext::point_t position =
288 mathtext::point_t(current_x, 0);
289 const mathtext::bounding_box_t glyph_bounding_box =
290 bounding_box(*iterator, current_x, family);
291 ret = ret.merge(position + glyph_bounding_box);
297 text_raw(
const float x,
const float y,
298 const std::wstring
string,
299 const unsigned int family = FAMILY_PLAIN)
309 for (std::wstring::const_iterator iterator =
string.begin(); iterator !=
string.end(); ++iterator) {
311 const bool cyrillic_or_cjk = is_cyrillic_or_cjk(buf[0]);
313 if (cyrillic_or_cjk) {
318 const mathtext::bounding_box_t
b =
319 bounding_box(buf, family);
323 transform_pad(xt, yt,
x + advance,
y);
324 gPad->PaintText(xt, yt, buf);
325 advance +=
b.advance();
326 if (cyrillic_or_cjk) {
333 text_with_bounding_box(
const float ,
const float ,
338 using mathtext::math_text_renderer_t::bounding_box;
385 TAttFill::operator = (rhs);
407 const mathtext::math_text_t math_text(t);
410 renderer->set_parameter(
x,
y, size, angle);
411 renderer->text(0, 0, math_text);
422 const mathtext::math_text_t math_text(t);
425 renderer->set_parameter(0, 0, size, angle);
427 const mathtext::bounding_box_t bounding_box =
428 renderer->bounding_box(math_text);
432 renderer->transform_pad(
433 x[0],
y[0], bounding_box.left(), bounding_box.bottom());
434 renderer->transform_pad(
435 x[1],
y[1], bounding_box.right(), bounding_box.bottom());
436 renderer->transform_pad(
437 x[2],
y[2], bounding_box.right(), bounding_box.top());
438 renderer->transform_pad(
439 x[3],
y[3], bounding_box.left(), bounding_box.top());
441 x0 = std::min(std::min(
x[0],
x[1]), std::min(
x[2],
x[3]));
442 y0 = std::min(std::min(
y[0],
y[1]), std::min(
y[2],
y[3]));
443 x1 = std::max(std::max(
x[0],
x[1]), std::max(
x[2],
x[3]));
444 y1 = std::max(std::max(
y[0],
y[1]), std::max(
y[2],
y[3]));
456 const mathtext::math_text_t math_text(t);
459 renderer->set_parameter(0, 0, size, angle);
461 const mathtext::bounding_box_t bounding_box =
462 renderer->bounding_box(math_text);
467 Short_t valign = align - 10 * halign;
470 case 0:
x = bounding_box.left();
break;
471 case 1:
x = 0;
break;
472 case 2:
x = bounding_box.horizontal_center();
break;
473 case 3:
x = bounding_box.right();
break;
476 case 0:
y = bounding_box.bottom();
break;
477 case 1:
y = 0;
break;
478 case 2:
y = bounding_box.vertical_center();
break;
479 case 3:
y = bounding_box.top();
break;
481 renderer->transform_pad(x0, y0,
x,
y);
594 if (
gPad->IsBatch()) {
607 gPad->PaintText(
x,
y, text1);
616 size = size / std::min(w,
h);
622 if (newText.
Length() == 0)
return;
645 while (newText.
Contains(
"\\frac")) {
647 i1 = newText.
Index(
"\\frac");
648 str = newText(i1,len).
Data();
649 i2 = str.
Index(
"}{");
650 newText.
Replace(i1+i2,2,
" \\over ");
654 if (newText.
Contains(
"\\splitline")) {
657 while (newText.
Contains(
"\\splitline")) {
659 i1 = newText.
Index(
"\\splitline");
660 str = newText(i1,len).
Data();
661 i2 = str.
Index(
"}{");
662 newText.
Replace(i1+i2,2,
" \\atop ");
685 const char quote =
'"';
687 if (
gROOT->ClassSaved(TMathText::Class())) {
690 out <<
" TMathText *";
697 out <<
"mathtex = new TMathText("<<
fX <<
"," <<
fY <<
","
698 << quote << s.
Data() << quote <<
");" << std::endl;
700 out <<
"mathtex->SetNDC();" << std::endl;
706 out<<
" mathtex->Draw();" << std::endl;
static const double x1[5]
R__EXTERN TVirtualPS * gVirtualPS
Fill Area Attributes class.
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
virtual void Modify()
Change current fill area attributes if necessary.
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
virtual Float_t GetTextSize() const
Return the text size.
virtual void Modify()
Change current text attributes if necessary.
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
Color_t fTextColor
Text color.
virtual void SetTextAngle(Float_t tangle=0)
Set the text angle.
virtual Float_t GetTextAngle() const
Return the text angle.
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
Font_t fTextFont
Text font.
virtual void SaveTextAttributes(std::ostream &out, const char *name, Int_t alidef=12, Float_t angdef=0, Int_t coldef=1, Int_t fondef=61, Float_t sizdef=1)
Save text attributes as C++ statement(s) on output stream out.
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Short_t fTextAlign
Text alignment.
void Copy(TAttText &atttext) const
Copy this text attributes to a new TAttText.
To draw TeX Mathematical Formula.
friend class TMathTextRenderer
virtual ~TMathText(void)
Destructor.
Double_t GetYsize(void)
Get Y size.
TMathText & operator=(const TMathText &)
TMathText Painter.
void GetSize(Double_t &x0, Double_t &y0, Double_t &x1, Double_t &y1, const Double_t size, const Double_t angle, const Char_t *t, const Int_t length)
Get the text bounding box.
void Copy(TObject &text) const
Copy.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Double_t GetXsize(void)
Get X size.
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE)
Get the text width and height.
TMathText(void)
Default constructor.
void GetAlignPoint(Double_t &x0, Double_t &y0, const Double_t size, const Double_t angle, const Char_t *t, const Int_t length, const Short_t align)
Alignment.
void Render(const Double_t x, const Double_t y, const Double_t size, const Double_t angle, const Char_t *t, const Int_t length)
Render the text.
TMathText * DrawMathText(Double_t x, Double_t y, const char *text)
Make a copy of this object with the new parameters and copy object attributes.
virtual void PaintMathText(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Paint text (used by Paint()).
virtual void Paint(Option_t *option="")
Paint text.
virtual const char * GetTitle() const
Returns title of object.
Mother of all ROOT objects.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
@ kCanDelete
if object in a list can be deleted
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
TString & Remove(Ssiz_t pos)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
static FT_Face fgFace[kTTMaxFonts]
font face
static void SetTextFont(Font_t fontnumber)
Set specified font.
static Int_t fgCurFontIdx
current font index
Base class for several text objects.
Double_t fY
Y position of text (left,center,etc..)
TText & operator=(const TText &src)
Assignment operator.
Double_t fX
X position of text (left,center,etc..)
void Copy(TObject &text) const
Copy this text to text.
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
RooArgList L(const RooAbsArg &v1)