Cloned library of VTK-5.0.0 with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

377 lines
12 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkTextActor.cxx,v $
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 "vtkTextActor.h"
#include "vtkObjectFactory.h"
#include "vtkTextMapper.h"
#include "vtkTextProperty.h"
#include "vtkViewport.h"
#include "vtkWindow.h"
vtkCxxRevisionMacro(vtkTextActor, "$Revision: 1.22 $");
vtkStandardNewMacro(vtkTextActor);
vtkCxxSetObjectMacro(vtkTextActor,TextProperty,vtkTextProperty);
// ----------------------------------------------------------------------------
vtkTextActor::vtkTextActor()
{
// To remain compatible with code using vtkActor2D, we must set
// position coord to Viewport, not Normalized Viewport
// so...compute equivalent coords for initial position
this->PositionCoordinate->SetCoordinateSystemToViewport();
this->AdjustedPositionCoordinate = vtkCoordinate::New();
this->AdjustedPositionCoordinate->SetCoordinateSystemToNormalizedViewport();
// Create default text mapper
vtkTextMapper *mapper = vtkTextMapper::New();
this->SetMapper(mapper);
mapper->Delete();
this->TextProperty = vtkTextProperty::New();
this->LastOrigin[0] = 0;
this->LastOrigin[1] = 0;
this->LastSize[0] = 0;
this->LastSize[1] = 0;
this->MinimumSize[0] = 10;
this->MinimumSize[1] = 10;
this->MaximumLineHeight = 1.0;
this->ScaledText = 0;
this->AlignmentPoint = 0;
this->FontScaleExponent = 1;
this->FontScaleTarget = 10;
// IMPORTANT: backward compat: the buildtime is updated here so that the
// TextProperty->GetMTime() is lower than BuildTime. In that case, this
// will prevent the TextProperty to override the mapper's TextProperty
// when the actor is created after the mapper.
this->BuildTime.Modified();
}
// ----------------------------------------------------------------------------
vtkTextActor::~vtkTextActor()
{
this->AdjustedPositionCoordinate->Delete();
this->SetTextProperty(NULL);
}
// ----------------------------------------------------------------------------
void vtkTextActor::SetNonLinearFontScale(double exp, int tgt)
{
if (this->FontScaleExponent == exp && this->FontScaleTarget == tgt)
{
return;
}
this->FontScaleExponent = exp;
this->FontScaleTarget = tgt;
this->Modified();
}
// ----------------------------------------------------------------------------
void vtkTextActor::SetMapper(vtkTextMapper *mapper)
{
this->vtkActor2D::SetMapper( mapper );
}
// ----------------------------------------------------------------------------
void vtkTextActor::SetMapper(vtkMapper2D *mapper)
{
if (mapper->IsA("vtkTextMapper"))
{
this->SetMapper( (vtkTextMapper *)mapper );
}
else
{
vtkErrorMacro("Must use vtkTextMapper for this class");
}
}
// ----------------------------------------------------------------------------
void vtkTextActor::SetInput(const char* input)
{
vtkTextMapper *mapper = (vtkTextMapper *)this->GetMapper();
if (!mapper)
{
vtkErrorMacro("Actor has not vtkTextMapper");
}
mapper->SetInput(input);
}
// ----------------------------------------------------------------------------
char* vtkTextActor::GetInput()
{
vtkTextMapper *mapper = (vtkTextMapper *)this->GetMapper();
if (!mapper)
{
vtkErrorMacro("Actor has not vtkTextMapper");
}
return mapper->GetInput();
}
// ----------------------------------------------------------------------------
void vtkTextActor::ShallowCopy(vtkProp *prop)
{
vtkTextActor *a = vtkTextActor::SafeDownCast(prop);
if ( a != NULL )
{
this->SetPosition2(a->GetPosition2());
this->SetMinimumSize(a->GetMinimumSize());
this->SetMaximumLineHeight(a->GetMaximumLineHeight());
this->SetScaledText(a->GetScaledText());
this->SetAlignmentPoint(a->GetAlignmentPoint());
this->SetTextProperty(a->GetTextProperty());
}
// Now do superclass (mapper is handled by it as well).
this->vtkActor2D::ShallowCopy(prop);
}
// ----------------------------------------------------------------------------
// Release any graphics resources that are being consumed by this actor.
// The parameter window could be used to determine which graphic
// resources to release.
void vtkTextActor::ReleaseGraphicsResources(vtkWindow *win)
{
this->vtkActor2D::ReleaseGraphicsResources(win);
}
// ----------------------------------------------------------------------------
int vtkTextActor::RenderOverlay(vtkViewport *viewport)
{
// Everything is built in RenderOpaqueGeometry, just have to render
return this->vtkActor2D::RenderOverlay(viewport);
}
// ----------------------------------------------------------------------------
int vtkTextActor::RenderOpaqueGeometry(vtkViewport *viewport)
{
int size[2];
vtkTextMapper *mapper = (vtkTextMapper *)this->GetMapper();
if (!mapper)
{
vtkErrorMacro(<<"Need mapper to render text actor");
return 0;
}
vtkTextProperty *tprop = this->GetTextProperty();
vtkTextProperty *tpropmapper = mapper->GetTextProperty();
if (!tprop && !tpropmapper)
{
vtkErrorMacro(<<"Need text property to render text actor");
return 0;
}
if (tprop && tprop->GetMTime() > this->BuildTime)
{
// Shallow copy here so that the size of the text prop is not affected
// by the automatic adjustment of its text mapper's size (i.e. its
// mapper's text property is identical except for the font size
// which will be modified later). This allows text actors to
// share the same text property.
if (tpropmapper && tprop->GetMTime() > tpropmapper->GetMTime())
{
tpropmapper->ShallowCopy(tprop);
}
}
int *point1, *point2;
double u, v;
// we don't need to do anything additional, just pass the call
// right through to the actor
if (!this->ScaledText)
{
point1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
point2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
size[0] = point2[0] - point1[0];
size[1] = point2[1] - point1[1];
switch (this->AlignmentPoint)
{
case 0:
u = point1[0];
v = point1[1];
break;
case 1:
u = point1[0] + size[0]/2;
v = point1[1];
break;
case 2:
u = point2[0];
v = point1[1];
break;
case 3:
u = point1[0];
v = point1[1] + size[1]/2;
break;
case 4:
u = point1[0] + size[0]/2;
v = point1[1] + size[1]/2;
break;
case 5:
u = point2[0];
v = point1[1] + size[1]/2;
break;
case 6:
u = point1[0];
v = point2[1];
break;
case 7:
u = point1[0] + size[0]/2;
v = point2[1];
break;
case 8:
u = point2[0];
v = point2[1];
break;
}
viewport->ViewportToNormalizedViewport(u, v);
this->AdjustedPositionCoordinate->SetValue(u,v);
this->BuildTime.Modified();
}
else
{
point1 = this->PositionCoordinate->GetComputedViewportValue(viewport);
point2 = this->Position2Coordinate->GetComputedViewportValue(viewport);
size[0] = point2[0] - point1[0];
size[1] = point2[1] - point1[1];
// Check to see whether we have to rebuild everything
int positionsHaveChanged = 0;
if (viewport->GetMTime() > this->BuildTime ||
(viewport->GetVTKWindow() &&
viewport->GetVTKWindow()->GetMTime() > this->BuildTime))
{
// if the viewport has changed we may - or may not need
// to rebuild, it depends on if the projected coords change
if (this->LastSize[0] != size[0] || this->LastSize[1] != size[1] ||
this->LastOrigin[0] != point1[0] || this->LastOrigin[1] != point1[1])
{
positionsHaveChanged = 1;
}
}
// Check to see whether we have to rebuild everything
if (positionsHaveChanged ||
this->GetMTime() > this->BuildTime ||
mapper->GetMTime() > this->BuildTime ||
tpropmapper->GetMTime() > this->BuildTime)
{
vtkDebugMacro(<<"Rebuilding text");
this->LastOrigin[0] = point1[0];
this->LastOrigin[1] = point1[1];
// Lets try to minimize the number of times we change the font size.
// If the width of the font box has not changed by more than a pixel
// (numerical issues) do not recompute font size.
if (mapper->GetMTime() > this->BuildTime ||
tpropmapper->GetMTime() > this->BuildTime ||
this->LastSize[0] < size[0] - 1 || this->LastSize[1] < size[1] - 1 ||
this->LastSize[0] > size[0] + 1 || this->LastSize[1] > size[1] + 1)
{
this->LastSize[0] = size[0];
this->LastSize[1] = size[1];
// limit by minimum size
if (this->MinimumSize[0] > size[0])
{
size[0] = this->MinimumSize[0];
}
if (this->MinimumSize[1] > size[1])
{
size[1] = this->MinimumSize[1];
}
int max_height = (int)(this->MaximumLineHeight * (float)size[1]);
int fsize = mapper->SetConstrainedFontSize(
viewport,
size[0],
(size[1] < max_height ? size[1] : max_height));
// apply non-linear scaling
fsize = static_cast<int>(pow(static_cast<double>(fsize),this->FontScaleExponent)*
pow(this->FontScaleTarget, 1.0 - this->FontScaleExponent));
tpropmapper->SetFontSize(fsize);
}
// now set the position of the Text
int fpos[2];
switch (tpropmapper->GetJustification())
{
case VTK_TEXT_LEFT:
fpos[0] = point1[0];
break;
case VTK_TEXT_CENTERED:
fpos[0] = point1[0] + size[0]/2;
break;
case VTK_TEXT_RIGHT:
fpos[0] = point1[0]+size[0];
break;
}
switch (tpropmapper->GetVerticalJustification())
{
case VTK_TEXT_TOP:
fpos[1] = point1[1] + size[1];
break;
case VTK_TEXT_CENTERED:
fpos[1] = point1[1] + size[1]/2;
break;
case VTK_TEXT_BOTTOM:
fpos[1] = point1[1];
break;
}
u = fpos[0];
v = fpos[1];
viewport->ViewportToNormalizedViewport(u, v);
this->AdjustedPositionCoordinate->SetValue(u,v);
this->BuildTime.Modified();
}
}
// Everything is built, just have to render
return this->vtkActor2D::RenderOpaqueGeometry(viewport);
}
// ----------------------------------------------------------------------------
void vtkTextActor::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
if (this->TextProperty)
{
os << indent << "Text Property:\n";
this->TextProperty->PrintSelf(os,indent.GetNextIndent());
}
else
{
os << indent << "Text Property: (none)\n";
}
os << indent << "MaximumLineHeight: " << this->MaximumLineHeight << endl;
os << indent << "MinimumSize: " << this->MinimumSize[0] << " " << this->MinimumSize[1] << endl;
os << indent << "ScaledText: " << this->ScaledText << endl;
os << indent << "AlignmentPoint: " << this->AlignmentPoint << endl;
os << indent << "FontScaleExponent: " << this->FontScaleExponent << endl;
os << indent << "FontScaleTarget: " << this->FontScaleTarget << endl;
}