vtkMathTextUtilities.cxx 4.92 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMathTextUtilities.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 "vtkMathTextUtilities.h"

18
#include "vtkDebugLeaks.h" // Must be included before any singletons
19
#include "vtkMath.h"
20
#include "vtkObjectFactory.h"
21
#include "vtkTextActor.h"
22
#include "vtkTextProperty.h"
23 24
#include "vtkViewport.h"
#include "vtkWindow.h"
25

26 27
#include <algorithm>

28 29
//----------------------------------------------------------------------------
// The singleton, and the singleton cleanup
30
vtkMathTextUtilities* vtkMathTextUtilities::Instance = nullptr;
31 32 33 34 35 36
vtkMathTextUtilitiesCleanup vtkMathTextUtilities::Cleanup;

//----------------------------------------------------------------------------
// Create the singleton cleanup
// Register our singleton cleanup callback against the FTLibrary so that
// it might be called before the FTLibrary singleton is destroyed.
37
vtkMathTextUtilitiesCleanup::vtkMathTextUtilitiesCleanup() = default;
38 39 40 41 42

//----------------------------------------------------------------------------
// Delete the singleton cleanup
vtkMathTextUtilitiesCleanup::~vtkMathTextUtilitiesCleanup()
{
43
  vtkMathTextUtilities::SetInstance(nullptr);
44 45 46 47 48 49
}

//----------------------------------------------------------------------------
vtkMathTextUtilities* vtkMathTextUtilities::GetInstance()
{
  if (!vtkMathTextUtilities::Instance)
50
  {
51 52
    vtkMathTextUtilities::Instance =
      static_cast<vtkMathTextUtilities*>(vtkObjectFactory::CreateInstance("vtkMathTextUtilities"));
53
  }
54 55 56 57 58 59 60 61

  return vtkMathTextUtilities::Instance;
}

//----------------------------------------------------------------------------
void vtkMathTextUtilities::SetInstance(vtkMathTextUtilities* instance)
{
  if (vtkMathTextUtilities::Instance == instance)
62
  {
63
    return;
64
  }
65 66

  if (vtkMathTextUtilities::Instance)
67
  {
68
    vtkMathTextUtilities::Instance->Delete();
69
  }
70 71 72 73 74

  vtkMathTextUtilities::Instance = instance;

  // User will call ->Delete() after setting instance
  if (instance)
75
  {
76
    instance->Register(nullptr);
77
  }
78 79
}

80
//----------------------------------------------------------------------------
81 82
int vtkMathTextUtilities::GetConstrainedFontSize(
  const char* str, vtkTextProperty* tprop, int targetWidth, int targetHeight, int dpi)
83
{
84
  if (str == nullptr || str[0] == '\0' || targetWidth == 0 || targetHeight == 0 || tprop == nullptr)
85
  {
86
    return 0;
87
  }
88 89 90

  // Use the current font size as a first guess
  int bbox[4];
91
  double fontSize = tprop->GetFontSize();
92
  if (!this->GetBoundingBox(tprop, str, dpi, bbox))
93
  {
94
    return -1;
95
  }
96
  int width = bbox[1] - bbox[0];
97 98 99 100 101
  int height = bbox[3] - bbox[2];

  // Bad assumption but better than nothing -- assume the bbox grows linearly
  // with the font size:
  if (width != 0 && height != 0)
102
  {
103 104
    fontSize *= std::min(static_cast<double>(targetWidth) / static_cast<double>(width),
      static_cast<double>(targetHeight) / static_cast<double>(height));
105
    tprop->SetFontSize(static_cast<int>(fontSize));
106
    if (!this->GetBoundingBox(tprop, str, dpi, bbox))
107
    {
108
      return -1;
109
    }
110
    width = bbox[1] - bbox[0];
111
    height = bbox[3] - bbox[2];
112
  }
113 114 115

  // Now just step up/down until the bbox matches the target.
  while ((width < targetWidth || height < targetHeight) && fontSize < 200)
116
  {
117 118
    fontSize += 1.;
    tprop->SetFontSize(fontSize);
119
    if (!this->GetBoundingBox(tprop, str, dpi, bbox))
120
    {
121
      return -1;
122
    }
123
    width = bbox[1] - bbox[0];
124
    height = bbox[3] - bbox[2];
125
  }
126 127

  while ((width > targetWidth || height > targetHeight) && fontSize > 0)
128
  {
129 130
    fontSize -= 1.;
    tprop->SetFontSize(fontSize);
131
    if (!this->GetBoundingBox(tprop, str, dpi, bbox))
132
    {
133
      return -1;
134
    }
135
    width = bbox[1] - bbox[0];
136
    height = bbox[3] - bbox[2];
137
  }
138 139 140 141

  return fontSize;
}

142 143 144 145
//----------------------------------------------------------------------------
vtkMathTextUtilities* vtkMathTextUtilities::New()
{
  vtkMathTextUtilities* ret = vtkMathTextUtilities::GetInstance();
146
  if (ret)
147
  {
148
    ret->Register(nullptr);
149
  }
150 151 152 153
  return ret;
}

//----------------------------------------------------------------------------
154
vtkMathTextUtilities::vtkMathTextUtilities() = default;
155

156
//----------------------------------------------------------------------------
157
vtkMathTextUtilities::~vtkMathTextUtilities() = default;
158

159
//----------------------------------------------------------------------------
160
void vtkMathTextUtilities::PrintSelf(ostream& os, vtkIndent indent)
161 162 163
{
  this->Superclass::PrintSelf(os, indent);

164
  os << indent << "Instance: " << this->Instance << endl;
165
}