Commit bdf3b4c2 authored by David C. Lonie's avatar David C. Lonie
Browse files

Defer matplotlib initialization for text rendering.

Rather than querying for matplotlib when
vtkMatplotlibMathTextUtilities is constructed, check only when
the library is needed. This saves some start up time for e.g.
ParaView when mathtext is not used.

Some additional changes are required due to a change in behavior:
vtkMatplotlibMathTextUtilities::New() used to return NULL when
matplotlib was not found to signal that mathtext was unavailable.
The vtkMathTextUtilities::IsAvailable() virtual method has been
added to allow querying of the availability, now that New() can
return a valid object when matplotlib is unavailable.
parent b0691ec1
......@@ -962,7 +962,7 @@ void vtkOpenGLContextDevice2D::DrawMathTextString(float point[2],
const vtkStdString &string)
{
vtkMathTextUtilities *mathText = vtkMathTextUtilities::GetInstance();
if (!mathText)
if (!mathText || !mathText->IsAvailable())
{
vtkWarningMacro(<<"MathText is not available to parse string "
<< string.c_str() << ". Install matplotlib and enable "
......
......@@ -1352,7 +1352,7 @@ void vtkOpenGLContextDevice2D::DrawMathTextString(float point[2],
const vtkStdString &string)
{
vtkMathTextUtilities *mathText = vtkMathTextUtilities::GetInstance();
if (!mathText)
if (!mathText || !mathText->IsAvailable())
{
vtkWarningMacro(<<"MathText is not available to parse string "
<< string.c_str() << ". Install matplotlib and enable "
......
......@@ -50,8 +50,6 @@ void vtkTextRenderer::PrintSelf(ostream &os, vtkIndent indent)
this->Superclass::PrintSelf(os, indent);
os << indent << "Instance: " << vtkTextRenderer::Instance << endl;
os << indent << "HasFreeType: " << this->HasFreeType << endl;
os << indent << "HasMathText: " << this->HasMathText << endl;
os << indent << "MathTextRegExp: " << this->MathTextRegExp << endl;
os << indent << "MathTextRegExp2: " << this->MathTextRegExp2 << endl;
}
......@@ -114,8 +112,6 @@ void vtkTextRenderer::SetInstance(vtkTextRenderer *instance)
vtkTextRenderer::vtkTextRenderer()
: MathTextRegExp(new vtksys::RegularExpression("[^\\]\\$.+[^\\]\\$")),
MathTextRegExp2(new vtksys::RegularExpression("^\\$.+[^\\]\\$")),
HasFreeType(false),
HasMathText(false),
DefaultBackend(Detect)
{
}
......
......@@ -138,8 +138,8 @@ public:
// Description:
// Test for availability of various backends
bool FreeTypeIsSupported() { return HasFreeType; }
bool MathTextIsSupported() { return HasMathText; }
virtual bool FreeTypeIsSupported() { return false; }
virtual bool MathTextIsSupported() { return false; }
// Description:
// Given a text property and a string, get the bounding box {xmin, xmax,
......@@ -309,12 +309,6 @@ protected:
virtual void CleanUpFreeTypeEscapes(vtkStdString &str);
virtual void CleanUpFreeTypeEscapes(vtkUnicodeString &str);
// Description:
// Used to cache the availability of backends. Set these in the derived class
// constructor
bool HasFreeType;
bool HasMathText;
// Description:
// The backend to use when none is specified. Default: Detect
int DefaultBackend;
......
......@@ -51,6 +51,19 @@ void vtkMathTextFreeTypeTextRenderer::PrintSelf(ostream &os, vtkIndent indent)
}
}
//------------------------------------------------------------------------------
bool vtkMathTextFreeTypeTextRenderer::FreeTypeIsSupported()
{
return this->FreeTypeTools != NULL;
}
//------------------------------------------------------------------------------
bool vtkMathTextFreeTypeTextRenderer::MathTextIsSupported()
{
return this->MathTextUtilities != NULL &&
this->MathTextUtilities->IsAvailable();
}
//------------------------------------------------------------------------------
bool vtkMathTextFreeTypeTextRenderer::GetBoundingBoxInternal(
vtkTextProperty *tprop, const vtkStdString &str, int bbox[4], int dpi,
......@@ -81,7 +94,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetBoundingBoxInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
if (this->MathTextUtilities->GetBoundingBox(tprop, str.c_str(), dpi,
bbox))
......@@ -141,7 +154,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetBoundingBoxInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering.");
if (this->MathTextUtilities->GetBoundingBox(tprop, str.utf8_str(), dpi,
......@@ -200,7 +213,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetMetricsInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
if (this->MathTextUtilities->GetMetrics(tprop, str.c_str(), dpi,
metrics))
......@@ -260,7 +273,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetMetricsInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering.");
if (this->MathTextUtilities->GetMetrics(tprop, str.utf8_str(), dpi,
......@@ -313,7 +326,7 @@ bool vtkMathTextFreeTypeTextRenderer::RenderStringInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
if (this->MathTextUtilities->RenderString(str.c_str(), data, tprop,
dpi, textDims))
......@@ -368,7 +381,7 @@ bool vtkMathTextFreeTypeTextRenderer::RenderStringInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering.");
if (this->MathTextUtilities->RenderString(str.utf8_str(), data, tprop,
......@@ -422,7 +435,7 @@ int vtkMathTextFreeTypeTextRenderer::GetConstrainedFontSizeInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
if (this->MathTextUtilities->GetConstrainedFontSize(str.c_str(), tprop,
targetWidth,
......@@ -478,7 +491,7 @@ int vtkMathTextFreeTypeTextRenderer::GetConstrainedFontSizeInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering.");
if (this->MathTextUtilities->GetConstrainedFontSize(str.utf8_str(),
......@@ -535,7 +548,7 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
if (this->MathTextUtilities->StringToPath(str.c_str(), path, tprop,
dpi))
......@@ -587,7 +600,7 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal(
switch (static_cast<Backend>(backend))
{
case MathText:
if (this->HasMathText)
if (this->MathTextIsSupported())
{
vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering.");
if (this->MathTextUtilities->StringToPath(str.utf8_str(), path, tprop,
......@@ -634,9 +647,6 @@ vtkMathTextFreeTypeTextRenderer::vtkMathTextFreeTypeTextRenderer()
{
this->FreeTypeTools = vtkFreeTypeTools::GetInstance();
this->MathTextUtilities = vtkMathTextUtilities::GetInstance();
this->HasFreeType = (this->FreeTypeTools != NULL);
this->HasMathText = (this->MathTextUtilities != NULL);
}
//------------------------------------------------------------------------------
......
......@@ -43,6 +43,11 @@ public:
static vtkMathTextFreeTypeTextRenderer *New();
// Description:
// Test for availability of various backends
virtual bool FreeTypeIsSupported();
virtual bool MathTextIsSupported();
protected:
vtkMathTextFreeTypeTextRenderer();
~vtkMathTextFreeTypeTextRenderer();
......
......@@ -51,6 +51,10 @@ public:
vtkTypeMacro(vtkMathTextUtilities, vtkObject);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Returns true if mathtext rendering is available.
virtual bool IsAvailable() { return false; } // Override in subclasses.
// Description:
// This is a singleton pattern New. There will be only ONE reference
// to a vtkMathTextUtilities object per process. Clients that
......
......@@ -46,7 +46,7 @@ typedef Py_intptr_t Py_ssize_t;
#endif
//----------------------------------------------------------------------------
vtkMatplotlibMathTextUtilities::Availablity
vtkMatplotlibMathTextUtilities::Availability
vtkMatplotlibMathTextUtilities::MPLMathTextAvailable =
vtkMatplotlibMathTextUtilities::NOT_TESTED;
......@@ -55,13 +55,16 @@ vtkMatplotlibMathTextUtilities::NOT_TESTED;
// work in release mode builds.
#define vtkMplStartUpDebugMacro(x) if(debug){vtkGenericWarningMacro(x);}
vtkObjectFactoryNewMacro(vtkMatplotlibMathTextUtilities)
//----------------------------------------------------------------------------
void vtkMatplotlibMathTextUtilities::CheckMPLAvailability()
vtkMatplotlibMathTextUtilities::Availability
vtkMatplotlibMathTextUtilities::CheckMPLAvailability()
{
if (vtkMatplotlibMathTextUtilities::MPLMathTextAvailable != NOT_TESTED)
{
// Already tested. Nothing to do now.
return;
return vtkMatplotlibMathTextUtilities::MPLMathTextAvailable;
}
// Enable startup debugging output. This will be set to true when
......@@ -111,35 +114,14 @@ void vtkMatplotlibMathTextUtilities::CheckMPLAvailability()
vtkMplStartUpDebugMacro("Successfully imported matplotlib.");
vtkMatplotlibMathTextUtilities::MPLMathTextAvailable = AVAILABLE;
}
return vtkMatplotlibMathTextUtilities::MPLMathTextAvailable;
}
//----------------------------------------------------------------------------
vtkMatplotlibMathTextUtilities* vtkMatplotlibMathTextUtilities::New()
bool vtkMatplotlibMathTextUtilities::IsAvailable()
{
vtkMatplotlibMathTextUtilities::CheckMPLAvailability();
// Attempt to import matplotlib to check for availability
switch (vtkMatplotlibMathTextUtilities::MPLMathTextAvailable)
{
case vtkMatplotlibMathTextUtilities::AVAILABLE:
break;
case vtkMatplotlibMathTextUtilities::NOT_TESTED:
case vtkMatplotlibMathTextUtilities::UNAVAILABLE:
default:
return NULL;
}
// Adapted from VTK_OBJECT_FACTORY_NEW_BODY to enable debugging output when
// requested.
vtkObject* ret =
vtkObjectFactory::CreateInstance("vtkMatplotlibMathTextUtilities");
if (ret)
{
return static_cast<vtkMatplotlibMathTextUtilities*>(ret);
}
return new vtkMatplotlibMathTextUtilities;
return this->CheckMPLAvailability() == AVAILABLE;
}
//----------------------------------------------------------------------------
......@@ -313,6 +295,12 @@ bool vtkMatplotlibMathTextUtilities::CheckForError(PyObject *object)
PyObject *
vtkMatplotlibMathTextUtilities::GetFontProperties(vtkTextProperty *tprop)
{
if (!this->IsAvailable())
{
vtkErrorMacro(<<"Matplotlib rendering is unavailable.");
return NULL;
}
if (!this->FontPropertiesClass)
{
if (!this->InitializeFontPropertiesClass())
......@@ -536,6 +524,12 @@ bool vtkMatplotlibMathTextUtilities::GetMetrics(
vtkTextProperty *tprop, const char *str, int dpi,
vtkTextRenderer::Metrics &metrics)
{
if (!this->IsAvailable())
{
vtkErrorMacro(<<"Matplotlib rendering is unavailable.");
return false;
}
if (!this->MaskParser)
{
if (!this->InitializeMaskParser())
......@@ -620,6 +614,12 @@ bool vtkMatplotlibMathTextUtilities::RenderString(const char *str,
int dpi,
int textDims[2])
{
if (!this->IsAvailable())
{
vtkErrorMacro(<<"Matplotlib rendering is unavailable.");
return false;
}
if (!this->MaskParser)
{
if (!this->InitializeMaskParser())
......@@ -822,6 +822,12 @@ bool vtkMatplotlibMathTextUtilities::StringToPath(const char *str,
vtkTextProperty *tprop,
int dpi)
{
if (!this->IsAvailable())
{
vtkErrorMacro(<<"Matplotlib rendering is unavailable.");
return false;
}
if (!this->PathParser)
{
if (!this->InitializePathParser())
......@@ -1072,6 +1078,21 @@ void vtkMatplotlibMathTextUtilities::PrintSelf(ostream &os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
os << indent << "MPLMathTextAvailable: ";
switch (this->MPLMathTextAvailable)
{
case vtkMatplotlibMathTextUtilities::NOT_TESTED:
os << "Not tested\n";
break;
case vtkMatplotlibMathTextUtilities::AVAILABLE:
os << "Available\n";
break;
default:
case vtkMatplotlibMathTextUtilities::UNAVAILABLE:
os << "Unavailable\n";
break;
}
os << indent << "MaskParser: " << this->MaskParser << endl;
os << indent << "PathParser: " << this->PathParser << endl;
os << indent << "FontPropertiesClass: " << this->FontPropertiesClass << endl;
......
......@@ -44,6 +44,8 @@ public:
static vtkMatplotlibMathTextUtilities *New();
virtual bool IsAvailable();
// Description:
// Given a text property and a string, get the bounding box {xmin, xmax,
// ymin, ymax} of the rendered string in pixels. The origin of the bounding
......@@ -118,28 +120,33 @@ protected:
static void RotateCorners(double angleDeg, double corners[4][2],
double bbox[4]);
bool ScaleToPowerOfTwo;
bool PrepareImageData(vtkImageData *data, int bbox[4]);
private:
vtkMatplotlibMathTextUtilities(const vtkMatplotlibMathTextUtilities&); // Not implemented.
void operator=(const vtkMatplotlibMathTextUtilities&); // Not implemented.
// Description:
// Used for runtime checking of matplotlib's mathtext availability.
enum Availablity
// @sa IsAvailable
enum Availability
{
NOT_TESTED = 0,
AVAILABLE,
UNAVAILABLE
};
bool ScaleToPowerOfTwo;
bool PrepareImageData(vtkImageData *data, int bbox[4]);
// Description:
// Function used to check MPL availability and update MPLMathTextAvailable.
// This will do tests only the first time this method is called.
static void CheckMPLAvailability();
// This will do tests only the first time this method is called. This method
// is called internally when matplotlib rendering is first needed and is used
// to implement IsAvailable.
static Availability CheckMPLAvailability();
private:
vtkMatplotlibMathTextUtilities(const vtkMatplotlibMathTextUtilities&); // Not implemented.
void operator=(const vtkMatplotlibMathTextUtilities&); // Not implemented.
static Availablity MPLMathTextAvailable;
// Description:
// Cache the availability of matplotlib in the current python session.
static Availability MPLMathTextAvailable;
};
#endif
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