vtkTextMapper.cxx 17.4 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1
2
3
4
5
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTextMapper.cxx

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7
8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Will Schroeder's avatar
Will Schroeder committed
9

10
11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
Ken Martin's avatar
Ken Martin committed
13
14

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkTextMapper.h"
16

17
18
19
20
#include "vtkActor2D.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkImageData.h"
Ken Martin's avatar
Ken Martin committed
21
#include "vtkInformation.h"
22
#include "vtkObjectFactory.h"
23
24
25
26
27
28
29
30
31
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkRenderer.h"
#include "vtkStdString.h"
#include "vtkTextProperty.h"
#include "vtkTextRenderer.h"
#include "vtkTexture.h"
32
#include "vtkWindow.h"
33

34
35
#include <algorithm>

36
//----------------------------------------------------------------------------
37
vtkObjectFactoryNewMacro(vtkTextMapper)
38
//----------------------------------------------------------------------------
Sebastien Barre's avatar
Sebastien Barre committed
39
vtkCxxSetObjectMacro(vtkTextMapper,TextProperty,vtkTextProperty);
40

Sebastien Barre's avatar
Sebastien Barre committed
41
42
//----------------------------------------------------------------------------
// Creates a new text mapper
Ken Martin's avatar
Ken Martin committed
43
44
vtkTextMapper::vtkTextMapper()
{
45
  this->Input = NULL;
Charles Law's avatar
Charles Law committed
46
  this->TextProperty = NULL;
Will Schroeder's avatar
Will Schroeder committed
47

48
49
  this->RenderedDPI = 0;

50
51
52
  vtkNew<vtkTextProperty> tprop;
  this->SetTextProperty(tprop.GetPointer());

53
54
55
56
57
58
59
  this->Points->SetNumberOfPoints(4);
  this->Points->SetPoint(0, 0., 0., 0.);
  this->Points->SetPoint(1, 0., 0., 0.);
  this->Points->SetPoint(2, 0., 0., 0.);
  this->Points->SetPoint(3, 0., 0., 0.);
  this->PolyData->SetPoints(this->Points.GetPointer());

60
61
62
63
64
65
66
67
68
69
70
  vtkNew<vtkCellArray> quad;
  quad->InsertNextCell(4);
  quad->InsertCellPoint(0);
  quad->InsertCellPoint(1);
  quad->InsertCellPoint(2);
  quad->InsertCellPoint(3);
  this->PolyData->SetPolys(quad.GetPointer());

  vtkNew<vtkFloatArray> tcoords;
  tcoords->SetNumberOfComponents(2);
  tcoords->SetNumberOfTuples(4);
71
72
73
74
  tcoords->SetTuple2(0, 0., 0.);
  tcoords->SetTuple2(1, 0., 0.);
  tcoords->SetTuple2(2, 0., 0.);
  tcoords->SetTuple2(3, 0., 0.);
75
76
77
78
79
  this->PolyData->GetPointData()->SetTCoords(tcoords.GetPointer());
  this->Mapper->SetInputData(this->PolyData.GetPointer());

  this->Texture->SetInputData(this->Image.GetPointer());
  this->TextDims[0] = this->TextDims[1] = 0;
Ken Martin's avatar
Ken Martin committed
80
81
}

Sebastien Barre's avatar
Sebastien Barre committed
82
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
83
84
85
86
// Shallow copy of an actor.
void vtkTextMapper::ShallowCopy(vtkTextMapper *tm)
{
  this->SetInput(tm->GetInput());
Sebastien Barre's avatar
Sebastien Barre committed
87
88
  this->SetTextProperty(tm->GetTextProperty());

89
  this->SetClippingPlanes(tm->GetClippingPlanes());
Ken Martin's avatar
Ken Martin committed
90
91
}

Sebastien Barre's avatar
Sebastien Barre committed
92
//----------------------------------------------------------------------------
93
94
vtkTextMapper::~vtkTextMapper()
{
95
  delete [] this->Input;
Sebastien Barre's avatar
Sebastien Barre committed
96
  this->SetTextProperty(NULL);
Will Schroeder's avatar
Will Schroeder committed
97
}
Ken Martin's avatar
Ken Martin committed
98

Ken Martin's avatar
Ken Martin committed
99
//----------------------------------------------------------------------------
100
void vtkTextMapper::PrintSelf(ostream& os, vtkIndent indent)
Ken Martin's avatar
Ken Martin committed
101
{
Brad King's avatar
Brad King committed
102
  this->Superclass::PrintSelf(os,indent);
Ken Martin's avatar
Ken Martin committed
103

Sebastien Barre's avatar
Sebastien Barre committed
104
  if (this->TextProperty)
Ken Martin's avatar
Ken Martin committed
105
    {
Sebastien Barre's avatar
Sebastien Barre committed
106
107
    os << indent << "Text Property:\n";
    this->TextProperty->PrintSelf(os,indent.GetNextIndent());
Ken Martin's avatar
Ken Martin committed
108
    }
Sebastien Barre's avatar
Sebastien Barre committed
109
  else
Ken Martin's avatar
Ken Martin committed
110
    {
Sebastien Barre's avatar
Sebastien Barre committed
111
    os << indent << "Text Property: (none)\n";
Ken Martin's avatar
Ken Martin committed
112
    }
113

Sebastien Barre's avatar
Sebastien Barre committed
114
  os << indent << "Input: " << (this->Input ? this->Input : "(none)") << "\n";
115
116

  os << indent << "TextDims: "
David C. Lonie's avatar
David C. Lonie committed
117
     << this->TextDims[0] << ", " << this->TextDims[1] << "\n";
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

  os << indent << "CoordsTime: " << this->CoordsTime.GetMTime() << "\n";
  os << indent << "TCoordsTime: " << this->TCoordsTime.GetMTime() << "\n";
  os << indent << "Image:\n";
  this->Image->PrintSelf(os, indent.GetNextIndent());
  os << indent << "Points:\n";
  this->Points->PrintSelf(os, indent.GetNextIndent());
  os << indent << "PolyData:\n";
  this->PolyData->PrintSelf(os, indent.GetNextIndent());
  os << indent << "Mapper:\n";
  this->Mapper->PrintSelf(os, indent.GetNextIndent());
  os << indent << "Texture:\n";
  this->Texture->PrintSelf(os, indent.GetNextIndent());
}

//----------------------------------------------------------------------------
134
void vtkTextMapper::GetSize(vtkViewport *vp, int size[2])
135
{
136
137
138
139
140
141
142
143
144
  vtkWindow *win = vp ? vp->GetVTKWindow() : NULL;
  if (!win)
    {
    size[0] = size[1] = 0;
    vtkErrorMacro(<<"No render window available: cannot determine DPI.");
    return;
    }

  this->UpdateImage(win->GetDPI());
145
146
  size[0] = this->TextDims[0];
  size[1] = this->TextDims[1];
Ken Martin's avatar
Ken Martin committed
147
}
Ken Martin's avatar
Ken Martin committed
148

Sebastien Barre's avatar
Sebastien Barre committed
149
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
150
151
152
153
154
155
156
int vtkTextMapper::GetWidth(vtkViewport* viewport)
{
  int size[2];
  this->GetSize(viewport, size);
  return size[0];
}

Sebastien Barre's avatar
Sebastien Barre committed
157
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
158
159
160
161
162
163
164
int vtkTextMapper::GetHeight(vtkViewport* viewport)
{
  int size[2];
  this->GetSize(viewport, size);
  return size[1];
}

Sebastien Barre's avatar
Sebastien Barre committed
165
166
167
168
//----------------------------------------------------------------------------
int vtkTextMapper::SetConstrainedFontSize(vtkViewport *viewport,
                                          int targetWidth,
                                          int targetHeight)
169
{
170
171
172
  return this->SetConstrainedFontSize(this, viewport, targetWidth, targetHeight);
}

173

174
//----------------------------------------------------------------------------
175
176
int vtkTextMapper::SetConstrainedFontSize(vtkTextMapper *tmapper,
                                          vtkViewport *viewport,
177
178
179
                                          int targetWidth, int targetHeight)
{
  // If target "empty" just return
180
181
182
183
  if (targetWidth == 0 && targetHeight == 0)
    {
    return 0;
    }
184

185
  vtkTextProperty *tprop = tmapper->GetTextProperty();
Sebastien Barre's avatar
Sebastien Barre committed
186
187
  if (!tprop)
    {
188
    vtkGenericWarningMacro(<<"Need text property to apply constraint");
Sebastien Barre's avatar
Sebastien Barre committed
189
190
    return 0;
    }
Sebastien Barre's avatar
Sebastien Barre committed
191
  int fontSize = tprop->GetFontSize();
192
193
194

  // Use the last size as a first guess
  int tempi[2];
195
  tmapper->GetSize(viewport, tempi);
196

Sebastien Barre's avatar
Sebastien Barre committed
197
198
199
200
201
202
203
  // Now get an estimate of the target font size using bissection
  // Based on experimentation with big and small font size increments,
  // ceil() gives the best result.
  // big:   floor: 10749, ceil: 10106, cast: 10749, vtkMath::Round: 10311
  // small: floor: 12122, ceil: 11770, cast: 12122, vtkMath::Round: 11768
  // I guess the best optim would be to have a look at the shape of the
  // font size growth curve (probably not that linear)
204
205
  if (tempi[0] && tempi[1])
    {
206
207
208
    float fx = targetWidth / static_cast<float>(tempi[0]);
    float fy = targetHeight / static_cast<float>(tempi[1]);
    fontSize = static_cast<int>(ceil(fontSize * ((fx <= fy) ? fx : fy)));
209
    tprop->SetFontSize(fontSize);
210
    tmapper->GetSize(viewport, tempi);
211
    }
Sebastien Barre's avatar
Sebastien Barre committed
212

213
  // While the size is too small increase it
Ken Martin's avatar
Ken Martin committed
214
  while (tempi[1] <= targetHeight &&
215
         tempi[0] <= targetWidth &&
Sebastien Barre's avatar
Sebastien Barre committed
216
         fontSize < 100)
217
    {
Sebastien Barre's avatar
Sebastien Barre committed
218
219
    fontSize++;
    tprop->SetFontSize(fontSize);
220
    tmapper->GetSize(viewport, tempi);
221
222
223
    }

  // While the size is too large decrease it
224
  while ((tempi[1] > targetHeight || tempi[0] > targetWidth)
Sebastien Barre's avatar
Sebastien Barre committed
225
         && fontSize > 0)
226
    {
Sebastien Barre's avatar
Sebastien Barre committed
227
228
    fontSize--;
    tprop->SetFontSize(fontSize);
229
    tmapper->GetSize(viewport, tempi);
230
231
    }

Sebastien Barre's avatar
Sebastien Barre committed
232
233
234
235
  return fontSize;
}

//----------------------------------------------------------------------------
236
237
238
239
240
int vtkTextMapper::SetMultipleConstrainedFontSize(vtkViewport *viewport,
                                                  int targetWidth,
                                                  int targetHeight,
                                                  vtkTextMapper **mappers,
                                                  int nbOfMappers,
Sebastien Barre's avatar
Sebastien Barre committed
241
242
243
244
245
246
247
248
249
                                                  int *maxResultingSize)
{
  maxResultingSize[0] = maxResultingSize[1] = 0;

  if (nbOfMappers == 0)
    {
    return 0;
    }

Sebastien Barre's avatar
Sebastien Barre committed
250
  int fontSize, aSize;
Sebastien Barre's avatar
Sebastien Barre committed
251
252

  // First try to find the constrained font size of the first mapper: it
253
  // will be used minimize the search for the remaining mappers, given the
Sebastien Barre's avatar
Sebastien Barre committed
254
  // fact that all mappers are likely to have the same constrained font size.
Sebastien Barre's avatar
Sebastien Barre committed
255
256
  int i, first;
  for (first = 0; first < nbOfMappers && !mappers[first]; first++) {}
Sebastien Barre's avatar
Sebastien Barre committed
257
258
259
260
261

  if (first >= nbOfMappers)
    {
    return 0;
    }
262

Sebastien Barre's avatar
Sebastien Barre committed
263
  fontSize = mappers[first]->SetConstrainedFontSize(
Sebastien Barre's avatar
Sebastien Barre committed
264
265
    viewport, targetWidth, targetHeight);

266
  // Find the constrained font size for the remaining mappers and
Sebastien Barre's avatar
Sebastien Barre committed
267
  // pick the smallest
Sebastien Barre's avatar
Sebastien Barre committed
268
  for (i = first + 1; i < nbOfMappers; i++)
Sebastien Barre's avatar
Sebastien Barre committed
269
    {
Sebastien Barre's avatar
Sebastien Barre committed
270
    if (mappers[i])
Sebastien Barre's avatar
Sebastien Barre committed
271
      {
Sebastien Barre's avatar
Sebastien Barre committed
272
273
274
275
276
277
278
      mappers[i]->GetTextProperty()->SetFontSize(fontSize);
      aSize = mappers[i]->SetConstrainedFontSize(
        viewport, targetWidth, targetHeight);
      if (aSize < fontSize)
        {
        fontSize = aSize;
        }
Sebastien Barre's avatar
Sebastien Barre committed
279
280
281
282
      }
    }

  // Assign the smallest size to all text mappers and find the largest area
283
  int tempi[2];
Sebastien Barre's avatar
Sebastien Barre committed
284
  for (i = first; i < nbOfMappers; i++)
Sebastien Barre's avatar
Sebastien Barre committed
285
    {
Sebastien Barre's avatar
Sebastien Barre committed
286
    if (mappers[i])
Sebastien Barre's avatar
Sebastien Barre committed
287
      {
Sebastien Barre's avatar
Sebastien Barre committed
288
289
290
291
292
293
294
295
296
297
      mappers[i]->GetTextProperty()->SetFontSize(fontSize);
      mappers[i]->GetSize(viewport, tempi);
      if (tempi[0] > maxResultingSize[0])
        {
        maxResultingSize[0] = tempi[0];
        }
      if (tempi[1] > maxResultingSize[1])
        {
        maxResultingSize[1] = tempi[1];
        }
Sebastien Barre's avatar
Sebastien Barre committed
298
299
300
301
302
303
304
305
306
      }
    }

  // The above code could be optimized further since the mappers
  // labels are likely to have the same height: in that case, we could
  // have searched for the largest label, find the constrained size
  // for this one, then applied this size to all others.  But who
  // knows, maybe one day the text property will support a text
  // orientation/rotation, and in that case the height will vary.
307
308
309
310
311
312
  return fontSize;
}


//----------------------------------------------------------------------------
int vtkTextMapper::SetRelativeFontSize(vtkTextMapper *tmapper,
313
                                       vtkViewport *viewport,  int *targetSize,
314
315
                                       int *stringSize, float sizeFactor)
{
316
  sizeFactor = (sizeFactor <= 0.0f ? 0.015f : sizeFactor);
317
318
319
320

  int fontSize, targetWidth, targetHeight;
  // Find the best size for the font
  targetWidth = targetSize[0] > targetSize[1] ? targetSize[0] : targetSize[1];
321
322
  targetHeight = static_cast<int>(sizeFactor * targetSize[0]
                                  + sizeFactor * targetSize[1]);
323
324
325
326
327
328
329
330

  fontSize = tmapper->SetConstrainedFontSize(tmapper, viewport, targetWidth, targetHeight);
  tmapper->GetSize(viewport, stringSize);

  return fontSize;
}

//----------------------------------------------------------------------------
331
332
333
int vtkTextMapper::SetMultipleRelativeFontSize(vtkViewport *viewport,
                                               vtkTextMapper **textMappers,
                                               int nbOfMappers, int *targetSize,
334
335
336
337
338
339
340
341
342
343
                                               int *stringSize, float sizeFactor)
{
  int fontSize, targetWidth, targetHeight;

  // Find the best size for the font
  // WARNING: check that the below values are in sync with the above
  // similar function.

  targetWidth = targetSize [0] > targetSize[1] ? targetSize[0] : targetSize[1];

344
345
  targetHeight = static_cast<int>(sizeFactor * targetSize[0]
                                  + sizeFactor * targetSize[1]);
346

347
348
  fontSize =
    vtkTextMapper::SetMultipleConstrainedFontSize(viewport,
349
350
351
352
                                                  targetWidth, targetHeight,
                                                  textMappers,
                                                  nbOfMappers,
                                                  stringSize);
Sebastien Barre's avatar
Sebastien Barre committed
353
354

  return fontSize;
355
356
}

Sebastien Barre's avatar
Sebastien Barre committed
357
//----------------------------------------------------------------------------
358
void vtkTextMapper::RenderOverlay(vtkViewport *viewport, vtkActor2D *actor)
Will Schroeder's avatar
Will Schroeder committed
359
{
360
361
362
363
364
365
366
  // This is neccessary for GL2PS exports when this actor/mapper are part of an
  // composite actor/mapper.
  if (!actor->GetVisibility())
    {
    return;
    }

367
  vtkDebugMacro(<<"RenderOverlay called");
Ken Martin's avatar
Ken Martin committed
368
369

  vtkRenderer *ren = NULL;
370
  if (this->Input && this->Input[0])
Will Schroeder's avatar
Will Schroeder committed
371
    {
372
373
374
375
376
377
378
379
380
381
    vtkWindow *win = viewport->GetVTKWindow();
    if (!win)
      {
      vtkErrorMacro(<<"No render window available: cannot determine DPI.");
      return;
      }

    this->UpdateImage(win->GetDPI());
    this->UpdateQuad(actor, win->GetDPI());

Ken Martin's avatar
Ken Martin committed
382
383
    ren = vtkRenderer::SafeDownCast(viewport);
    if (ren)
384
385
386
      {
      vtkDebugMacro(<<"Texture::Render called");
      this->Texture->Render(ren);
Ken Martin's avatar
Ken Martin committed
387
388
389
390
391
392
393
394
395
      vtkInformation *info = actor->GetPropertyKeys();
      if (!info)
        {
        info = vtkInformation::New();
        actor->SetPropertyKeys(info);
        info->Delete();
        }
      info->Set(vtkProp::GeneralTextureUnit(),
        this->Texture->GetTextureUnit());
396
      }
Will Schroeder's avatar
Will Schroeder committed
397

398
399
    vtkDebugMacro(<<"PolyData::RenderOverlay called");
    this->Mapper->RenderOverlay(viewport, actor);
Will Schroeder's avatar
Will Schroeder committed
400

401
402
403
404
405
    // clean up
    if (ren)
      {
      this->Texture->PostRender(ren);
      }
Ken Martin's avatar
Ken Martin committed
406
407
    }

408
409
410
  vtkDebugMacro(<<"Superclass::RenderOverlay called");
  this->Superclass::RenderOverlay(viewport, actor);
}
411

412
413
414
415
//----------------------------------------------------------------------------
void vtkTextMapper::ReleaseGraphicsResources(vtkWindow *win)
{
  this->Superclass::ReleaseGraphicsResources(win);
416
  this->Mapper->ReleaseGraphicsResources(win);
417
418
  this->Texture->ReleaseGraphicsResources(win);
}
419

420
//----------------------------------------------------------------------------
Bill Lorensen's avatar
Bill Lorensen committed
421
vtkMTimeType vtkTextMapper::GetMTime()
422
{
Bill Lorensen's avatar
Bill Lorensen committed
423
  vtkMTimeType result = this->Superclass::GetMTime();
424
425
426
427
428
429
430
  result = std::max(result, this->CoordsTime.GetMTime());
  result = std::max(result, this->Image->GetMTime());
  result = std::max(result, this->Points->GetMTime());
  result = std::max(result, this->PolyData->GetMTime());
  result = std::max(result, this->Mapper->GetMTime());
  result = std::max(result, this->Texture->GetMTime());
  return result;
Will Schroeder's avatar
Will Schroeder committed
431
}
Ken Martin's avatar
Ken Martin committed
432

Sebastien Barre's avatar
Sebastien Barre committed
433
//----------------------------------------------------------------------------
434
void vtkTextMapper::UpdateQuad(vtkActor2D *actor, int dpi)
Will Schroeder's avatar
Will Schroeder committed
435
{
436
  vtkDebugMacro(<<"UpdateQuad called");
Sebastien Barre's avatar
Sebastien Barre committed
437

438
439
  // Update texture coordinates:
  if (this->Image->GetMTime() > this->TCoordsTime)
Will Schroeder's avatar
Will Schroeder committed
440
    {
441
442
443
    int dims[3];
    this->Image->GetDimensions(dims);

444
445
446
    // The coordinates are calculated to be centered on a texel and
    // trim the padding from the image. (padding is often added to
    // create textures that have power-of-two dimensions)
447
448
449
450
    float tw = static_cast<float>(this->TextDims[0]);
    float th = static_cast<float>(this->TextDims[1]);
    float iw = static_cast<float>(dims[0]);
    float ih = static_cast<float>(dims[1]);
451
452
453
454
    float tcXMin = 0;
    float tcYMin = 0;
    float tcXMax = static_cast<float>(tw) / iw;
    float tcYMax = static_cast<float>(th) / ih;
455
    if (vtkFloatArray *tc =
456
        vtkArrayDownCast<vtkFloatArray>(
457
458
459
460
461
462
463
464
          this->PolyData->GetPointData()->GetTCoords()))
      {
      vtkDebugMacro(<<"Setting tcoords: xmin, xmax, ymin, ymax: "
                    << tcXMin << ", " << tcXMax << ", "
                    << tcYMin << ", " << tcYMax);
      tc->Reset();
      tc->InsertNextValue(tcXMin);
      tc->InsertNextValue(tcYMin);
465

466
467
      tc->InsertNextValue(tcXMin);
      tc->InsertNextValue(tcYMax);
Ken Martin's avatar
Ken Martin committed
468

469
470
      tc->InsertNextValue(tcXMax);
      tc->InsertNextValue(tcYMax);
Sebastien Barre's avatar
Sebastien Barre committed
471

472
473
474
475
476
477
478
479
480
      tc->InsertNextValue(tcXMax);
      tc->InsertNextValue(tcYMin);

      this->TCoordsTime.Modified();
      }
    else
      {
      vtkErrorMacro(<<"Invalid texture coordinate array type.");
      }
Sebastien Barre's avatar
Sebastien Barre committed
481
    }
482

483
  if (this->CoordsTime < actor->GetMTime() ||
484
485
      this->CoordsTime < this->TextProperty->GetMTime() ||
      this->CoordsTime < this->TCoordsTime)
Will Schroeder's avatar
Will Schroeder committed
486
    {
487
488
489
490
491
492
    int text_bbox[4];
    vtkTextRenderer *tren = vtkTextRenderer::GetInstance();
    if (tren)
      {
      if (!tren->GetBoundingBox(this->TextProperty,
                                this->Input ? this->Input : std::string(),
493
                                text_bbox, dpi))
494
495
496
497
498
499
500
        {
        vtkErrorMacro(<<"Error calculating bounding box.");
        }
      }
    else
      {
      vtkErrorMacro(<<"Could not locate vtkTextRenderer object.");
Ken Martin's avatar
Ken Martin committed
501
502
      text_bbox[0] = 0;
      text_bbox[2] = 0;
503
      }
504
505
506
    // adjust the quad so that the anchor point and a point with the same
    // coordinates fall on the same pixel.
    double shiftPixel = 1;
507
508
    double x = static_cast<double>(text_bbox[0]);
    double y = static_cast<double>(text_bbox[2]);
509
510
511
512
    double w = static_cast<double>(this->TextDims[0]);
    double h = static_cast<double>(this->TextDims[1]);

    this->Points->Reset();
513
514
515
516
    this->Points->InsertNextPoint(x - shiftPixel, y - shiftPixel, 0.);
    this->Points->InsertNextPoint(x - shiftPixel, y + h - shiftPixel, 0.);
    this->Points->InsertNextPoint(x + w - shiftPixel, y + h - shiftPixel, 0.);
    this->Points->InsertNextPoint(x + w - shiftPixel, y - shiftPixel, 0.);
517
    this->CoordsTime.Modified();
Will Schroeder's avatar
Will Schroeder committed
518
    }
519
}
Will Schroeder's avatar
Will Schroeder committed
520

521
//----------------------------------------------------------------------------
522
void vtkTextMapper::UpdateImage(int dpi)
523
524
525
{
  vtkDebugMacro(<<"UpdateImage called");
  if (this->MTime > this->Image->GetMTime() ||
526
      this->RenderedDPI != dpi ||
527
      this->TextProperty->GetMTime() > this->Image->GetMTime())
Will Schroeder's avatar
Will Schroeder committed
528
    {
529
530
531
    vtkTextRenderer *tren = vtkTextRenderer::GetInstance();
    if (tren)
      {
532
533
      if (!tren->RenderString(this->TextProperty,
                              this->Input ? this->Input : std::string(),
534
                              this->Image.GetPointer(), this->TextDims, dpi))
535
536
537
        {
        vtkErrorMacro(<<"Texture generation failed.");
        }
538
      this->RenderedDPI = dpi;
539
540
541
542
543
544
545
      vtkDebugMacro(<< "Text rendered to " << this->TextDims[0] << ", "
                    << this->TextDims[1] << " buffer.");
      }
    else
      {
      vtkErrorMacro(<<"Could not locate vtkTextRenderer object.");
      }
Will Schroeder's avatar
Will Schroeder committed
546
547
    }
}