16 #include FT_FREETYPE_H
25 #include "../../../graf2d/mathtext/inc/mathtext.h"
26 #include "../../../graf2d/mathtext/inc/mathrender.h"
52 public mathtext::math_text_renderer_t {
59 float _pad_pixel_transform[6];
63 float _pad_scale_x_relative;
64 float _pad_scale_y_relative;
65 float _current_font_size[mathtext::math_text_renderer_t::NFAMILY];
66 inline size_t root_face_number(
67 const unsigned int family,
const bool serif =
false)
const
69 static const int precision = 2;
71 if (family >= mathtext::math_text_renderer_t::
73 family <= mathtext::math_text_renderer_t::
75 const unsigned int offset = family -
76 mathtext::math_text_renderer_t::FAMILY_REGULAR;
78 ((offset == 0 ? 13 :
offset) * 10 + precision) :
79 ((offset + 4) * 10 + precision);
80 }
else if (family >= mathtext::math_text_renderer_t::
81 FAMILY_STIX_REGULAR) {
82 const unsigned int offset = family -
83 mathtext::math_text_renderer_t::FAMILY_STIX_REGULAR;
84 return (offset + 16) * 10 + precision;
89 inline bool is_cyrillic_or_cjk(
const wchar_t c)
const
91 return mathtext::math_text_renderer_t::is_cyrillic(c) ||
92 mathtext::math_text_renderer_t::is_cjk(c);
94 inline size_t root_cjk_face_number(
95 const bool serif =
false)
const
97 return (serif ? 28 : 29) * 10 + 2;
100 inline mathtext::affine_transform_t
101 transform_logical_to_pixel(
void)
const
103 return mathtext::affine_transform_t::identity;
105 inline mathtext::affine_transform_t
106 transform_pixel_to_logical(
void)
const
108 return mathtext::affine_transform_t::identity;
111 inline TMathTextRenderer(
TMathText *parent)
113 _parent(parent), _font_size(0), _angle_degree(0)
120 for (i = 0; i<6; i++) _pad_pixel_transform[i] = 0;
124 _pad_scale_x_relative = 0;
125 _pad_scale_y_relative = 0;
126 for (i = 0; i < mathtext::math_text_renderer_t::NFAMILY; i++) _current_font_size[i] = 0;
129 font_size(
const unsigned int family = FAMILY_PLAIN)
const
131 return _current_font_size[family];
134 point(
const float ,
const float )
138 set_font_size(
const float size,
const unsigned int family)
140 _current_font_size[family] = size;
143 set_font_size(
const float size)
147 _current_font_size + NFAMILY, size);
150 reset_font_size(
const unsigned int )
154 set_parameter(
const float x,
const float y,
const float size,
155 const float angle_degree)
157 _x0 =
gPad->XtoAbsPixel(x);
158 _y0 =
gPad->YtoAbsPixel(y);
165 _pad_scale =
std::min(_pad_scale_x, _pad_scale_y);
167 _angle_degree = angle_degree;
169 const float angle_radiant = _angle_degree * (kPI / 180.0);
172 _pad_pixel_transform[0] = _pad_scale * cosf(angle_radiant);
173 _pad_pixel_transform[1] = -_pad_scale * sinf(angle_radiant);
174 _pad_pixel_transform[2] = _x0;
175 _pad_pixel_transform[3] = _pad_pixel_transform[1];
176 _pad_pixel_transform[4] = -_pad_pixel_transform[0];
177 _pad_pixel_transform[5] = _y0;
184 transform_pad(
double &xt,
double &yt,
185 const float x,
const float y)
const
188 x * _pad_pixel_transform[0] +
189 y * _pad_pixel_transform[1] + _pad_pixel_transform[2]));
191 x * _pad_pixel_transform[3] +
192 y * _pad_pixel_transform[4] + _pad_pixel_transform[5]));
195 filled_rectangle(
const mathtext::bounding_box_t &bounding_box_0)
204 transform_pad(xt[0], yt[0],
205 bounding_box_0.left(),
206 bounding_box_0.bottom());
207 transform_pad(xt[1], yt[1],
208 bounding_box_0.right(),
209 bounding_box_0.bottom());
210 transform_pad(xt[2], yt[2],
211 bounding_box_0.right(),
212 bounding_box_0.top());
213 transform_pad(xt[3], yt[3],
214 bounding_box_0.left(),
215 bounding_box_0.top());
216 gPad->PaintFillArea(4, xt, yt);
219 rectangle(
const mathtext::bounding_box_t &)
222 inline mathtext::bounding_box_t
223 bounding_box(
const wchar_t character,
float ¤t_x,
224 const unsigned int family)
227 const bool cyrillic_or_cjk = is_cyrillic_or_cjk(character);
229 if (cyrillic_or_cjk) {
240 const float scale = _current_font_size[family] /
242 const FT_Glyph_Metrics metrics =
244 const float lower_left_x = metrics.horiBearingX;
245 const float lower_left_y =
246 metrics.horiBearingY - metrics.height;
247 const float upper_right_x =
248 metrics.horiBearingX + metrics.width;
249 const float upper_right_y = metrics.horiBearingY;
250 const float advance = metrics.horiAdvance;
251 const float margin =
std::max(0.0
F, lower_left_x);
252 const float italic_correction =
253 upper_right_x <= advance ? 0.0F :
254 std::max(0.0
F, upper_right_x + margin - advance);
255 const mathtext::bounding_box_t ret =
256 mathtext::bounding_box_t(
257 lower_left_x, lower_left_y,
258 upper_right_x, upper_right_y,
259 advance, italic_correction) * scale;
261 current_x += ret.advance();
262 TTF::fgCurFontIdx = old_font_index;
266 inline mathtext::bounding_box_t
267 bounding_box(
const std::wstring
string,
268 const unsigned int family = FAMILY_PLAIN)
270 if (TTF::fgCurFontIdx<0)
return mathtext::bounding_box_t(0, 0, 0, 0, 0, 0);
272 TTF::fgFace[TTF::fgCurFontIdx]->units_per_EM == 0) {
273 return mathtext::bounding_box_t(0, 0, 0, 0, 0, 0);
276 std::wstring::const_iterator iterator =
string.begin();
278 mathtext::bounding_box_t ret =
279 bounding_box(*iterator, current_x, family);
282 for(; iterator !=
string.end(); iterator++) {
283 const mathtext::point_t position =
284 mathtext::point_t(current_x, 0);
285 const mathtext::bounding_box_t glyph_bounding_box =
286 bounding_box(*iterator, current_x, family);
287 ret = ret.merge(position + glyph_bounding_box);
293 text_raw(
const float x,
const float y,
294 const std::wstring
string,
295 const unsigned int family = FAMILY_PLAIN)
305 for(std::wstring::const_iterator iterator =
string.begin();
306 iterator !=
string.end(); iterator++) {
308 const bool cyrillic_or_cjk = is_cyrillic_or_cjk(buf[0]);
310 if (cyrillic_or_cjk) {
315 const mathtext::bounding_box_t b =
316 bounding_box(buf, family);
320 transform_pad(xt, yt, x + advance, y);
321 gPad->PaintText(xt, yt, buf);
322 advance += b.advance();
323 if (cyrillic_or_cjk) {
330 text_with_bounding_box(
const float ,
const float ,
335 using mathtext::math_text_renderer_t::bounding_box;
346 fRenderer =
new TMathTextRenderer(
this);
355 fRenderer =
new TMathTextRenderer(
this);
372 fRenderer =
new TMathTextRenderer(
this);
404 const mathtext::math_text_t math_text(t);
407 renderer->set_parameter(x, y, size, angle);
408 renderer->text(0, 0, math_text);
419 const mathtext::math_text_t math_text(t);
422 renderer->set_parameter(0, 0, size, angle);
424 const mathtext::bounding_box_t bounding_box =
425 renderer->bounding_box(math_text);
429 renderer->transform_pad(
430 x[0], y[0], bounding_box.left(), bounding_box.bottom());
431 renderer->transform_pad(
432 x[1], y[1], bounding_box.right(), bounding_box.bottom());
433 renderer->transform_pad(
434 x[2], y[2], bounding_box.right(), bounding_box.top());
435 renderer->transform_pad(
436 x[3], y[3], bounding_box.left(), bounding_box.top());
453 const mathtext::math_text_t math_text(t);
456 renderer->set_parameter(0, 0, size, angle);
458 const mathtext::bounding_box_t bounding_box =
459 renderer->bounding_box(math_text);
464 Short_t valign = align - 10 * halign;
467 case 0: x = bounding_box.left();
break;
468 case 1: x = 0;
break;
469 case 2: x = bounding_box.horizontal_center();
break;
470 case 3: x = bounding_box.right();
break;
473 case 0: y = bounding_box.bottom();
break;
474 case 1: y = 0;
break;
475 case 2: y = bounding_box.vertical_center();
break;
476 case 3: y = bounding_box.top();
break;
478 renderer->transform_pad(x0, y0, x, y);
496 GetSize(x0, y0, x1, y1, size, 0, text, length);
517 GetSize(x0, y0, x1, y1, size, angle, text, length);
538 GetSize(x0, y0, x1, y1, size, angle, text, length);
599 gPad->PaintText(x, y, text1);
614 if (newText.
Length() == 0)
return;
636 while (newText.
Contains(
"\\frac")) {
638 i1 = newText.
Index(
"\\frac");
639 str = newText(i1,len).
Data();
640 i2 = str.
Index(
"}{");
641 newText.
Replace(i1+i2,2,
" \\over ");
645 if (newText.
Contains(
"\\splitline")) {
648 while (newText.
Contains(
"\\splitline")) {
650 i1 = newText.
Index(
"\\splitline");
651 str = newText(i1,len).
Data();
652 i2 = str.
Index(
"}{");
653 newText.
Replace(i1+i2,2,
" \\atop ");
664 Render(x - x0, y - y0, size, angle, text, length);
676 const char quote =
'"';
681 out <<
" TMathText *";
688 out <<
"mathtex = new TMathText("<<
fX <<
"," <<
fY <<
","
689 << quote << s.
Data() << quote <<
");" << std::endl;
691 out <<
"mathtex->SetNDC();" << std::endl;
697 out<<
" mathtex->Draw();" << std::endl;
virtual const char * GetTitle() const
Returns title of object.
virtual void PaintMathText(Double_t x, Double_t y, Double_t angle, Double_t size, const char *text)
Paint text (used by Paint()).
virtual Float_t GetTextAngle() const
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
void Copy(TAttText &atttext) const
Copy this text attributes to a new TAttText.
RooArgList L(const RooAbsArg &v1)
TString & ReplaceAll(const TString &s1, const TString &s2)
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.
virtual Float_t GetTextSize() const
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
virtual void SetFillStyle(Style_t fstyle)
void GetBoundingBox(UInt_t &w, UInt_t &h, Bool_t angle=kFALSE)
Get the text width and height.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
virtual void Modify()
Change current text attributes if necessary.
const char * Data() const
virtual void SetTextFont(Font_t tfont=62)
Fill Area Attributes class.
static void SetTextFont(Font_t fontnumber)
Set specified font.
virtual void Modify()
Change current fill area attributes if necessary.
ClassImp(TMathText) TMathText
Default constructor.
Base class for several text objects.
virtual void SetNDC(Bool_t isNDC=kTRUE)
Set NDC mode on if isNDC = kTRUE, off otherwise.
TMathText & operator=(const TMathText &)
TMathText Painter.
virtual void SetTextAlign(Short_t align=11)
static Int_t fgCurFontIdx
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Double_t length(const TVector2 &v)
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.
friend class TMathTextRenderer
virtual void SetFillColor(Color_t fcolor)
void Copy(TObject &text) const
Copy this text to text.
virtual ~TMathText(void)
Destructor.
virtual void SetTextAngle(Float_t tangle=0)
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.
Bool_t TestBit(UInt_t f) const
TString & Remove(Ssiz_t pos)
static const double x1[5]
void Copy(TObject &text) const
Copy.
To draw TeX Mathematical Formula.
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Binding & operator=(OUT(*fun)(void))
Mother of all ROOT objects.
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.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
R__EXTERN TVirtualPS * gVirtualPS
static FT_Face fgFace[kTTMaxFonts]
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.
virtual void SetTextSize(Float_t tsize=1)
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
virtual void Paint(Option_t *option="")
Paint text.
Double_t GetYsize(void)
Get Y size.
Double_t GetXsize(void)
Get X size.
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.