SDF text on a fixed grid, for judging REveText rendering quality.
A screen mode, font-size ladder B screen mode, one line per font at the same size C world mode, size ladder in world units D world mode, text rotated about y and about x E mixed mode, text at increasing depth; all lines should be the same size
REveText::SetMode() takes 0 for world, 1 for screen and 2 for mixed. Two viewers, one perspective and one orthographic, show the same scenes.
#include <map>
#include <string>
const char *kRuler = "Ill1 OQ08 //\\\\ ..";
const char *kFonts[] = {"LiberationSerif-Regular", "LiberationMono-Regular", "verdana",
"georgia", "comic", "comicbd",
"BlackChancery"};
const int kNFonts = sizeof(kFonts) / sizeof(char *);
const float kSizes[] = {0.005f, 0.008f, 0.012f, 0.018f, 0.024f, 0.033f, 0.045f, 0.060f};
const int kNSizes = sizeof(kSizes) / sizeof(float);
const double kWorldLim = 100.0;
std::map<std::string, REveElement *> gPanels;
{
t->SetText(txt);
t->SetFont(font);
t->SetTextColor(col);
t->SetDrawFrame(false);
holder->AddElement(t);
return t;
}
static void AddBBoxAnchor(
REveElement *holder,
double lim)
{
const double v[8][3] = {{-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}, {1, -1, -1},
{-1, -1, 1}, {-1, 1, 1}, {1, 1, 1}, {1, -1, 1}};
for (int i = 0; i < 8; ++i)
b->SetVertex(i, lim *
v[i][0], lim *
v[i][1], lim *
v[i][2]);
b->SetMainTransparency(90);
}
{
for (int i = 0; i < kNSizes; ++i) {
float s = kSizes[i];
auto t = MakeText(
h,
Form(
"A_%02d_size_%.3f", i, s),
Form(
"%.3f %s", s, kRuler),
"LiberationSerif-Regular", 1, s,
}
}
{
for (int i = 0; i < kNFonts; ++i) {
auto t = MakeText(
h,
Form(
"B_%02d_%s", i, kFonts[i]),
Form(
"%s %s", kRuler, kFonts[i]), kFonts[i], 1, 0.018f,
}
}
{
AddBBoxAnchor(
h, kWorldLim);
float y = -kWorldLim + 10.0;
for (int i = 0; i < kNSizes; ++i) {
float s = 200.0 * kSizes[i];
auto t = MakeText(
h,
Form(
"C_%02d_size_%.1f", i, s),
Form(
"%.1f %s", s, kRuler),
"LiberationSerif-Regular", 0, s,
t->RefMainTrans().SetPos(-kWorldLim,
y, 0.0);
}
}
{
AddBBoxAnchor(
h, kWorldLim);
const int angles[] = {0, 20, 40, 60, 75};
for (int i = 0; i < 5; ++i) {
auto t = MakeText(
h,
Form(
"D_rotY_%02d", angles[i]),
Form(
"Y%02d %s", angles[i], kRuler),
"LiberationSerif-Regular", 0, 8.0f,
kGreen + 3);
auto &tr = t->RefMainTrans();
tr.SetPos(-kWorldLim, 20.0 * i + 10.0, 0.0);
tr.SetRotByAngles(0.0, angles[i] * d2r, 0.0);
}
for (int i = 0; i < 5; ++i) {
auto t = MakeText(
h,
Form(
"D_rotX_%02d", angles[i]),
Form(
"X%02d %s", angles[i], kRuler),
"LiberationSerif-Regular", 0, 8.0f,
kMagenta + 2);
auto &tr = t->RefMainTrans();
tr.SetPos(-kWorldLim, -20.0 * i - 10.0, 0.0);
tr.SetRotByAngles(angles[i] * d2r, 0.0, 0.0);
}
}
{
AddBBoxAnchor(
h, kWorldLim);
for (int i = 0; i < 5; ++i) {
double z = -kWorldLim + i * (2.0 * kWorldLim / 4.0);
auto t = MakeText(
h,
Form(
"E_%02d_z_%+.0f", i, z),
Form(
"z%+.0f %s", z, kRuler),
"LiberationSerif-Regular", 2,
t->RefMainTrans().SetPos(-kWorldLim, -kWorldLim + i * 45.0, z);
}
}
void tg_only(const char *panel = "")
{
std::string want(panel);
for (
auto &[
name, el] : gPanels) {
bool on = want.empty() ||
name == want;
}
}
void texts_grid(const char *panels = "ABCDE")
{
std::string want(panels);
auto eveMng = REveManager::Create();
eveMng->AllowMultipleRemoteConnections(false, false);
for (int i = 0; i < kNFonts; ++i)
REveText::AssertSdfFont(kFonts[i], rf + kFonts[i] + ".ttf");
auto *scScreen = eveMng->SpawnNewScene("Screen text", "Panels A, B -- screen mode");
auto *scWorld = eveMng->SpawnNewScene("World text", "Panels C, D -- world mode");
auto *scMixed = eveMng->SpawnNewScene("Mixed text", "Panel E -- mixed mode");
{"A", "A_screen_size_ladder", scScreen, PanelA},
{"B", "B_screen_fonts", scScreen, PanelB},
{"C", "C_world_size_ladder", scWorld, PanelC},
{"D", "D_world_rotation_fan", scWorld, PanelD},
{"E", "E_mixed_depth_ladder", scMixed, PanelE},
};
if (want.find(
d.key) == std::string::npos)
continue;
}
auto *
v0 = (
REveViewer *)eveMng->GetViewers()->FirstChild();
v0->SetName(
"Perspective");
v0->SetCameraType(REveViewer::kCameraPerspXOY);
auto *
v1 = eveMng->SpawnNewViewer(
"Orthographic",
"Same scenes, ortho camera");
v1->SetCameraType(REveViewer::kCameraOrthoXOY);
for (
auto *
v : {
v0,
v1}) {
v->SetAxesType(REveViewer::kAxesEdge);
}
eveMng->Show();
}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
short Color_t
Color number (short)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char mode
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
3D box with arbitrary vertices (cuboid).
Base class for REveUtil visualization elements, providing hierarchy management, rendering control and...
RAII guard for locking Eve manager (ctor) and processing changes (dtor).
Eve representation of TGLScene.
Eve representation of a GL view.
static const TString & GetDataDir()
Get the data directory in the installation. Static utility function.
Namespace for ROOT features in testing.