Updates will be applied - 3:30pm EDT (UTC -400). No downtime expected.

Commit 846f27a9 authored by Cory Quammen's avatar Cory Quammen Committed by Kitware Robot

Merge topic 'vtkContext2D_enhancements'

aeb47cf0 ENH: Computation of string bounds accounting for justification
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Ben Boeckel's avatarBen Boeckel <ben.boeckel@kitware.com>
Reviewed-by: default avatarDavid Lonie <david.lonie@kitware.com>
Merge-request: !812
parents 50d28c89 aeb47cf0
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestContext2D.cxx,NO_VALID
)
vtk_test_cxx_executable(${vtk-module}CxxTests tests)
/*=========================================================================
Program: Visualization Toolkit
Module: TestContext2D.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkContext2D.h"
#include "vtkContextActor.h"
#include "vtkContextDevice2D.h"
#include "vtkContextItem.h"
#include "vtkContextScene.h"
#include "vtkContextView.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLContextDevice2D.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkTextProperty.h"
//----------------------------------------------------------------------------
namespace {
class ContextItem : public vtkContextItem
{
public:
ContextItem() : Succeeded(true) {}
static ContextItem *New();
vtkTypeMacro(ContextItem, vtkContextItem);
virtual bool Paint(vtkContext2D* painter);
bool Succeeded;
};
//----------------------------------------------------------------------------
vtkStandardNewMacro(ContextItem);
//----------------------------------------------------------------------------
bool IsVector4Same(float expected[4], float computed[4])
{
double eps = 1e-6;
bool same = (fabs(expected[0] - computed[0]) < eps &&
fabs(expected[1] - computed[1]) < eps &&
fabs(expected[2] - computed[2]) < eps &&
fabs(expected[3] - computed[3]) < eps);
if (!same)
{
std::cout << "Not the same!\n";
std::cout << "Expected: (" << expected[0] << ", " << expected[1] << ", "
<< expected[2] << ", " << expected[3] << ")\n";
std::cout << "Computed: (" << computed[0] << ", " << computed[1] << ", "
<< computed[2] << ", " << computed[3] << ")\n";
}
return same;
}
//----------------------------------------------------------------------------
bool ContextItem::Paint(vtkContext2D* painter)
{
const char* text = "Test";
float expectedUnjustifiedBounds[4];
painter->ComputeStringBounds(text, expectedUnjustifiedBounds);
float expectedJustifiedBounds[4] = {0, 0, expectedUnjustifiedBounds[2], expectedUnjustifiedBounds[3]};
float unjustifiedBounds[4];
float justifiedBounds[4];
// Left justification
painter->GetTextProp()->SetJustification(VTK_TEXT_LEFT);
painter->ComputeStringBounds(text, unjustifiedBounds);
std::cout << "Left-justified ComputeStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedUnjustifiedBounds, unjustifiedBounds);
painter->ComputeJustifiedStringBounds(text, justifiedBounds);
std::cout << "Left-justified ComputeJustifiedStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedJustifiedBounds, justifiedBounds);
// Center justification
painter->GetTextProp()->SetJustification(VTK_TEXT_CENTERED);
painter->ComputeStringBounds(text, unjustifiedBounds);
std::cout << "Center-justified ComputeStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedUnjustifiedBounds, unjustifiedBounds);
expectedJustifiedBounds[0] = -0.5*expectedUnjustifiedBounds[2]; // negative half the width
painter->ComputeJustifiedStringBounds(text, justifiedBounds);
std::cout << "Center-justified ComputeJustifiedStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedJustifiedBounds, justifiedBounds);
// Right justification
painter->GetTextProp()->SetJustification(VTK_TEXT_RIGHT);
painter->ComputeStringBounds(text, unjustifiedBounds);
std::cout << "Right-justified ComputeStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedUnjustifiedBounds, unjustifiedBounds);
expectedJustifiedBounds[0] = -expectedUnjustifiedBounds[2]; // negative full width
painter->ComputeJustifiedStringBounds(text, justifiedBounds);
std::cout << "Right-justified result from ComputeJustifiedStringBounds\n";
this->Succeeded = this->Succeeded && IsVector4Same(expectedJustifiedBounds, justifiedBounds);
return true;
}
} // end anonymous namespace
//----------------------------------------------------------------------------
int TestContext2D(int, char*[])
{
// Set up a 2D context view, context test object and add it to the scene
vtkNew<vtkContextView> view;
view->GetRenderWindow()->SetSize(300, 300);
vtkNew<ContextItem> test;
view->GetScene()->AddItem(test.GetPointer());
// Force the use of the freetype based rendering strategy
vtkOpenGLContextDevice2D::SafeDownCast(view->GetContext()->GetDevice())
->SetStringRendererToFreeType();
view->GetRenderWindow()->SetMultiSamples(0);
view->GetInteractor()->Initialize();
view->Render();
return test->Succeeded ? EXIT_SUCCESS : EXIT_FAILURE;
}
......@@ -11,6 +11,8 @@ vtk_module(vtkRenderingContext2D
vtkRenderingFreeType
TEST_DEPENDS
vtkRenderingContext${VTK_RENDERING_BACKEND}
vtkTestingRendering
vtkViewsContext2D
KIT
vtkRendering
)
......@@ -680,6 +680,32 @@ void vtkContext2D::ComputeStringBounds(const char* string,
this->ComputeStringBounds(vtkStdString(string), bounds);
}
//-----------------------------------------------------------------------------
void vtkContext2D::ComputeJustifiedStringBounds(const char* string, float bounds[4])
{
this->ComputeStringBounds(string, bounds);
// Shift according to the text property justification
vtkTextProperty* textProp = this->Device->GetTextProp();
if (textProp->GetJustification() == VTK_TEXT_CENTERED)
{
bounds[0] -= 0.5f*bounds[2];
}
else if (textProp->GetJustification() == VTK_TEXT_RIGHT)
{
bounds[0] -= bounds[2];
}
if (textProp->GetVerticalJustification() == VTK_TEXT_CENTERED)
{
bounds[1] -= 0.5f*bounds[3];
}
else if (textProp->GetVerticalJustification() == VTK_TEXT_TOP)
{
bounds[1] -= bounds[3];
}
}
//-----------------------------------------------------------------------------
int vtkContext2D::ComputeFontSizeForBoundedString(const vtkStdString &string,
float width, float height)
......@@ -970,41 +996,47 @@ void vtkContext2D::SetContext3D(vtkContext3D *context)
//-----------------------------------------------------------------------------
vtkVector2f vtkContext2D::CalculateTextPosition(vtkPoints2D* rect)
{
// Draw the text at the appropriate point inside the rect for the alignment
// specified. This is a convenience when an area of the screen should have
// text drawn that is aligned to the entire area.
if (rect->GetNumberOfPoints() < 2)
{
return vtkVector2f();
}
vtkVector2f p(0, 0);
float *f = vtkFloatArray::SafeDownCast(rect->GetData())->GetPointer(0);
return this->CalculateTextPosition(f);
}
//-----------------------------------------------------------------------------
vtkVector2f vtkContext2D::CalculateTextPosition(float rect[4])
{
// Draw the text at the appropriate point inside the rect for the alignment
// specified. This is a convenience when an area of the screen should have
// text drawn that is aligned to the entire area.
vtkVector2f p(0, 0);
if (this->Device->GetTextProp()->GetJustification() == VTK_TEXT_LEFT)
{
p.SetX(f[0]);
p.SetX(rect[0]);
}
else if (this->Device->GetTextProp()->GetJustification() == VTK_TEXT_CENTERED)
{
p.SetX(f[0] + 0.5f*f[2]);
p.SetX(rect[0] + 0.5f*rect[2]);
}
else
{
p.SetX(f[0] + f[2]);
p.SetX(rect[0] + rect[2]);
}
if (this->Device->GetTextProp()->GetVerticalJustification() == VTK_TEXT_BOTTOM)
{
p.SetY(f[1]);
p.SetY(rect[1]);
}
else if (this->Device->GetTextProp()->GetVerticalJustification() == VTK_TEXT_CENTERED)
{
p.SetY(f[1] + 0.5f*f[3]);
p.SetY(rect[1] + 0.5f*rect[3]);
}
else
{
p.SetY(f[1] + f[3]);
p.SetY(rect[1] + rect[3]);
}
return p;
}
......
......@@ -309,6 +309,9 @@ public:
// supplied bounds variable, the first two elements are the bottom corner of
// the string, and the second two elements are the width and height of the
// bounding box.
//
// NOTE:the text justification from the current text property is
// NOT considered when computing these bounds.
void ComputeStringBounds(const vtkStdString &string, vtkPoints2D *bounds);
void ComputeStringBounds(const vtkStdString &string, float bounds[4]);
void ComputeStringBounds(const vtkUnicodeString &string, vtkPoints2D *bounds);
......@@ -316,6 +319,11 @@ public:
void ComputeStringBounds(const char* string, vtkPoints2D *bounds);
void ComputeStringBounds(const char* string, float bounds[4]);
// Description:
// Compute the bounds of the supplied string while considering the justification
// of the current text property.
void ComputeJustifiedStringBounds(const char* string, float bounds[4]);
// Description:
// Calculate the largest possible font size where the supplied string will fit
// within the specified bounds. In addition to being returned, this font size
......@@ -445,8 +453,18 @@ private:
// Description:
// Calculate position of text for rendering in a rectangle.
// The first point in rect is the bottom left corner of
// the text box, and the second point is the width and
// height of the rect.
vtkVector2f CalculateTextPosition(vtkPoints2D* rect);
// Description:
// Calculate position of text for rendering in a rectangle.
// The first two elements of rect represent the lower left
// corner of the text box, and the 3rd and 4th elements
// represent width and height.
vtkVector2f CalculateTextPosition(float rect[4]);
//ETX
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment