diff --git a/Common/Core/vtkWindow.cxx b/Common/Core/vtkWindow.cxx index 724267b2d33..4cad518682b 100644 --- a/Common/Core/vtkWindow.cxx +++ b/Common/Core/vtkWindow.cxx @@ -32,7 +32,7 @@ vtkWindow::vtkWindow() strcpy( this->WindowName, windowname ); this->Erase = 1; this->DoubleBuffer = 0; - this->DPI = 120; + this->DPI = 72; this->TileViewport[0] = 0; this->TileViewport[1] = 0; this->TileViewport[2] = 1.0; diff --git a/Common/Core/vtkWindow.h b/Common/Core/vtkWindow.h index d82a145811a..5cbba4a9f7c 100644 --- a/Common/Core/vtkWindow.h +++ b/Common/Core/vtkWindow.h @@ -120,7 +120,7 @@ class VTKCOMMONCORE_EXPORT vtkWindow : public vtkObject // Return a best estimate to the dots per inch of the display // device being rendered (or printed). vtkGetMacro(DPI,int); - vtkSetClampMacro(DPI,int,1,3000); + vtkSetClampMacro(DPI,int,1,VTK_INT_MAX); // Description: // Attempt to detect and set the DPI of the display device by querying the diff --git a/IO/Export/vtkGL2PSExporter.cxx b/IO/Export/vtkGL2PSExporter.cxx index 43bd82c714b..5a4d467a3c4 100644 --- a/IO/Export/vtkGL2PSExporter.cxx +++ b/IO/Export/vtkGL2PSExporter.cxx @@ -734,14 +734,19 @@ void vtkGL2PSExporter::DrawTextActor3D(vtkTextActor3D *textAct, vtkTextProperty *tprop = textAct->GetTextProperty(); vtkNew textPath; vtkTextRenderer *tren = vtkTextRenderer::GetInstance(); - if (tren) + + if (!tren) { - tren->StringToPath(tprop, vtkStdString(string), textPath.GetPointer()); + vtkWarningMacro(<<"Cannot generate path data from 3D text string '" + << string << "': Text renderer unavailable."); + return; } - else + + if (!tren->StringToPath(tprop, vtkStdString(string), textPath.GetPointer(), + vtkTextActor3D::GetRenderedDPI())) { - vtkWarningMacro(<<"Cannot generate path data from 3D text string: " - << string); + vtkWarningMacro(<<"Failed to generate path data from 3D text string '" + << string << "': StringToPath failed."); return; } @@ -783,7 +788,8 @@ void vtkGL2PSExporter::DrawTextActor3D(vtkTextActor3D *textAct, textPos[2] + (forward[2] * 0.0001)}; vtkTextRenderer::Metrics metrics; - if (tren->GetMetrics(tprop, string, metrics)) + if (tren->GetMetrics(tprop, string, metrics, + vtkTextActor3D::GetRenderedDPI())) { vtkNew bgPath; bgPath->InsertNextPoint(static_cast(metrics.TopLeft.GetX()), diff --git a/Interaction/Widgets/vtkCaptionRepresentation.cxx b/Interaction/Widgets/vtkCaptionRepresentation.cxx index faa349d7523..063520c9b28 100644 --- a/Interaction/Widgets/vtkCaptionRepresentation.cxx +++ b/Interaction/Widgets/vtkCaptionRepresentation.cxx @@ -193,10 +193,19 @@ void vtkCaptionRepresentation::AdjustCaptionBoundary() return; } + vtkWindow *win = this->Renderer->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return; + } + int text_bbox[4]; if (!tren->GetBoundingBox(this->CaptionActor2D->GetCaptionTextProperty(), - this->CaptionActor2D->GetCaption(), text_bbox)) + this->CaptionActor2D->GetCaption(), text_bbox, + win->GetDPI())) { + vtkErrorMacro(<<"Error calculating caption bounding box."); return; } diff --git a/Interaction/Widgets/vtkTextRepresentation.cxx b/Interaction/Widgets/vtkTextRepresentation.cxx index 00f154073c8..6068f8e7985 100644 --- a/Interaction/Widgets/vtkTextRepresentation.cxx +++ b/Interaction/Widgets/vtkTextRepresentation.cxx @@ -20,6 +20,7 @@ #include "vtkRenderer.h" #include "vtkStdString.h" #include "vtkCommand.h" +#include "vtkWindow.h" class vtkTextRepresentationObserver : public vtkCommand { @@ -270,9 +271,16 @@ void vtkTextRepresentation::CheckTextBoundary() this->TextActor->ComputeScaledFont(this->GetRenderer()); + vtkWindow *win = this->Renderer->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return; + } + int text_bbox[4]; if (!tren->GetBoundingBox(this->TextActor->GetScaledTextProperty(), - this->GetText(), text_bbox)) + this->GetText(), text_bbox, win->GetDPI())) { return; } diff --git a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor.png.md5 b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor.png.md5 index 3b372b32ec5..547b3ad1cf9 100644 --- a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor.png.md5 +++ b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor.png.md5 @@ -1 +1 @@ -a84ace11ef6ec63994f9be321a24b5f9 +50101c180fac543f8e5cff299c31cd59 diff --git a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_1.png.md5 b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_1.png.md5 index bb356d3378f..12a2d04be7a 100644 --- a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_1.png.md5 +++ b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_1.png.md5 @@ -1 +1 @@ -cef3b676f5b613333f0299bef1304b2d +3b0a123f21ae9514f9b02beab27ab73c diff --git a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_2.png.md5 b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_2.png.md5 deleted file mode 100644 index 92dbb6d97dc..00000000000 --- a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_2.png.md5 +++ /dev/null @@ -1 +0,0 @@ -9d81d2defe95ef7a25c7cfd22afce23e diff --git a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_3.png.md5 b/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_3.png.md5 deleted file mode 100644 index 4bebe5d4310..00000000000 --- a/Rendering/Annotation/Testing/Data/Baseline/TestCaptionActor_3.png.md5 +++ /dev/null @@ -1 +0,0 @@ -781a5b795cf2e68ac0b74eda9b0b8294 diff --git a/Rendering/Annotation/vtkAxisActor.cxx b/Rendering/Annotation/vtkAxisActor.cxx index 8669cd5cfee..eb12abd8c3c 100644 --- a/Rendering/Annotation/vtkAxisActor.cxx +++ b/Rendering/Annotation/vtkAxisActor.cxx @@ -33,6 +33,7 @@ #include "vtkTextProperty.h" #include "vtkVectorText.h" #include "vtkViewport.h" +#include "vtkWindow.h" vtkStandardNewMacro(vtkAxisActor); vtkCxxSetObjectMacro(vtkAxisActor, Camera, vtkCamera); @@ -986,6 +987,13 @@ vtkAxisActor::SetLabelPositions2D(vtkViewport *viewport, bool force) return; } + vtkWindow *win = viewport->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return; + } + for (int i = 0; i < this->NumberOfLabelsBuilt; i++) { ptIdx = 4*i + 1; @@ -1002,7 +1010,8 @@ vtkAxisActor::SetLabelPositions2D(vtkViewport *viewport, bool force) int bbox[4]; if (!tren->GetBoundingBox(this->LabelActors2D[i]->GetTextProperty(), - this->LabelActors2D[i]->GetInput(), bbox)) + this->LabelActors2D[i]->GetInput(), bbox, + win->GetDPI())) { vtkErrorMacro(<< "Unable to calculate bounding box for label " << this->LabelActors2D[i]->GetInput()); diff --git a/Rendering/ContextOpenGL/vtkOpenGLContextDevice2D.cxx b/Rendering/ContextOpenGL/vtkOpenGLContextDevice2D.cxx index 42874116f2a..5ae1e590f66 100644 --- a/Rendering/ContextOpenGL/vtkOpenGLContextDevice2D.cxx +++ b/Rendering/ContextOpenGL/vtkOpenGLContextDevice2D.cxx @@ -871,7 +871,8 @@ void vtkOpenGLContextDevice2D::DrawString(float *point, if (image->GetNumberOfPoints() == 0 && image->GetNumberOfCells() == 0) { int textDims[2]; - if (!this->TextRenderer->RenderString(this->TextProp, string, image, + if (!this->TextRenderer->RenderString(this->TextProp, string, + this->RenderWindow->GetDPI(), image, textDims)) { return; @@ -923,7 +924,8 @@ void vtkOpenGLContextDevice2D::DrawString(float *point, void vtkOpenGLContextDevice2D::ComputeStringBounds(const vtkUnicodeString &string, float bounds[4]) { - vtkVector2i box = this->TextRenderer->GetBounds(this->TextProp, string); + vtkVector2i box = this->TextRenderer->GetBounds(this->TextProp, string, + this->RenderWindow->GetDPI()); // Check for invalid bounding box if (box[0] == VTK_INT_MIN || box[0] == VTK_INT_MAX || box[1] == VTK_INT_MIN || box[1] == VTK_INT_MAX) diff --git a/Rendering/ContextOpenGL2/vtkOpenGLContextDevice2D.cxx b/Rendering/ContextOpenGL2/vtkOpenGLContextDevice2D.cxx index c95dada5665..9cd05960f6c 100644 --- a/Rendering/ContextOpenGL2/vtkOpenGLContextDevice2D.cxx +++ b/Rendering/ContextOpenGL2/vtkOpenGLContextDevice2D.cxx @@ -1256,7 +1256,8 @@ void vtkOpenGLContextDevice2D::DrawString(float *point, if (image->GetNumberOfPoints() == 0 && image->GetNumberOfCells() == 0) { int textDims[2]; - if (!this->TextRenderer->RenderString(this->TextProp, string, image, + if (!this->TextRenderer->RenderString(this->TextProp, string, + this->RenderWindow->GetDPI(), image, textDims)) { return; @@ -1317,7 +1318,8 @@ void vtkOpenGLContextDevice2D::DrawString(float *point, void vtkOpenGLContextDevice2D::ComputeStringBounds(const vtkUnicodeString &string, float bounds[4]) { - vtkVector2i box = this->TextRenderer->GetBounds(this->TextProp, string); + vtkVector2i box = this->TextRenderer->GetBounds(this->TextProp, string, + this->RenderWindow->GetDPI()); // Check for invalid bounding box if (box[0] == VTK_INT_MIN || box[0] == VTK_INT_MAX || box[1] == VTK_INT_MIN || box[1] == VTK_INT_MAX) diff --git a/Rendering/Core/vtkLabeledContourMapper.cxx b/Rendering/Core/vtkLabeledContourMapper.cxx index c986bfc1100..b8e98317d21 100644 --- a/Rendering/Core/vtkLabeledContourMapper.cxx +++ b/Rendering/Core/vtkLabeledContourMapper.cxx @@ -557,6 +557,11 @@ bool vtkLabeledContourMapper::PrepareRender(vtkRenderer *ren, vtkActor *act) vtkCellArray *lines = input->GetLines(); vtkDataArray *scalars = input->GetPointData()->GetScalars(); vtkTextRenderer *tren = vtkTextRenderer::GetInstance(); + if (!tren) + { + vtkErrorMacro(<< "Text renderer unavailable."); + return false; + } // Maps scalar values to text properties: typedef std::map LabelPropertyMapType; @@ -638,7 +643,8 @@ bool vtkLabeledContourMapper::PrepareRender(vtkRenderer *ren, vtkActor *act) it->TProp = tpropIt->second; // Assign bounding box/dims. - if (!tren->GetBoundingBox(it->TProp, it->Text, it->BoundingBox.GetData())) + if (!tren->GetBoundingBox(it->TProp, it->Text, it->BoundingBox.GetData(), + vtkTextActor3D::GetRenderedDPI())) { vtkErrorMacro(<<"Error calculating bounding box for string '" << it->Text << "'."); diff --git a/Rendering/Core/vtkStringToImage.h b/Rendering/Core/vtkStringToImage.h index 33636f48956..36b05dea81b 100644 --- a/Rendering/Core/vtkStringToImage.h +++ b/Rendering/Core/vtkStringToImage.h @@ -49,9 +49,9 @@ class VTKRENDERINGCORE_EXPORT vtkStringToImage : public vtkObject // is valid (it may not if GetBoundingBox() failed or if the string // was empty). virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string) = 0; + const vtkUnicodeString& string, int dpi) = 0; virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkStdString& string) = 0; + const vtkStdString& string, int dpi) = 0; // Description: // Given a text property and a string, this function initializes the @@ -60,11 +60,11 @@ class VTKRENDERINGCORE_EXPORT vtkStringToImage : public vtkObject // This is useful when ScaleToPowerOfTwo is true, and the image dimensions may // not match the dimensions of the rendered text. virtual int RenderString(vtkTextProperty *property, - const vtkUnicodeString& string, + const vtkUnicodeString& string, int dpi, vtkImageData *data, int textDims[2] = NULL) = 0; virtual int RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int text_dims[2] = NULL) = 0; diff --git a/Rendering/Core/vtkTextActor.cxx b/Rendering/Core/vtkTextActor.cxx index c44a6b9720b..8f4e872da6b 100644 --- a/Rendering/Core/vtkTextActor.cxx +++ b/Rendering/Core/vtkTextActor.cxx @@ -29,6 +29,7 @@ #include "vtkMath.h" #include "vtkTextRenderer.h" #include "vtkRenderer.h" +#include "vtkRenderWindow.h" #include @@ -101,6 +102,7 @@ vtkTextActor::vtkTextActor() this->InputRendered = false; this->FormerOrientation = 0.0; + this->RenderedDPI = 0; this->TextRenderer = vtkTextRenderer::GetInstance(); if (!this->TextRenderer) @@ -175,7 +177,8 @@ int vtkTextActor::SetConstrainedFontSize(vtkViewport* viewport, int targetWidth, int targetHeight) { - return this->SetConstrainedFontSize(this, viewport, targetWidth, targetHeight); + return this->SetConstrainedFontSize(this, viewport, targetWidth, + targetHeight); } @@ -330,26 +333,43 @@ void vtkTextActor::SetNonLinearFontScale(double exp, int tgt) } // ---------------------------------------------------------------------------- -bool vtkTextActor::RenderImage(vtkTextProperty *tprop, vtkViewport *) +bool vtkTextActor::RenderImage(vtkTextProperty *tprop, vtkViewport *vp) { vtkStdString text; if (this->Input && this->Input[0]) { text = this->Input; } - return this->TextRenderer->RenderString(tprop, text, this->ImageData); + + vtkWindow *win = vp->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return false; + } + + return this->TextRenderer->RenderString(tprop, text, this->ImageData, + NULL, win->GetDPI()); } // ---------------------------------------------------------------------------- -bool vtkTextActor::GetImageBoundingBox(vtkTextProperty *tprop, vtkViewport *, - int bbox[4]) +bool vtkTextActor::GetImageBoundingBox(vtkTextProperty *tprop, vtkViewport *vp, + int bbox[4]) { vtkStdString text; if (this->Input && this->Input[0]) { text = this->Input; } - return this->TextRenderer->GetBoundingBox(tprop, text, bbox); + + vtkWindow *win = vp->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return false; + } + + return this->TextRenderer->GetBoundingBox(tprop, text, bbox, win->GetDPI()); } // ---------------------------------------------------------------------------- @@ -718,9 +738,16 @@ void vtkTextActor::ComputeScaledFont(vtkViewport *viewport) } int max_height = static_cast(this->MaximumLineHeight * size[1]); + vtkWindow *win = viewport->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return; + } + int fsize = this->TextRenderer->GetConstrainedFontSize( this->Input, this->ScaledTextProperty, size[0], - (size[1] < max_height ? size[1] : max_height)); + (size[1] < max_height ? size[1] : max_height), win->GetDPI()); if (fsize == -1) { @@ -860,9 +887,17 @@ int vtkTextActor::UpdateRectangle(vtkViewport* viewport) this->ComputeScaledFont(viewport); } + vtkWindow *win = viewport->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return 0; + } + //check if we need to render the string if(this->ScaledTextProperty->GetMTime() > this->BuildTime || - !this->InputRendered || this->GetMTime() > this->BuildTime) + !this->InputRendered || this->GetMTime() > this->BuildTime || + this->RenderedDPI != win->GetDPI()) { if(!this->RenderImage(this->ScaledTextProperty, viewport)) { @@ -879,6 +914,7 @@ int vtkTextActor::UpdateRectangle(vtkViewport* viewport) this->Texture->SetInputData(this->ImageData); this->Texture->Modified(); this->InputRendered = true; + this->RenderedDPI = win->GetDPI(); this->BuildTime.Modified(); } return 1; diff --git a/Rendering/Core/vtkTextActor.h b/Rendering/Core/vtkTextActor.h index 4dd477d4eaa..4eff5b5ea84 100644 --- a/Rendering/Core/vtkTextActor.h +++ b/Rendering/Core/vtkTextActor.h @@ -265,6 +265,7 @@ class VTKRENDERINGCORE_EXPORT vtkTextActor : public vtkTexturedActor2D char *Input; bool InputRendered; double FormerOrientation; + int RenderedDPI; vtkTextProperty *ScaledTextProperty; diff --git a/Rendering/Core/vtkTextActor3D.cxx b/Rendering/Core/vtkTextActor3D.cxx index 64b81308442..4dab1571186 100644 --- a/Rendering/Core/vtkTextActor3D.cxx +++ b/Rendering/Core/vtkTextActor3D.cxx @@ -116,7 +116,8 @@ int vtkTextActor3D::GetBoundingBox(int bbox[4]) return 0; } - if (!tRend->GetBoundingBox(this->TextProperty, this->Input, bbox)) + if (!tRend->GetBoundingBox(this->TextProperty, this->Input, bbox, + vtkTextActor3D::GetRenderedDPI())) { vtkErrorMacro(<<"No text in input."); return 0; @@ -137,18 +138,6 @@ int vtkTextActor3D::RenderOverlay(vtkViewport *viewport) { int rendered_something = 0; - // Is the viewport's RenderWindow capturing GL2PS-special props? - if (vtkRenderer *renderer = vtkRenderer::SafeDownCast(viewport)) - { - if (vtkRenderWindow *renderWindow = renderer->GetRenderWindow()) - { - if (renderWindow->GetCapturingGL2PSSpecialProps()) - { - renderer->CaptureGL2PSSpecialProp(this); - } - } - } - if (this->UpdateImageActor() && this->ImageData && this->ImageData->GetNumberOfPoints() > 0) @@ -180,16 +169,7 @@ int vtkTextActor3D::RenderTranslucentPolygonalGeometry(vtkViewport *viewport) // Does this prop have some translucent polygonal geometry? int vtkTextActor3D::HasTranslucentPolygonalGeometry() { - int result = 0; - - if (this->UpdateImageActor() && - this->ImageData && - this->ImageData->GetNumberOfPoints() > 0) - { - result=this->ImageActor->HasTranslucentPolygonalGeometry(); - } - - return result; + return 1; } // -------------------------------------------------------------------------- @@ -197,9 +177,20 @@ int vtkTextActor3D::RenderOpaqueGeometry(vtkViewport *viewport) { int rendered_something = 0; + if (vtkRenderer *renderer = vtkRenderer::SafeDownCast(viewport)) + { + if (vtkRenderWindow *renderWindow = renderer->GetRenderWindow()) + { + // Is the viewport's RenderWindow capturing GL2PS-special props? + if (renderWindow->GetCapturingGL2PSSpecialProps()) + { + renderer->CaptureGL2PSSpecialProp(this); + } + } + } + if (this->UpdateImageActor() && - this->ImageData && - this->ImageData->GetNumberOfPoints() > 0) + this->ImageData && this->ImageData->GetNumberOfPoints() > 0) { rendered_something += this->ImageActor->RenderOpaqueGeometry(viewport); } @@ -214,6 +205,7 @@ int vtkTextActor3D::UpdateImageActor() if (!this->TextProperty) { vtkErrorMacro(<<"Need a text property to render text actor"); + this->ImageActor->SetInputData(0); return 0; } @@ -251,12 +243,15 @@ int vtkTextActor3D::UpdateImageActor() if (!tRend) { vtkErrorMacro(<<"Failed getting the TextRenderer instance."); + this->ImageActor->SetInputData(0); return 0; } - if (!tRend->RenderString(this->TextProperty, this->Input, this->ImageData)) + if (!tRend->RenderString(this->TextProperty, this->Input, this->ImageData, + NULL, vtkTextActor3D::GetRenderedDPI())) { vtkErrorMacro(<<"Failed rendering text to buffer"); + this->ImageActor->SetInputData(0); return 0; } diff --git a/Rendering/Core/vtkTextActor3D.h b/Rendering/Core/vtkTextActor3D.h index 07544c3c4e6..2f134235762 100644 --- a/Rendering/Core/vtkTextActor3D.h +++ b/Rendering/Core/vtkTextActor3D.h @@ -54,6 +54,13 @@ class VTKRENDERINGCORE_EXPORT vtkTextActor3D : public vtkProp3D virtual void SetTextProperty(vtkTextProperty *p); vtkGetObjectMacro(TextProperty,vtkTextProperty); + // Description: + // Since a 3D text actor is not pixel-aligned and positioned in 3D space, + // the text is rendered at a constant DPI, rather than using the current + // window DPI. This static method returns the DPI value used to produce the + // text images. + static int GetRenderedDPI() { return 72; } + // Description: // Shallow copy of this text actor. Overloads the virtual // vtkProp method. @@ -65,10 +72,10 @@ class VTKRENDERINGCORE_EXPORT vtkTextActor3D : public vtkProp3D void GetBounds(double bounds[6]) {this->vtkProp3D::GetBounds( bounds );} // Description: - // Get the Freetype-derived real bounding box for the given vtkTextProperty + // Get the vtkTextRenderer-derived bounding box for the given vtkTextProperty // and text string str. Results are returned in the four element bbox int // array. This call can be used for sizing other elements. - virtual int GetBoundingBox(int bbox[4]); + int GetBoundingBox(int bbox[4]); //BTX // Description: diff --git a/Rendering/Core/vtkTextMapper.cxx b/Rendering/Core/vtkTextMapper.cxx index 34e5916e9a1..d318b1c3564 100644 --- a/Rendering/Core/vtkTextMapper.cxx +++ b/Rendering/Core/vtkTextMapper.cxx @@ -29,6 +29,7 @@ #include "vtkTextProperty.h" #include "vtkTextRenderer.h" #include "vtkTexture.h" +#include "vtkWindow.h" #include @@ -44,6 +45,8 @@ vtkTextMapper::vtkTextMapper() this->Input = NULL; this->TextProperty = NULL; + this->RenderedDPI = 0; + vtkNew tprop; this->SetTextProperty(tprop.GetPointer()); @@ -128,9 +131,17 @@ void vtkTextMapper::PrintSelf(ostream& os, vtkIndent indent) } //---------------------------------------------------------------------------- -void vtkTextMapper::GetSize(vtkViewport *, int size[]) +void vtkTextMapper::GetSize(vtkViewport *vp, int size[2]) { - UpdateImage(); + 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()); size[0] = this->TextDims[0]; size[1] = this->TextDims[1]; } @@ -161,7 +172,8 @@ int vtkTextMapper::SetConstrainedFontSize(vtkViewport *viewport, //---------------------------------------------------------------------------- -int vtkTextMapper::SetConstrainedFontSize(vtkTextMapper *tmapper, vtkViewport *viewport, +int vtkTextMapper::SetConstrainedFontSize(vtkTextMapper *tmapper, + vtkViewport *viewport, int targetWidth, int targetHeight) { // If target "empty" just return @@ -357,8 +369,16 @@ void vtkTextMapper::RenderOverlay(vtkViewport *viewport, vtkActor2D *actor) vtkRenderer *ren = NULL; if (this->Input && this->Input[0]) { - this->UpdateImage(); - this->UpdateQuad(actor); + vtkWindow *win = viewport->GetVTKWindow(); + if (!win) + { + vtkErrorMacro(<<"No render window available: cannot determine DPI."); + return; + } + + this->UpdateImage(win->GetDPI()); + this->UpdateQuad(actor, win->GetDPI()); + ren = vtkRenderer::SafeDownCast(viewport); if (ren) { @@ -438,13 +458,10 @@ int vtkTextMapper::GetNumberOfLines(const char *input) #endif // VTK_LEGACY_REMOVE //---------------------------------------------------------------------------- -void vtkTextMapper::UpdateQuad(vtkActor2D *actor) +void vtkTextMapper::UpdateQuad(vtkActor2D *actor, int dpi) { vtkDebugMacro(<<"UpdateQuad called"); - // Ensure that the image is up to date. - UpdateImage(); - // Update texture coordinates: if (this->Image->GetMTime() > this->TCoordsTime) { @@ -503,7 +520,7 @@ void vtkTextMapper::UpdateQuad(vtkActor2D *actor) { if (!tren->GetBoundingBox(this->TextProperty, this->Input ? this->Input : std::string(), - text_bbox)) + text_bbox, dpi)) { vtkErrorMacro(<<"Error calculating bounding box."); } @@ -528,10 +545,11 @@ void vtkTextMapper::UpdateQuad(vtkActor2D *actor) } //---------------------------------------------------------------------------- -void vtkTextMapper::UpdateImage() +void vtkTextMapper::UpdateImage(int dpi) { vtkDebugMacro(<<"UpdateImage called"); if (this->MTime > this->Image->GetMTime() || + this->RenderedDPI != dpi || this->TextProperty->GetMTime() > this->Image->GetMTime()) { vtkTextRenderer *tren = vtkTextRenderer::GetInstance(); @@ -539,10 +557,11 @@ void vtkTextMapper::UpdateImage() { if (!tren->RenderString(this->TextProperty, this->Input ? this->Input : std::string(), - this->Image.GetPointer(), this->TextDims)) + this->Image.GetPointer(), this->TextDims, dpi)) { vtkErrorMacro(<<"Texture generation failed."); } + this->RenderedDPI = dpi; vtkDebugMacro(<< "Text rendered to " << this->TextDims[0] << ", " << this->TextDims[1] << " buffer."); } diff --git a/Rendering/Core/vtkTextMapper.h b/Rendering/Core/vtkTextMapper.h index b4a869e825c..46f9cb19790 100644 --- a/Rendering/Core/vtkTextMapper.h +++ b/Rendering/Core/vtkTextMapper.h @@ -135,11 +135,12 @@ class VTKRENDERINGCORE_EXPORT vtkTextMapper : public vtkMapper2D vtkTextMapper(const vtkTextMapper&); // Not implemented. void operator=(const vtkTextMapper&); // Not implemented. - void UpdateQuad(vtkActor2D *actor); - void UpdateImage(); + void UpdateQuad(vtkActor2D *actor, int dpi); + void UpdateImage(int dpi); int TextDims[2]; + int RenderedDPI; vtkTimeStamp CoordsTime; vtkTimeStamp TCoordsTime; vtkNew Image; diff --git a/Rendering/Core/vtkTextRenderer.h b/Rendering/Core/vtkTextRenderer.h index 7d7cd95a68d..c3dad681995 100644 --- a/Rendering/Core/vtkTextRenderer.h +++ b/Rendering/Core/vtkTextRenderer.h @@ -146,16 +146,14 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject // ymin, ymax} of the rendered string in pixels. The origin of the bounding // box is the anchor point described by the horizontal and vertical // justification text property variables. - // Some rendering backends need the DPI of the target. If it is not provided, - // a DPI of 120 is assumed. // Return true on success, false otherwise. bool GetBoundingBox(vtkTextProperty *tprop, const vtkStdString &str, - int bbox[4], int dpi = 120, int backend = Default) + int bbox[4], int dpi, int backend = Default) { return this->GetBoundingBoxInternal(tprop, str, bbox, dpi, backend); } bool GetBoundingBox(vtkTextProperty *tprop, const vtkUnicodeString &str, - int bbox[4], int dpi = 120, int backend = Default) + int bbox[4], int dpi, int backend = Default) { return this->GetBoundingBoxInternal(tprop, str, bbox, dpi, backend); } @@ -164,16 +162,14 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject // Description: // Given a text property and a string, get some metrics for the rendered // string. - // Some rendering backends need the DPI of the target. If it is not provided, - // a DPI of 120 is assumed. // Return true on success, false otherwise. bool GetMetrics(vtkTextProperty *tprop, const vtkStdString &str, - Metrics &metrics, int dpi = 120, int backend = Default) + Metrics &metrics, int dpi, int backend = Default) { return this->GetMetricsInternal(tprop, str, metrics, dpi, backend); } bool GetMetrics(vtkTextProperty *tprop, const vtkUnicodeString &str, - Metrics &metrics, int dpi = 120, int backend = Default) + Metrics &metrics, int dpi, int backend = Default) { return this->GetMetricsInternal(tprop, str, metrics, dpi, backend); } @@ -191,16 +187,14 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject // The origin of the image's extents is aligned with the anchor point // described by the text property's vertical and horizontal justification // options. - // Some rendering backends need the DPI of the target. If it is not provided, - // a DPI of 120 is assumed. bool RenderString(vtkTextProperty *tprop, const vtkStdString &str, - vtkImageData *data, int textDims[2] = NULL, int dpi = 120, + vtkImageData *data, int textDims[2], int dpi, int backend = Default) { return this->RenderStringInternal(tprop, str, data, textDims, dpi, backend); } bool RenderString(vtkTextProperty *tprop, const vtkUnicodeString &str, - vtkImageData *data, int textDims[2] = NULL, int dpi = 120, + vtkImageData *data, int textDims[2], int dpi, int backend = Default) { return this->RenderStringInternal(tprop, str, data, textDims, dpi, backend); @@ -211,17 +205,15 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject // tprop that is required to fit the string in the target rectangle. The // computed font size will be set in @a tprop as well. If an error occurs, // this function will return -1. - // Some rendering backends need the DPI of the target. If it is not provided, - // a DPI of 120 is assumed. int GetConstrainedFontSize(const vtkStdString &str, vtkTextProperty *tprop, - int targetWidth, int targetHeight, int dpi = 120, + int targetWidth, int targetHeight, int dpi, int backend = Default) { return this->GetConstrainedFontSizeInternal(str, tprop, targetWidth, targetHeight, dpi, backend); } int GetConstrainedFontSize(const vtkUnicodeString &str, vtkTextProperty *tprop, - int targetWidth, int targetHeight, int dpi = 120, + int targetWidth, int targetHeight, int dpi, int backend = Default) { return this->GetConstrainedFontSizeInternal(str, tprop, targetWidth, @@ -235,14 +227,14 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject // property's horizontal and vertical justification options. // Return true on success, false otherwise. bool StringToPath(vtkTextProperty *tprop, const vtkStdString &str, - vtkPath *path, int backend = Default) + vtkPath *path, int dpi, int backend = Default) { - return this->StringToPathInternal(tprop, str, path, backend); + return this->StringToPathInternal(tprop, str, path, dpi, backend); } bool StringToPath(vtkTextProperty *tprop, const vtkUnicodeString &str, - vtkPath *path, int backend = Default) + vtkPath *path, int dpi, int backend = Default) { - return this->StringToPathInternal(tprop, str, path, backend); + return this->StringToPathInternal(tprop, str, path, dpi, backend); } // Description: @@ -293,10 +285,10 @@ class VTKRENDERINGCORE_EXPORT vtkTextRenderer: public vtkObject int dpi, int backend) = 0; virtual bool StringToPathInternal(vtkTextProperty *tprop, const vtkStdString &str, vtkPath *path, - int backend) = 0; + int dpi, int backend) = 0; virtual bool StringToPathInternal(vtkTextProperty *tprop, const vtkUnicodeString &str, vtkPath *path, - int backend) = 0; + int dpi, int backend) = 0; virtual void SetScaleToPowerOfTwoInternal(bool scale) = 0; // Description: diff --git a/Rendering/FreeType/Testing/Cxx/CMakeLists.txt b/Rendering/FreeType/Testing/Cxx/CMakeLists.txt index 2ad3e9d9470..435be434495 100644 --- a/Rendering/FreeType/Testing/Cxx/CMakeLists.txt +++ b/Rendering/FreeType/Testing/Cxx/CMakeLists.txt @@ -26,10 +26,12 @@ set_tests_properties( if(${Module_vtkRenderingMatplotlib}) set(TestMathTextFreeTypeTextRenderer_ARGS DATA{../Data/Fonts/DejaVuSans.ttf}) set(TestFreeTypeTextMapper_ARGS DATA{../Data/Fonts/DejaVuSans.ttf}) + set(TestFontDPIScaling_ARGS DATA{../Data/Fonts/DejaVuSans.ttf}) vtk_add_test_cxx(${vtk-module}CxxTests matplotlib_tests TestMathTextFreeTypeTextRenderer.cxx TestFreeTypeTextMapper.cxx + TestFontDPIScaling.cxx ) list(APPEND tests ${matplotlib_tests}) diff --git a/Rendering/FreeType/Testing/Cxx/TestFTStringToPath.cxx b/Rendering/FreeType/Testing/Cxx/TestFTStringToPath.cxx index 14b32c0d95f..0fb4a63e848 100644 --- a/Rendering/FreeType/Testing/Cxx/TestFTStringToPath.cxx +++ b/Rendering/FreeType/Testing/Cxx/TestFTStringToPath.cxx @@ -58,9 +58,9 @@ int TestFTStringToPath(int , char *[]) vtkNew path; vtkNew tprop; - vtkFreeTypeTools::GetInstance()->StringToPath(tprop.GetPointer(), - vtkStdString("FreeType Path"), - path.GetPointer()); + vtkFreeTypeTools::GetInstance()->StringToPath( + tprop.GetPointer(), vtkStdString("FreeType Path"), + view->GetRenderWindow()->GetDPI(), path.GetPointer()); test->SetPath(path.GetPointer()); diff --git a/Rendering/FreeType/Testing/Cxx/TestFontDPIScaling.cxx b/Rendering/FreeType/Testing/Cxx/TestFontDPIScaling.cxx new file mode 100644 index 00000000000..4c229880400 --- /dev/null +++ b/Rendering/FreeType/Testing/Cxx/TestFontDPIScaling.cxx @@ -0,0 +1,225 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestMathTextFreeTypeTextRenderer.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 "vtkTextRenderer.h" + +#include "vtkNew.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkStdString.h" +#include "vtkTextActor.h" +#include "vtkTextProperty.h" + +#include +#include + +//---------------------------------------------------------------------------- +int TestFontDPIScaling(int argc, char *argv[]) +{ + if (argc < 2) + { + cerr << "Missing font filename." << endl; + return EXIT_FAILURE; + } + + std::string uncodeFontFile(argv[1]); + + vtkStdString str = "Sample multiline\ntext rendered\nusing FreeTypeTools."; + + vtkNew actor1; + actor1->GetTextProperty()->SetFontSize(20); + actor1->GetTextProperty()->SetColor(1.0, 0.0, 0.0); + actor1->GetTextProperty()->SetJustificationToLeft(); + actor1->GetTextProperty()->SetVerticalJustificationToTop(); + actor1->GetTextProperty()->SetFontFamilyToTimes(); + actor1->SetInput(str.c_str()); + actor1->SetPosition(10, 590); + + vtkNew actor2; + actor2->GetTextProperty()->SetFontSize(20); + actor2->GetTextProperty()->SetColor(0.0, 1.0, 0.0); + actor2->GetTextProperty()->SetJustificationToRight(); + actor2->GetTextProperty()->SetVerticalJustificationToTop(); + actor2->GetTextProperty()->SetFontFamilyToCourier(); + actor2->SetInput(str.c_str()); + actor2->SetPosition(590, 590); + + vtkNew actor3; + actor3->GetTextProperty()->SetFontSize(20); + actor3->GetTextProperty()->SetColor(0.0, 0.0, 1.0); + actor3->GetTextProperty()->SetJustificationToLeft(); + actor3->GetTextProperty()->SetVerticalJustificationToBottom(); + actor3->GetTextProperty()->SetItalic(1); + actor3->SetInput(str.c_str()); + actor3->SetPosition(10, 10); + + vtkNew actor4; + actor4->GetTextProperty()->SetFontSize(20); + actor4->GetTextProperty()->SetColor(0.3, 0.4, 0.5); + actor4->GetTextProperty()->SetJustificationToRight(); + actor4->GetTextProperty()->SetVerticalJustificationToBottom(); + actor4->GetTextProperty()->SetBold(1); + actor4->GetTextProperty()->SetShadow(1); + actor4->GetTextProperty()->SetShadowOffset(-3, 2); + actor4->SetInput(str.c_str()); + actor4->SetPosition(590, 10); + + vtkNew actor5; + actor5->GetTextProperty()->SetFontSize(20); + actor5->GetTextProperty()->SetColor(1.0, 1.0, 0.0); + actor5->GetTextProperty()->SetJustificationToCentered(); + actor5->GetTextProperty()->SetVerticalJustificationToCentered(); + actor5->GetTextProperty()->SetBold(1); + actor5->GetTextProperty()->SetItalic(1); + actor5->GetTextProperty()->SetShadow(1); + actor5->GetTextProperty()->SetShadowOffset(5, -8); + actor5->SetInput(str.c_str()); + actor5->SetPosition(300, 300); + + vtkNew actor6; + actor6->GetTextProperty()->SetFontSize(16); + actor6->GetTextProperty()->SetColor(1.0, 0.5, 0.2); + actor6->GetTextProperty()->SetJustificationToCentered(); + actor6->GetTextProperty()->SetVerticalJustificationToCentered(); + actor6->GetTextProperty()->SetOrientation(45); + actor6->SetInput(str.c_str()); + actor6->SetPosition(300, 450); + + vtkNew actor7; + actor7->GetTextProperty()->SetFontSize(16); + actor7->GetTextProperty()->SetColor(0.5, 0.2, 1.0); + actor7->GetTextProperty()->SetJustificationToLeft(); + actor7->GetTextProperty()->SetVerticalJustificationToCentered(); + actor7->GetTextProperty()->SetOrientation(45); + actor7->SetInput(str.c_str()); + actor7->SetPosition(100, 156); + + vtkNew actor8; + actor8->GetTextProperty()->SetFontSize(16); + actor8->GetTextProperty()->SetColor(0.8, 1.0, 0.3); + actor8->GetTextProperty()->SetJustificationToRight(); + actor8->GetTextProperty()->SetVerticalJustificationToCentered(); + actor8->GetTextProperty()->SetOrientation(45); + actor8->SetInput(str.c_str()); + actor8->SetPosition(500, 249); + + // Mathtext tests + + // Test that escaped "$" are passed through to freetype: + vtkNew actor9; + actor9->GetTextProperty()->SetFontSize(12); + actor9->GetTextProperty()->SetColor(0.2, 0.5, 1.0); + actor9->SetInput("Escaped dollar signs:\n\\$10, \\$20"); + actor9->SetPosition(100, 450); + + vtkNew actor10; + actor10->GetTextProperty()->SetFontSize(16); + actor10->GetTextProperty()->SetColor(0.5, 0.2, 1.0); + actor10->GetTextProperty()->SetJustificationToRight(); + actor10->GetTextProperty()->SetOrientation(45); + actor10->SetInput("Test MathText $\\int_0^\\infty\\frac{2\\pi}" + "{x - \\frac{z}{4}}\\,dx$"); + actor10->SetPosition(588, 433); + + // Invalid latex markup -- should fallback to freetype. + vtkNew actor11; + actor11->GetTextProperty()->SetFontSize(15); + actor11->GetTextProperty()->SetColor(1.0, 0.5, 0.2); + actor11->SetInput("Test FreeType fallback:\n$\\asdf$"); + actor11->SetPosition(10, 350); + + // Both $...$ and \\$ + vtkNew actor12; + actor12->GetTextProperty()->SetFontSize(18); + actor12->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + actor12->SetInput("Test MathText '\\$' $\\$\\sqrt[3]{8}$"); + actor12->SetPosition(10, 300); + + // $...$ without other text. + vtkNew actor13; + actor13->GetTextProperty()->SetFontSize(18); + actor13->GetTextProperty()->SetColor(0.2, 1.0, 1.0); + actor13->SetInput("$A = \\pi r^2$"); + actor13->SetPosition(10, 250); + + // Numbers, using courier, Text that gets 'cut off' + vtkNew actor14; + actor14->GetTextProperty()->SetFontSize(21); + actor14->GetTextProperty()->SetColor(1.0, 0.0, 0.0); + actor14->GetTextProperty()->SetJustificationToCentered(); + actor14->GetTextProperty()->SetVerticalJustificationToCentered(); + actor14->GetTextProperty()->SetBold(1); + actor14->GetTextProperty()->SetItalic(1); + actor14->GetTextProperty()->SetFontFamilyToCourier(); + actor14->SetInput("4.0"); + actor14->SetPosition(500, 400); + + // UTF-8 freetype handling: + vtkNew actor15; + actor15->GetTextProperty()->SetFontFamily(VTK_FONT_FILE); + actor15->GetTextProperty()->SetFontFile(uncodeFontFile.c_str()); + actor15->GetTextProperty()->SetJustificationToCentered(); + actor15->GetTextProperty()->SetVerticalJustificationToCentered(); + actor15->GetTextProperty()->SetFontSize(18); + actor15->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + actor15->SetInput("UTF-8 FreeType: \xce\xa8\xd2\x94\xd2\x96\xd1\x84\xd2\xbe"); + actor15->SetPosition(300, 110); + + // Test for rotated kerning (PR#15301) + vtkNew actor16; + actor16->GetTextProperty()->SetFontFile(uncodeFontFile.c_str()); + actor16->GetTextProperty()->SetFontFamily(VTK_FONT_FILE); + actor16->GetTextProperty()->SetJustificationToCentered(); + actor16->GetTextProperty()->SetVerticalJustificationToCentered(); + actor16->GetTextProperty()->SetFontSize(18); + actor16->GetTextProperty()->SetOrientation(90); + actor16->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + actor16->SetInput("oTeVaVoVAW"); + actor16->SetPosition(300, 200); + + vtkNew ren; + ren->SetBackground(0.1, 0.1, 0.1); + vtkNew win; + win->SetDPI(96); + win->SetSize(600, 600); + win->AddRenderer(ren.GetPointer()); + vtkNew iren; + iren->SetRenderWindow(win.GetPointer()); + + ren->AddActor(actor1.GetPointer()); + ren->AddActor(actor2.GetPointer()); + ren->AddActor(actor3.GetPointer()); + ren->AddActor(actor4.GetPointer()); + ren->AddActor(actor5.GetPointer()); + ren->AddActor(actor6.GetPointer()); + ren->AddActor(actor7.GetPointer()); + ren->AddActor(actor8.GetPointer()); + ren->AddActor(actor9.GetPointer()); + ren->AddActor(actor10.GetPointer()); + ren->AddActor(actor11.GetPointer()); + ren->AddActor(actor12.GetPointer()); + ren->AddActor(actor13.GetPointer()); + ren->AddActor(actor14.GetPointer()); + ren->AddActor(actor15.GetPointer()); + ren->AddActor(actor16.GetPointer()); + + win->SetMultiSamples(0); + win->Render(); + win->GetInteractor()->Initialize(); + win->GetInteractor()->Start(); + + return EXIT_SUCCESS; +} diff --git a/Rendering/FreeType/Testing/Data/Baseline/TestFontDPIScaling.png.md5 b/Rendering/FreeType/Testing/Data/Baseline/TestFontDPIScaling.png.md5 new file mode 100644 index 00000000000..0a9e63160e3 --- /dev/null +++ b/Rendering/FreeType/Testing/Data/Baseline/TestFontDPIScaling.png.md5 @@ -0,0 +1 @@ +1c292bb373a07e4e96adfa845b708510 diff --git a/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapper.png.md5 b/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapper.png.md5 index def2e1a84fb..bc4d540e13a 100644 --- a/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapper.png.md5 +++ b/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapper.png.md5 @@ -1 +1 @@ -776c796b4f1d5999c570dbba44941c52 +f63e7ee1cf1eb018516200803d8a217f diff --git a/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapperNoMath.png.md5 b/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapperNoMath.png.md5 index 0d3ffb8c0ed..97acdf8b810 100644 --- a/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapperNoMath.png.md5 +++ b/Rendering/FreeType/Testing/Data/Baseline/TestFreeTypeTextMapperNoMath.png.md5 @@ -1 +1 @@ -c873cc65d2bb65fed2ffc7167d3e87cc +9674f2662980d405810aa6c9cab225a3 diff --git a/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRenderer.png.md5 b/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRenderer.png.md5 index 2df75b96d5f..ee4f3cd3f35 100644 --- a/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRenderer.png.md5 +++ b/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRenderer.png.md5 @@ -1 +1 @@ -03a5b5d10aaa1fea93cfb64e104eaab7 +51d2d54769d8ef1174757be6fcc43392 diff --git a/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRendererNoMath.png.md5 b/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRendererNoMath.png.md5 index 902411a4874..bad067fee87 100644 --- a/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRendererNoMath.png.md5 +++ b/Rendering/FreeType/Testing/Data/Baseline/TestMathTextFreeTypeTextRendererNoMath.png.md5 @@ -1 +1 @@ -9e083f5e7f260b72822e8c05c33ce836 +6f9c7264b8fcade67f0490e1aae70f4a diff --git a/Rendering/FreeType/vtkFreeTypeStringToImage.cxx b/Rendering/FreeType/vtkFreeTypeStringToImage.cxx index a0f6e4d3084..f8653050e15 100644 --- a/Rendering/FreeType/vtkFreeTypeStringToImage.cxx +++ b/Rendering/FreeType/vtkFreeTypeStringToImage.cxx @@ -52,7 +52,8 @@ vtkFreeTypeStringToImage::~vtkFreeTypeStringToImage() //----------------------------------------------------------------------------- vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string) + const vtkUnicodeString& string, + int dpi) { int tmp[4] = { 0, 0, 0, 0 }; vtkVector2i recti(tmp); @@ -61,7 +62,7 @@ vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, return recti; } - this->Implementation->FreeType->GetBoundingBox(property, string, tmp); + this->Implementation->FreeType->GetBoundingBox(property, string, dpi, tmp); recti.Set(tmp[1] - tmp[0], tmp[3] - tmp[2]); @@ -71,7 +72,8 @@ vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, //----------------------------------------------------------------------------- vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, - const vtkStdString& string) + const vtkStdString& string, + int dpi) { vtkVector2i recti(0, 0); int tmp[4]; @@ -80,7 +82,7 @@ vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, return recti; } - this->Implementation->FreeType->GetBoundingBox(property, string, tmp); + this->Implementation->FreeType->GetBoundingBox(property, string, dpi, tmp); recti.Set(tmp[1] - tmp[0], tmp[3] - tmp[2]); @@ -91,34 +93,21 @@ vtkVector2i vtkFreeTypeStringToImage::GetBounds(vtkTextProperty *property, //----------------------------------------------------------------------------- int vtkFreeTypeStringToImage::RenderString(vtkTextProperty *property, const vtkUnicodeString& string, - vtkImageData *data, int textDims[2]) + int dpi, vtkImageData *data, + int textDims[2]) { - // Get the required size, and initialize a new QImage to draw on. - vtkVector2i box = this->GetBounds(property, string); - if (box.GetX() == 0 || box.GetY() == 0) - { - return 0; - } - return this->Implementation->FreeType->RenderString(property, - string, + string, dpi, data, textDims); } //----------------------------------------------------------------------------- int vtkFreeTypeStringToImage::RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int textDims[2]) { - // Get the required size, and initialize a new QImage to draw on. - vtkVector2i box = this->GetBounds(property, string); - if (box.GetX() == 0 || box.GetY() == 0) - { - return 0; - } - - return this->Implementation->FreeType->RenderString(property, string, data, - textDims); + return this->Implementation->FreeType->RenderString(property, string, dpi, + data, textDims); } //----------------------------------------------------------------------------- diff --git a/Rendering/FreeType/vtkFreeTypeStringToImage.h b/Rendering/FreeType/vtkFreeTypeStringToImage.h index d88ded7b684..873a2e84dd9 100644 --- a/Rendering/FreeType/vtkFreeTypeStringToImage.h +++ b/Rendering/FreeType/vtkFreeTypeStringToImage.h @@ -46,9 +46,9 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeStringToImage : public vtkStringToI // is valid (it may not if GetBoundingBox() failed or if the string // was empty). virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string); + const vtkUnicodeString& string, int dpi); virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkStdString& string); + const vtkStdString& string, int dpi); // Description: // Given a text property and a string, this function initializes the @@ -57,11 +57,11 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeStringToImage : public vtkStringToI // This is useful when ScaleToPowerOfTwo is true, and the image dimensions may // not match the dimensions of the rendered text. virtual int RenderString(vtkTextProperty *property, - const vtkUnicodeString& string, + const vtkUnicodeString& string, int dpi, vtkImageData *data, int textDims[2] = NULL); virtual int RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int textDims[2] = NULL); diff --git a/Rendering/FreeType/vtkFreeTypeTools.cxx b/Rendering/FreeType/vtkFreeTypeTools.cxx index 9a2f2e385aa..5c99e94579d 100644 --- a/Rendering/FreeType/vtkFreeTypeTools.cxx +++ b/Rendering/FreeType/vtkFreeTypeTools.cxx @@ -77,6 +77,8 @@ class vtkFreeTypeTools::MetaData vtkTextProperty *textProperty; unsigned long textPropertyCacheId; unsigned long unrotatedTextPropertyCacheId; + FTC_ScalerRec scaler; + FTC_ScalerRec unrotatedScaler; FT_Face face; bool faceHasKerning; bool faceIsRotated; @@ -392,7 +394,7 @@ void vtkFreeTypeTools::ReleaseCacheManager() //---------------------------------------------------------------------------- bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, - const vtkStdString& str, + const vtkStdString& str, int dpi, int bbox[4]) { // We need the tprop and bbox @@ -409,7 +411,7 @@ bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, } MetaData metaData; - bool result = this->PrepareMetaData(tprop, metaData); + bool result = this->PrepareMetaData(tprop, dpi, metaData); if (result) { result = this->CalculateBoundingBox(str, metaData); @@ -423,7 +425,7 @@ bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, //---------------------------------------------------------------------------- bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, - const vtkUnicodeString& str, + const vtkUnicodeString& str, int dpi, int bbox[4]) { // We need the tprop and bbox @@ -440,7 +442,7 @@ bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, } MetaData metaData; - bool result = this->PrepareMetaData(tprop, metaData); + bool result = this->PrepareMetaData(tprop, dpi, metaData); if (result) { result = this->CalculateBoundingBox(str, metaData); @@ -454,7 +456,7 @@ bool vtkFreeTypeTools::GetBoundingBox(vtkTextProperty *tprop, //---------------------------------------------------------------------------- bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, - const vtkStdString &str, + const vtkStdString &str, int dpi, vtkTextRenderer::Metrics &metrics) { if (!tprop) @@ -470,7 +472,7 @@ bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, } MetaData metaData; - bool result = this->PrepareMetaData(tprop, metaData); + bool result = this->PrepareMetaData(tprop, dpi, metaData); if (result) { result = this->CalculateBoundingBox(str, metaData); @@ -488,7 +490,7 @@ bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, //---------------------------------------------------------------------------- bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, - const vtkUnicodeString &str, + const vtkUnicodeString &str, int dpi, vtkTextRenderer::Metrics &metrics) { if (!tprop) @@ -504,7 +506,7 @@ bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, } MetaData metaData; - bool result = this->PrepareMetaData(tprop, metaData); + bool result = this->PrepareMetaData(tprop, dpi, metaData); if (result) { result = this->CalculateBoundingBox(str, metaData); @@ -522,41 +524,43 @@ bool vtkFreeTypeTools::GetMetrics(vtkTextProperty *tprop, //---------------------------------------------------------------------------- bool vtkFreeTypeTools::RenderString(vtkTextProperty *tprop, - const vtkStdString& str, + const vtkStdString& str, int dpi, vtkImageData *data, int textDims[2]) { - return this->RenderStringInternal(tprop, str, data, textDims); + return this->RenderStringInternal(tprop, str, dpi, data, textDims); } //---------------------------------------------------------------------------- bool vtkFreeTypeTools::RenderString(vtkTextProperty *tprop, - const vtkUnicodeString& str, + const vtkUnicodeString& str, int dpi, vtkImageData *data, int textDims[2]) { - return this->RenderStringInternal(tprop, str, data, textDims); + return this->RenderStringInternal(tprop, str, dpi, data, textDims); } //---------------------------------------------------------------------------- bool vtkFreeTypeTools::StringToPath(vtkTextProperty *tprop, - const vtkStdString &str, vtkPath *path) + const vtkStdString &str, int dpi, + vtkPath *path) { - return this->StringToPathInternal(tprop, str, path); + return this->StringToPathInternal(tprop, str, dpi, path); } //---------------------------------------------------------------------------- bool vtkFreeTypeTools::StringToPath(vtkTextProperty *tprop, - const vtkUnicodeString &str, vtkPath *path) + const vtkUnicodeString &str, int dpi, + vtkPath *path) { - return this->StringToPathInternal(tprop, str, path); + return this->StringToPathInternal(tprop, str, dpi, path); } //---------------------------------------------------------------------------- int vtkFreeTypeTools::GetConstrainedFontSize(const vtkStdString &str, - vtkTextProperty *tprop, + vtkTextProperty *tprop, int dpi, int targetWidth, int targetHeight) { MetaData metaData; - if (!this->PrepareMetaData(tprop, metaData)) + if (!this->PrepareMetaData(tprop, dpi, metaData)) { vtkErrorMacro(<<"Could not prepare metadata."); return false; @@ -566,11 +570,11 @@ int vtkFreeTypeTools::GetConstrainedFontSize(const vtkStdString &str, //---------------------------------------------------------------------------- int vtkFreeTypeTools::GetConstrainedFontSize(const vtkUnicodeString &str, - vtkTextProperty *tprop, + vtkTextProperty *tprop, int dpi, int targetWidth, int targetHeight) { MetaData metaData; - if (!this->PrepareMetaData(tprop, metaData)) + if (!this->PrepareMetaData(tprop, dpi, metaData)) { vtkErrorMacro(<<"Could not prepare metadata."); return false; @@ -676,23 +680,12 @@ bool vtkFreeTypeTools::GetSize(unsigned long tprop_cache_id, int font_size, FT_Size *size) { -#if VTK_FTFC_DEBUG_CD - printf("vtkFreeTypeTools::GetSize()\n"); -#endif - if (!size || font_size <= 0) { vtkErrorMacro(<< "Wrong parameters, size is NULL or invalid font size"); return 0; } - FTC_Manager *manager = this->GetCacheManager(); - if (!manager) - { - vtkErrorMacro(<< "Failed querying the cache manager !"); - return 0; - } - // Map the id of a text property in the cache to a FTC_FaceID FTC_FaceID face_id = reinterpret_cast(tprop_cache_id); @@ -702,7 +695,30 @@ bool vtkFreeTypeTools::GetSize(unsigned long tprop_cache_id, scaler_rec.height = font_size; scaler_rec.pixel = 1; - FT_Error error = FTC_Manager_LookupSize(*manager, &scaler_rec, size); + return this->GetSize(&scaler_rec, size); +} + +//---------------------------------------------------------------------------- +bool vtkFreeTypeTools::GetSize(FTC_Scaler scaler, FT_Size *size) +{ +#if VTK_FTFC_DEBUG_CD + printf("vtkFreeTypeTools::GetSize()\n"); +#endif + + if (!size) + { + vtkErrorMacro(<< "Size is NULL."); + return 0; + } + + FTC_Manager *manager = this->GetCacheManager(); + if (!manager) + { + vtkErrorMacro(<< "Failed querying the cache manager !"); + return 0; + } + + FT_Error error = FTC_Manager_LookupSize(*manager, scaler, size); if (error) { vtkErrorMacro(<< "Failed looking up a FreeType Size"); @@ -876,6 +892,44 @@ bool vtkFreeTypeTools::GetGlyph(unsigned long tprop_cache_id, return error ? false : true; } +//---------------------------------------------------------------------------- +bool vtkFreeTypeTools::GetGlyph(FTC_Scaler scaler, FT_UInt gindex, + FT_Glyph *glyph, int request) +{ +#if VTK_FTFC_DEBUG_CD + printf("vtkFreeTypeTools::GetGlyph()\n"); +#endif + + if (!glyph) + { + vtkErrorMacro(<< "Wrong parameters, one of them is NULL"); + return false; + } + + FTC_ImageCache *image_cache = this->GetImageCache(); + if (!image_cache) + { + vtkErrorMacro(<< "Failed querying the image cache manager !"); + return false; + } + + FT_ULong loadFlags = FT_LOAD_DEFAULT; + if (request == GLYPH_REQUEST_BITMAP) + { + loadFlags |= FT_LOAD_RENDER; + } + else if (request == GLYPH_REQUEST_OUTLINE) + { + loadFlags |= FT_LOAD_NO_BITMAP; + } + + // Lookup the glyph + FT_Error error = FTC_ImageCache_LookupScaler( + *image_cache, scaler, loadFlags, gindex, glyph, NULL); + + return error ? false : true; +} + //---------------------------------------------------------------------------- bool vtkFreeTypeTools::LookupFace(vtkTextProperty *tprop, FT_Library lib, FT_Face *face) @@ -1078,17 +1132,30 @@ inline bool vtkFreeTypeTools::PrepareImageMetaData(vtkTextProperty *tprop, } //---------------------------------------------------------------------------- -inline bool vtkFreeTypeTools::PrepareMetaData(vtkTextProperty *tprop, +inline bool vtkFreeTypeTools::PrepareMetaData(vtkTextProperty *tprop, int dpi, MetaData &metaData) { // Text properties metaData.textProperty = tprop; - if (!this->GetFace(tprop, metaData.textPropertyCacheId, metaData.face, - metaData.faceHasKerning)) + this->MapTextPropertyToId(tprop, &metaData.textPropertyCacheId); + + metaData.scaler.face_id = + reinterpret_cast(metaData.textPropertyCacheId); + metaData.scaler.width = tprop->GetFontSize() * 64; // 26.6 format point size + metaData.scaler.height = tprop->GetFontSize() * 64; + metaData.scaler.pixel = 0; + metaData.scaler.x_res = dpi; + metaData.scaler.y_res = dpi; + + FT_Size size; + if (!this->GetSize(&metaData.scaler, &size)) { return false; } + metaData.face = size->face; + metaData.faceHasKerning = (FT_HAS_KERNING(metaData.face) != 0); + // Store an unrotated version of this font, as we'll need this to get accurate // ascenders/descenders (see CalculateBoundingBox). if (tprop->GetOrientation() != 0.0) @@ -1096,18 +1163,21 @@ inline bool vtkFreeTypeTools::PrepareMetaData(vtkTextProperty *tprop, vtkNew unrotatedTProp; unrotatedTProp->ShallowCopy(tprop); unrotatedTProp->SetOrientation(0); - FT_Face unusedFace; - bool unusedBool; - if (!this->GetFace(unrotatedTProp.GetPointer(), - metaData.unrotatedTextPropertyCacheId, - unusedFace, unusedBool)) - { - return false; - } + this->MapTextPropertyToId(unrotatedTProp.GetPointer(), + &metaData.unrotatedTextPropertyCacheId); + + metaData.unrotatedScaler.face_id = + reinterpret_cast(metaData.unrotatedTextPropertyCacheId); + metaData.unrotatedScaler.width = tprop->GetFontSize() * 64; // 26.6 format point size + metaData.unrotatedScaler.height = tprop->GetFontSize() * 64; + metaData.unrotatedScaler.pixel = 0; + metaData.unrotatedScaler.x_res = dpi; + metaData.unrotatedScaler.y_res = dpi; } else { metaData.unrotatedTextPropertyCacheId = metaData.textPropertyCacheId; + metaData.unrotatedScaler = metaData.scaler; } // Rotation matrices: @@ -1141,6 +1211,7 @@ inline bool vtkFreeTypeTools::PrepareMetaData(vtkTextProperty *tprop, template bool vtkFreeTypeTools::RenderStringInternal(vtkTextProperty *tprop, const StringType &str, + int dpi, vtkImageData *data, int textDims[2]) { @@ -1160,7 +1231,7 @@ bool vtkFreeTypeTools::RenderStringInternal(vtkTextProperty *tprop, ImageMetaData metaData; // Setup the metadata cache - if (!this->PrepareMetaData(tprop, metaData)) + if (!this->PrepareMetaData(tprop, dpi, metaData)) { vtkErrorMacro(<<"Error prepare text metadata."); return false; @@ -1262,11 +1333,12 @@ bool vtkFreeTypeTools::RenderStringInternal(vtkTextProperty *tprop, template bool vtkFreeTypeTools::StringToPathInternal(vtkTextProperty *tprop, const StringType &str, + int dpi, vtkPath *path) { // Setup the metadata MetaData metaData; - if (!this->PrepareMetaData(tprop, metaData)) + if (!this->PrepareMetaData(tprop, dpi, metaData)) { vtkErrorMacro(<<"Could not prepare metadata."); return false; @@ -1327,7 +1399,6 @@ bool vtkFreeTypeTools::CalculateBoundingBox(const T& str, // face values are usually way too big. This is the same string used to // determine height in vtkFreeTypeUtilities. const char *heightString = "_/7Agfy"; - int fontSize = metaData.textProperty->GetFontSize(); metaData.ascent = 0; metaData.descent = 0; while (*heightString) @@ -1336,12 +1407,12 @@ bool vtkFreeTypeTools::CalculateBoundingBox(const T& str, FT_UInt glyphIndex; // Use the unrotated face to get correct metrics: FT_Bitmap *bitmap = this->GetBitmap( - *heightString, metaData.unrotatedTextPropertyCacheId, fontSize, - glyphIndex, bitmapGlyph); + *heightString, &metaData.unrotatedScaler, glyphIndex, bitmapGlyph); if (bitmap) { metaData.ascent = std::max(bitmapGlyph->top - 1, metaData.ascent); - metaData.descent = std::min(-static_cast((bitmap->rows - (bitmapGlyph->top - 1))), + metaData.descent = std::min(-static_cast((bitmap->rows - + (bitmapGlyph->top - 1))), metaData.descent); } ++heightString; @@ -1810,8 +1881,7 @@ bool vtkFreeTypeTools::RenderCharacter(CharType character, int &x, int &y, ImageMetaData *iMetaData = reinterpret_cast(&metaData); FT_BitmapGlyph bitmapGlyph; FT_UInt glyphIndex; - FT_Bitmap *bitmap = this->GetBitmap(character, iMetaData->textPropertyCacheId, - iMetaData->textProperty->GetFontSize(), + FT_Bitmap *bitmap = this->GetBitmap(character, &iMetaData->scaler, glyphIndex, bitmapGlyph); if (!bitmap) @@ -1937,9 +2007,7 @@ bool vtkFreeTypeTools::RenderCharacter(CharType character, int &x, int &y, FT_UInt glyphIndex; FT_OutlineGlyph outlineGlyph; - FT_Outline *outline = this->GetOutline(character, - metaData.textPropertyCacheId, - metaData.textProperty->GetFontSize(), + FT_Outline *outline = this->GetOutline(character, &metaData.scaler, glyphIndex, outlineGlyph); if (!outline) { @@ -2174,6 +2242,10 @@ int vtkFreeTypeTools::FitStringToBBox(const T &str, MetaData &metaData, static_cast(targetWidth) / static_cast(size[0]), static_cast(targetHeight) / static_cast(size[1])); metaData.textProperty->SetFontSize(static_cast(fontSize)); + metaData.scaler.height = fontSize * 64; // 26.6 format points + metaData.scaler.width = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.height = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.width = fontSize * 64; // 26.6 format points if (!this->CalculateBoundingBox(str, metaData)) { return -1; @@ -2187,6 +2259,10 @@ int vtkFreeTypeTools::FitStringToBBox(const T &str, MetaData &metaData, { fontSize += 1.; metaData.textProperty->SetFontSize(fontSize); + metaData.scaler.height = fontSize * 64; // 26.6 format points + metaData.scaler.width = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.height = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.width = fontSize * 64; // 26.6 format points if (!this->CalculateBoundingBox(str, metaData)) { return -1; @@ -2199,6 +2275,10 @@ int vtkFreeTypeTools::FitStringToBBox(const T &str, MetaData &metaData, { fontSize -= 1.; metaData.textProperty->SetFontSize(fontSize); + metaData.scaler.height = fontSize * 64; // 26.6 format points + metaData.scaler.width = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.height = fontSize * 64; // 26.6 format points + metaData.unrotatedScaler.width = fontSize * 64; // 26.6 format points if (!this->CalculateBoundingBox(str, metaData)) { return -1; @@ -2260,6 +2340,38 @@ inline FT_Bitmap* vtkFreeTypeTools::GetBitmap(FT_UInt32 c, return bitmap; } +//---------------------------------------------------------------------------- +FT_Bitmap *vtkFreeTypeTools::GetBitmap(FT_UInt32 c, FTC_Scaler scaler, + FT_UInt &gindex, + FT_BitmapGlyph &bitmap_glyph) +{ + // Get the glyph index + if (!this->GetGlyphIndex(reinterpret_cast(scaler->face_id), c, + &gindex)) + { + return 0; + } + + // Get the glyph as a bitmap + FT_Glyph glyph; + if (!this->GetGlyph(scaler, gindex, &glyph, + vtkFreeTypeTools::GLYPH_REQUEST_BITMAP) + || glyph->format != ft_glyph_format_bitmap) + { + return 0; + } + + bitmap_glyph = reinterpret_cast(glyph); + FT_Bitmap *bitmap = &bitmap_glyph->bitmap; + + if (bitmap->pixel_mode != ft_pixel_mode_grays) + { + return 0; + } + + return bitmap; +} + //---------------------------------------------------------------------------- inline FT_Outline *vtkFreeTypeTools::GetOutline(FT_UInt32 c, unsigned long prop_cache_id, @@ -2290,6 +2402,33 @@ inline FT_Outline *vtkFreeTypeTools::GetOutline(FT_UInt32 c, return outline; } +//---------------------------------------------------------------------------- +FT_Outline *vtkFreeTypeTools::GetOutline(FT_UInt32 c, FTC_Scaler scaler, + FT_UInt &gindex, + FT_OutlineGlyph &outline_glyph) +{ + // Get the glyph index + if (!this->GetGlyphIndex(reinterpret_cast(scaler->face_id), c, + &gindex)) + { + return 0; + } + + // Get the glyph as a outline + FT_Glyph glyph; + if (!this->GetGlyph(scaler, gindex, &glyph, + vtkFreeTypeTools::GLYPH_REQUEST_OUTLINE) + || glyph->format != ft_glyph_format_outline) + { + return 0; + } + + outline_glyph = reinterpret_cast(glyph); + FT_Outline *outline= &outline_glyph->outline; + + return outline; +} + //---------------------------------------------------------------------------- template void vtkFreeTypeTools::GetLineMetrics(T begin, T end, MetaData &metaData, @@ -2303,7 +2442,7 @@ void vtkFreeTypeTools::GetLineMetrics(T begin, T end, MetaData &metaData, int pen[2] = {0, 0}; bbox[0] = bbox[1] = pen[0]; bbox[2] = bbox[3] = pen[1]; - int fontSize = metaData.textProperty->GetFontSize(); + for (; begin != end; ++begin) { // Adjust the pen location for kerning @@ -2326,8 +2465,8 @@ void vtkFreeTypeTools::GetLineMetrics(T begin, T end, MetaData &metaData, } // Use the dimensions of the bitmap glyph to get a tight bounding box. - FT_Bitmap *bitmap = this->GetBitmap(*begin, metaData.textPropertyCacheId, - fontSize, gindex, bitmapGlyph); + FT_Bitmap *bitmap = this->GetBitmap(*begin, &metaData.scaler, gindex, + bitmapGlyph); if (bitmap) { bbox[0] = std::min(bbox[0], pen[0] + bitmapGlyph->left); diff --git a/Rendering/FreeType/vtkFreeTypeTools.h b/Rendering/FreeType/vtkFreeTypeTools.h index 6541e3cc4fe..2b9c0c68026 100644 --- a/Rendering/FreeType/vtkFreeTypeTools.h +++ b/Rendering/FreeType/vtkFreeTypeTools.h @@ -100,16 +100,16 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject // Returns true on success, false otherwise. // @sa GetMetrics bool GetBoundingBox(vtkTextProperty *tprop, const vtkStdString& str, - int bbox[4]); + int dpi, int bbox[4]); bool GetBoundingBox(vtkTextProperty *tprop, const vtkUnicodeString& str, - int bbox[4]); + int dpi, int bbox[4]); // Description: // Given a text property and a string, get the metrics of the rendered string. // Returns true on success, false otherwise. - bool GetMetrics(vtkTextProperty *tprop, const vtkStdString& str, + bool GetMetrics(vtkTextProperty *tprop, const vtkStdString& str, int dpi, vtkTextRenderer::Metrics &metrics); - bool GetMetrics(vtkTextProperty *tprop, const vtkUnicodeString& str, + bool GetMetrics(vtkTextProperty *tprop, const vtkUnicodeString& str, int dpi, vtkTextRenderer::Metrics &metrics); // Description: @@ -121,29 +121,29 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject // The origin of the image's extents is aligned with the anchor point // described by the text property's vertical and horizontal justification // options. - bool RenderString(vtkTextProperty *tprop, const vtkStdString& str, + bool RenderString(vtkTextProperty *tprop, const vtkStdString& str, int dpi, vtkImageData *data, int textDims[2] = NULL); bool RenderString(vtkTextProperty *tprop, const vtkUnicodeString& str, - vtkImageData *data, int textDims[2] = NULL); + int dpi, vtkImageData *data, int textDims[2] = NULL); // Description: // Given a text property and a string, this function populates the vtkPath // path with the outline of the rendered string. The origin of the path // coordinates is aligned with the anchor point described by the text // property's horizontal and vertical justification options. - bool StringToPath(vtkTextProperty *tprop, const vtkStdString& str, + bool StringToPath(vtkTextProperty *tprop, const vtkStdString& str, int dpi, vtkPath *path); bool StringToPath(vtkTextProperty *tprop, const vtkUnicodeString& str, - vtkPath *path); + int dpi, vtkPath *path); // Description: // This function returns the font size (in points) required to fit the string // in the target rectangle. The font size of tprop is updated to the computed // value as well. If an error occurs, -1 is returned. int GetConstrainedFontSize(const vtkStdString &str, vtkTextProperty *tprop, - int targetWidth, int targetHeight); + int dpi, int targetWidth, int targetHeight); int GetConstrainedFontSize(const vtkUnicodeString &str, - vtkTextProperty *tprop, + vtkTextProperty *tprop, int dpi, int targetWidth, int targetHeight); // Description: @@ -196,7 +196,7 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject // Used to store state about a particular rendering and cache constant values class MetaData; class ImageMetaData; - bool PrepareMetaData(vtkTextProperty *tprop, MetaData &metaData); + bool PrepareMetaData(vtkTextProperty *tprop, int dpi, MetaData &metaData); bool PrepareImageMetaData(vtkTextProperty *tprop, vtkImageData *image, ImageMetaData &metaData); @@ -253,6 +253,7 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject FT_Glyph *glyph, int request = GLYPH_REQUEST_DEFAULT); bool GetSize(unsigned long tprop_cache_id, int font_size, FT_Size *size); + bool GetSize(FTC_Scaler scaler, FT_Size *size); bool GetFace(unsigned long tprop_cache_id, FT_Face *face); bool GetGlyphIndex(unsigned long tprop_cache_id, FT_UInt32 c, FT_UInt *gindex); @@ -261,6 +262,10 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject FT_UInt gindex, FT_Glyph *glyph, int request = GLYPH_REQUEST_DEFAULT); + bool GetGlyph(FTC_Scaler scaler, + FT_UInt gindex, + FT_Glyph *glyph, + int request = GLYPH_REQUEST_DEFAULT); // Description: // Should the image be scaled to the next highest power of 2? @@ -279,12 +284,16 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject FT_Bitmap* GetBitmap(FT_UInt32 c, unsigned long prop_cache_id, int prop_font_size, FT_UInt &gindex, FT_BitmapGlyph &bitmap_glyph); + FT_Bitmap* GetBitmap(FT_UInt32 c, FTC_Scaler scaler, FT_UInt &gindex, + FT_BitmapGlyph &bitmap_glyph); // Description: // Attempt to get the outline for the specified character. FT_Outline* GetOutline(FT_UInt32 c, unsigned long prop_cache_id, int prop_font_size, FT_UInt &gindex, FT_OutlineGlyph &outline_glyph); + FT_Outline* GetOutline(FT_UInt32 c, FTC_Scaler scaler, FT_UInt &gindex, + FT_OutlineGlyph &outline_glyph); // Description: // The singleton instance and the singleton cleanup instance @@ -325,13 +334,13 @@ class VTKRENDERINGFREETYPE_EXPORT vtkFreeTypeTools : public vtkObject // Internal helper called by RenderString methods template bool RenderStringInternal(vtkTextProperty *tprop, const StringType &str, - vtkImageData *data, int textDims[2]); + int dpi, vtkImageData *data, int textDims[2]); // Description: // Internal helper method called by StringToPath methods template bool StringToPathInternal(vtkTextProperty *tprop, const StringType &str, - vtkPath *path); + int dpi, vtkPath *path); // Description: // This function initializes calculates the size of the required bounding box diff --git a/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.cxx b/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.cxx index e0aa10248a6..177fdfa8109 100644 --- a/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.cxx +++ b/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.cxx @@ -97,7 +97,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetBoundingBoxInternal( this->CleanUpFreeTypeEscapes(cleanString); // Interpret string as UTF-8, use the UTF-16 GetBoundingBox overload: return this->FreeTypeTools->GetBoundingBox( - tprop, vtkUnicodeString::from_utf8(cleanString), bbox); + tprop, vtkUnicodeString::from_utf8(cleanString), dpi, bbox); } case Default: case UserBackend: @@ -156,7 +156,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetBoundingBoxInternal( { vtkUnicodeString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); - return this->FreeTypeTools->GetBoundingBox(tprop, cleanString, bbox); + return this->FreeTypeTools->GetBoundingBox(tprop, cleanString, dpi, bbox); } case Default: case UserBackend: @@ -216,7 +216,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetMetricsInternal( this->CleanUpFreeTypeEscapes(cleanString); // Interpret string as UTF-8, use the UTF-16 GetBoundingBox overload: return this->FreeTypeTools->GetMetrics( - tprop, vtkUnicodeString::from_utf8(cleanString), metrics); + tprop, vtkUnicodeString::from_utf8(cleanString), dpi, metrics); } case Default: case UserBackend: @@ -275,7 +275,7 @@ bool vtkMathTextFreeTypeTextRenderer::GetMetricsInternal( { vtkUnicodeString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); - return this->FreeTypeTools->GetMetrics(tprop, cleanString, metrics); + return this->FreeTypeTools->GetMetrics(tprop, cleanString, dpi, metrics); } case Default: case UserBackend: @@ -329,7 +329,8 @@ bool vtkMathTextFreeTypeTextRenderer::RenderStringInternal( this->CleanUpFreeTypeEscapes(cleanString); // Interpret string as UTF-8, use the UTF-16 RenderString overload: return this->FreeTypeTools->RenderString( - tprop, vtkUnicodeString::from_utf8(cleanString), data, textDims); + tprop, vtkUnicodeString::from_utf8(cleanString), dpi, data, + textDims); } case Default: case UserBackend: @@ -382,7 +383,7 @@ bool vtkMathTextFreeTypeTextRenderer::RenderStringInternal( { vtkUnicodeString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); - return this->FreeTypeTools->RenderString(tprop, cleanString, data, + return this->FreeTypeTools->RenderString(tprop, cleanString, dpi, data, textDims); } case Default: @@ -438,7 +439,7 @@ int vtkMathTextFreeTypeTextRenderer::GetConstrainedFontSizeInternal( vtkStdString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); return this->FreeTypeTools->GetConstrainedFontSize(cleanString, tprop, - targetWidth, + dpi, targetWidth, targetHeight); } case Default: @@ -495,7 +496,7 @@ int vtkMathTextFreeTypeTextRenderer::GetConstrainedFontSizeInternal( vtkUnicodeString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); return this->FreeTypeTools->GetConstrainedFontSize(cleanString, tprop, - targetWidth, + dpi, targetWidth, targetHeight); } case Default: @@ -512,7 +513,8 @@ int vtkMathTextFreeTypeTextRenderer::GetConstrainedFontSizeInternal( //------------------------------------------------------------------------------ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( - vtkTextProperty *tprop, const vtkStdString &str, vtkPath *path, int backend) + vtkTextProperty *tprop, const vtkStdString &str, vtkPath *path, int dpi, + int backend) { if (!path || !tprop) { @@ -535,7 +537,8 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( case MathText: if (this->HasMathText) { - if (this->MathTextUtilities->StringToPath(str.c_str(), path, tprop)) + if (this->MathTextUtilities->StringToPath(str.c_str(), path, tprop, + dpi)) { return true; } @@ -546,7 +549,7 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( { vtkStdString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); - return this->FreeTypeTools->StringToPath(tprop, str, path); + return this->FreeTypeTools->StringToPath(tprop, str, dpi, path); } case Default: case UserBackend: @@ -562,7 +565,7 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( //------------------------------------------------------------------------------ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( - vtkTextProperty *tprop, const vtkUnicodeString &str, vtkPath *path, + vtkTextProperty *tprop, const vtkUnicodeString &str, vtkPath *path, int dpi, int backend) { if (!path || !tprop) @@ -587,7 +590,8 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( if (this->HasMathText) { vtkDebugMacro("Converting UTF16 to UTF8 for MathText rendering."); - if (this->MathTextUtilities->StringToPath(str.utf8_str(), path, tprop)) + if (this->MathTextUtilities->StringToPath(str.utf8_str(), path, tprop, + dpi)) { return true; } @@ -598,7 +602,7 @@ bool vtkMathTextFreeTypeTextRenderer::StringToPathInternal( { vtkUnicodeString cleanString(str); this->CleanUpFreeTypeEscapes(cleanString); - return this->FreeTypeTools->StringToPath(tprop, str, path); + return this->FreeTypeTools->StringToPath(tprop, str, dpi, path); } case Default: case UserBackend: diff --git a/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.h b/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.h index bab01f368d6..426366350d0 100644 --- a/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.h +++ b/Rendering/FreeType/vtkMathTextFreeTypeTextRenderer.h @@ -73,9 +73,9 @@ class VTKRENDERINGFREETYPE_EXPORT vtkMathTextFreeTypeTextRenderer : int targetWidth, int targetHeight, int dpi, int backend); bool StringToPathInternal(vtkTextProperty *tprop, const vtkStdString &str, - vtkPath *path, int backend); + vtkPath *path, int dpi, int backend); bool StringToPathInternal(vtkTextProperty *tprop, const vtkUnicodeString &str, - vtkPath *path, int backend); + vtkPath *path, int dpi, int backend); void SetScaleToPowerOfTwoInternal(bool scale); private: diff --git a/Rendering/FreeType/vtkMathTextUtilities.cxx b/Rendering/FreeType/vtkMathTextUtilities.cxx index f441f392aac..c1b39e22ace 100644 --- a/Rendering/FreeType/vtkMathTextUtilities.cxx +++ b/Rendering/FreeType/vtkMathTextUtilities.cxx @@ -95,7 +95,7 @@ int vtkMathTextUtilities::GetConstrainedFontSize(const char *str, vtkTextProperty *tprop, int targetWidth, int targetHeight, - unsigned int dpi) + int dpi) { if (str == NULL || str[0] == '\0' || targetWidth == 0 || targetHeight == 0 || tprop == NULL) diff --git a/Rendering/FreeType/vtkMathTextUtilities.h b/Rendering/FreeType/vtkMathTextUtilities.h index e2abc462733..979c26d2810 100644 --- a/Rendering/FreeType/vtkMathTextUtilities.h +++ b/Rendering/FreeType/vtkMathTextUtilities.h @@ -72,13 +72,12 @@ class VTKRENDERINGFREETYPE_EXPORT vtkMathTextUtilities : public vtkObject // Description: // Determine the dimensions of the image that RenderString will produce for // a given str, tprop, and dpi - virtual bool GetBoundingBox(vtkTextProperty *tprop, const char *str, - unsigned int dpi, int bbox[4]) = 0; + virtual bool GetBoundingBox(vtkTextProperty *tprop, const char *str, int dpi, + int bbox[4]) = 0; // Description: // Return the metrics for the rendered str, tprop, and dpi. - virtual bool GetMetrics(vtkTextProperty *tprop, const char *str, - unsigned int dpi, + virtual bool GetMetrics(vtkTextProperty *tprop, const char *str, int dpi, vtkTextRenderer::Metrics &metrics) = 0; // Description: @@ -88,14 +87,14 @@ class VTKRENDERINGFREETYPE_EXPORT vtkMathTextUtilities : public vtkObject // set to true, and the image dimensions may not match the dimensions of the // rendered text. virtual bool RenderString(const char *str, vtkImageData *data, - vtkTextProperty *tprop, - unsigned int dpi, int textDims[2] = NULL) = 0; + vtkTextProperty *tprop, int dpi, + int textDims[2] = NULL) = 0; // Description: // Parse the MathText expression in str and fill path with a contour of the // glyphs. virtual bool StringToPath(const char *str, vtkPath *path, - vtkTextProperty *tprop) = 0; + vtkTextProperty *tprop, int dpi) = 0; // Description: // This function returns the font size (in points) required to fit the string @@ -105,7 +104,7 @@ class VTKRENDERINGFREETYPE_EXPORT vtkMathTextUtilities : public vtkObject virtual int GetConstrainedFontSize(const char *str, vtkTextProperty *tprop, int targetWidth, int targetHeight, - unsigned int dpi); + int dpi); // Description: // Set to true if the graphics implmentation requires texture image dimensions diff --git a/Rendering/FreeType/vtkTextRendererStringToImage.cxx b/Rendering/FreeType/vtkTextRendererStringToImage.cxx index 23808f9f5cb..cdf91daa702 100644 --- a/Rendering/FreeType/vtkTextRendererStringToImage.cxx +++ b/Rendering/FreeType/vtkTextRendererStringToImage.cxx @@ -50,7 +50,7 @@ vtkTextRendererStringToImage::~vtkTextRendererStringToImage() //----------------------------------------------------------------------------- vtkVector2i vtkTextRendererStringToImage::GetBounds( - vtkTextProperty *property, const vtkUnicodeString& string) + vtkTextProperty *property, const vtkUnicodeString& string, int dpi) { int tmp[4] = { 0, 0, 0, 0 }; vtkVector2i recti(tmp); @@ -59,7 +59,8 @@ vtkVector2i vtkTextRendererStringToImage::GetBounds( return recti; } - this->Implementation->TextRenderer->GetBoundingBox(property, string, tmp); + this->Implementation->TextRenderer->GetBoundingBox(property, string, tmp, + dpi); recti.Set(tmp[1] - tmp[0], tmp[3] - tmp[2]); @@ -69,7 +70,8 @@ vtkVector2i vtkTextRendererStringToImage::GetBounds( //----------------------------------------------------------------------------- vtkVector2i vtkTextRendererStringToImage::GetBounds(vtkTextProperty *property, - const vtkStdString& string) + const vtkStdString& string, + int dpi) { vtkVector2i recti(0, 0); int tmp[4]; @@ -78,7 +80,8 @@ vtkVector2i vtkTextRendererStringToImage::GetBounds(vtkTextProperty *property, return recti; } - this->Implementation->TextRenderer->GetBoundingBox(property, string, tmp); + this->Implementation->TextRenderer->GetBoundingBox(property, string, tmp, + dpi); recti.Set(tmp[1] - tmp[0], tmp[3] - tmp[2]); @@ -88,34 +91,20 @@ vtkVector2i vtkTextRendererStringToImage::GetBounds(vtkTextProperty *property, //----------------------------------------------------------------------------- int vtkTextRendererStringToImage::RenderString( - vtkTextProperty *property, const vtkUnicodeString& string, + vtkTextProperty *property, const vtkUnicodeString& string, int dpi, vtkImageData *data, int textDims[2]) { - // Get the required size, and initialize a new QImage to draw on. - vtkVector2i box = this->GetBounds(property, string); - if (box.GetX() == 0 || box.GetY() == 0) - { - return 0; - } - return this->Implementation->TextRenderer->RenderString(property, string, - data, textDims); + data, textDims, dpi); } //----------------------------------------------------------------------------- int vtkTextRendererStringToImage::RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int textDims[2]) { - // Get the required size, and initialize a new QImage to draw on. - vtkVector2i box = this->GetBounds(property, string); - if (box.GetX() == 0 || box.GetY() == 0) - { - return 0; - } - return this->Implementation->TextRenderer->RenderString(property, string, - data, textDims); + data, textDims, dpi); } //----------------------------------------------------------------------------- diff --git a/Rendering/FreeType/vtkTextRendererStringToImage.h b/Rendering/FreeType/vtkTextRendererStringToImage.h index 845b7a70ccc..cd4f832430e 100644 --- a/Rendering/FreeType/vtkTextRendererStringToImage.h +++ b/Rendering/FreeType/vtkTextRendererStringToImage.h @@ -44,9 +44,11 @@ class VTKRENDERINGFREETYPE_EXPORT vtkTextRendererStringToImage : // is valid (it may not if GetBoundingBox() failed or if the string // was empty). virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string); + const vtkUnicodeString& string, + int dpi); virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkStdString& string); + const vtkStdString& string, + int dpi); // Description: // Given a text property and a string, this function initializes the @@ -56,10 +58,12 @@ class VTKRENDERINGFREETYPE_EXPORT vtkTextRendererStringToImage : // not match the dimensions of the rendered text. virtual int RenderString(vtkTextProperty *property, const vtkUnicodeString& string, + int dpi, vtkImageData *data, int textDims[2] = NULL); virtual int RenderString(vtkTextProperty *property, const vtkStdString& string, + int dpi, vtkImageData *data, int textDims[2] = NULL); diff --git a/Rendering/GL2PS/vtkGL2PSContextDevice2D.cxx b/Rendering/GL2PS/vtkGL2PSContextDevice2D.cxx index 5f13bdcd3bf..4111130394c 100644 --- a/Rendering/GL2PS/vtkGL2PSContextDevice2D.cxx +++ b/Rendering/GL2PS/vtkGL2PSContextDevice2D.cxx @@ -249,11 +249,10 @@ void vtkGL2PSContextDevice2D::DrawMathTextString(float apoint[], { vtkNew path; bool ok; - if (vtkMathTextUtilities::GetInstance()) + if (vtkMathTextUtilities *mtu = vtkMathTextUtilities::GetInstance()) { - ok = vtkMathTextUtilities::GetInstance()->StringToPath(string.c_str(), - path.GetPointer(), - this->TextProp); + ok = mtu->StringToPath(string.c_str(), path.GetPointer(), this->TextProp, + this->RenderWindow->GetDPI()); } else { diff --git a/Rendering/GL2PS/vtkGL2PSUtilities.cxx b/Rendering/GL2PS/vtkGL2PSUtilities.cxx index 73e15a001f0..6b49e9c19ed 100644 --- a/Rendering/GL2PS/vtkGL2PSUtilities.cxx +++ b/Rendering/GL2PS/vtkGL2PSUtilities.cxx @@ -59,11 +59,13 @@ void vtkGL2PSUtilities::DrawString(const char *str, return; } + int dpi = vtkGL2PSUtilities::RenderWindow->GetDPI(); + // Draw the background if needed: if (tprop->GetBackgroundOpacity() > 0.) { vtkTextRenderer::Metrics metrics; - if (tren->GetMetrics(tprop, str, metrics)) + if (tren->GetMetrics(tprop, str, metrics, dpi)) { double bgPos[3] = { pos[0], pos[1], backgroundDepth }; vtkGL2PSUtilities::ProjectPoint(bgPos); @@ -106,7 +108,8 @@ void vtkGL2PSUtilities::DrawString(const char *str, GLfloat angle = static_cast(tprop->GetOrientation()); - GLint fontSize = static_cast(tprop->GetFontSize()); + // GL2PS assumes 72 DPI, so we'll have to adjust the font size: + GLint fontSize = static_cast(tprop->GetFontSize() * (dpi / 72.)); GL2PSrgba rgba; double rgbad[3]; @@ -123,7 +126,7 @@ void vtkGL2PSUtilities::DrawString(const char *str, { // Render the string to a path and then draw it to GL2PS: vtkNew path; - tren->StringToPath(tprop, str, path.GetPointer()); + tren->StringToPath(tprop, str, path.GetPointer(), dpi); // Get color double rgbd[3]; tprop->GetColor(rgbd[0], rgbd[1], rgbd[2]); diff --git a/Rendering/Label/vtkFreeTypeLabelRenderStrategy.cxx b/Rendering/Label/vtkFreeTypeLabelRenderStrategy.cxx index 22a9c67235a..31e8ee4f450 100644 --- a/Rendering/Label/vtkFreeTypeLabelRenderStrategy.cxx +++ b/Rendering/Label/vtkFreeTypeLabelRenderStrategy.cxx @@ -22,6 +22,7 @@ #include "vtkTextProperty.h" #include "vtkTextRenderer.h" #include "vtkTimerLog.h" +#include "vtkWindow.h" vtkStandardNewMacro(vtkFreeTypeLabelRenderStrategy); @@ -78,8 +79,19 @@ void vtkFreeTypeLabelRenderStrategy::ComputeLabelBounds( copy->ShallowCopy(tprop); copy->SetOrientation(0.0); } + + int dpi = 72; + if (this->Renderer && this->Renderer->GetVTKWindow()) + { + dpi = this->Renderer->GetVTKWindow()->GetDPI(); + } + else + { + vtkWarningMacro(<<"No Renderer set. Assuming DPI of " << dpi << "."); + } + int bbox[4]; - this->TextRenderer->GetBoundingBox(copy, label.utf8_str(), bbox); + this->TextRenderer->GetBoundingBox(copy, label.utf8_str(), bbox, dpi); // Take line offset into account bds[0] = bbox[0]; diff --git a/Rendering/Matplotlib/Testing/Cxx/CMakeLists.txt b/Rendering/Matplotlib/Testing/Cxx/CMakeLists.txt index 385b3ae9020..0d6f38fd51b 100644 --- a/Rendering/Matplotlib/Testing/Cxx/CMakeLists.txt +++ b/Rendering/Matplotlib/Testing/Cxx/CMakeLists.txt @@ -21,7 +21,9 @@ if(MATPLOTLIB_FOUND) ) if(VTK_GHOSTSCRIPT_EXECUTABLE) + set(TestGL2PSFontDPIScaling_ARGS DATA{../Data/Fonts/DejaVuSans.ttf}) vtk_add_test_cxx(${vtk-module}CxxTests GL2PSTests + TestGL2PSFontDPIScaling.cxx TestGL2PSMathTextActor.cxx TestGL2PSMathTextActor3D.cxx TestGL2PSMathTextOutput.cxx diff --git a/Rendering/Matplotlib/Testing/Cxx/TestGL2PSFontDPIScaling.cxx b/Rendering/Matplotlib/Testing/Cxx/TestGL2PSFontDPIScaling.cxx new file mode 100644 index 00000000000..7b2e929f248 --- /dev/null +++ b/Rendering/Matplotlib/Testing/Cxx/TestGL2PSFontDPIScaling.cxx @@ -0,0 +1,244 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestMathTextFreeTypeTextRenderer.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 "vtkTextRenderer.h" + +#include "vtkGL2PSExporter.h" +#include "vtkNew.h" +#include "vtkRenderer.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkStdString.h" +#include "vtkTestingInteractor.h" +#include "vtkTextActor.h" +#include "vtkTextProperty.h" + +#include +#include + +//---------------------------------------------------------------------------- +int TestGL2PSFontDPIScaling(int argc, char *argv[]) +{ + if (argc < 2) + { + cerr << "Missing font filename." << endl; + return EXIT_FAILURE; + } + + std::string uncodeFontFile(argv[1]); + + vtkStdString str = "Sample multiline\ntext rendered\nusing FreeTypeTools."; + + vtkNew actor1; + actor1->GetTextProperty()->SetFontSize(20); + actor1->GetTextProperty()->SetColor(1.0, 0.0, 0.0); + actor1->GetTextProperty()->SetJustificationToLeft(); + actor1->GetTextProperty()->SetVerticalJustificationToTop(); + actor1->GetTextProperty()->SetFontFamilyToTimes(); + actor1->SetInput(str.c_str()); + actor1->SetPosition(10, 590); + + vtkNew actor2; + actor2->GetTextProperty()->SetFontSize(20); + actor2->GetTextProperty()->SetColor(0.0, 1.0, 0.0); + actor2->GetTextProperty()->SetJustificationToRight(); + actor2->GetTextProperty()->SetVerticalJustificationToTop(); + actor2->GetTextProperty()->SetFontFamilyToCourier(); + actor2->SetInput(str.c_str()); + actor2->SetPosition(590, 590); + + vtkNew actor3; + actor3->GetTextProperty()->SetFontSize(20); + actor3->GetTextProperty()->SetColor(0.0, 0.0, 1.0); + actor3->GetTextProperty()->SetJustificationToLeft(); + actor3->GetTextProperty()->SetVerticalJustificationToBottom(); + actor3->GetTextProperty()->SetItalic(1); + actor3->SetInput(str.c_str()); + actor3->SetPosition(10, 10); + + vtkNew actor4; + actor4->GetTextProperty()->SetFontSize(20); + actor4->GetTextProperty()->SetColor(0.3, 0.4, 0.5); + actor4->GetTextProperty()->SetJustificationToRight(); + actor4->GetTextProperty()->SetVerticalJustificationToBottom(); + actor4->GetTextProperty()->SetBold(1); + actor4->GetTextProperty()->SetShadow(1); + actor4->GetTextProperty()->SetShadowOffset(-3, 2); + actor4->SetInput(str.c_str()); + actor4->SetPosition(590, 10); + + vtkNew actor5; + actor5->GetTextProperty()->SetFontSize(20); + actor5->GetTextProperty()->SetColor(1.0, 1.0, 0.0); + actor5->GetTextProperty()->SetJustificationToCentered(); + actor5->GetTextProperty()->SetVerticalJustificationToCentered(); + actor5->GetTextProperty()->SetBold(1); + actor5->GetTextProperty()->SetItalic(1); + actor5->GetTextProperty()->SetShadow(1); + actor5->GetTextProperty()->SetShadowOffset(5, -8); + actor5->SetInput(str.c_str()); + actor5->SetPosition(300, 300); + + vtkNew actor6; + actor6->GetTextProperty()->SetFontSize(16); + actor6->GetTextProperty()->SetColor(1.0, 0.5, 0.2); + actor6->GetTextProperty()->SetJustificationToCentered(); + actor6->GetTextProperty()->SetVerticalJustificationToCentered(); + actor6->GetTextProperty()->SetOrientation(45); + actor6->SetInput(str.c_str()); + actor6->SetPosition(300, 450); + + vtkNew actor7; + actor7->GetTextProperty()->SetFontSize(16); + actor7->GetTextProperty()->SetColor(0.5, 0.2, 1.0); + actor7->GetTextProperty()->SetJustificationToLeft(); + actor7->GetTextProperty()->SetVerticalJustificationToCentered(); + actor7->GetTextProperty()->SetOrientation(45); + actor7->SetInput(str.c_str()); + actor7->SetPosition(100, 156); + + vtkNew actor8; + actor8->GetTextProperty()->SetFontSize(16); + actor8->GetTextProperty()->SetColor(0.8, 1.0, 0.3); + actor8->GetTextProperty()->SetJustificationToRight(); + actor8->GetTextProperty()->SetVerticalJustificationToCentered(); + actor8->GetTextProperty()->SetOrientation(45); + actor8->SetInput(str.c_str()); + actor8->SetPosition(500, 249); + + // Mathtext tests + + // Test that escaped "$" are passed through to freetype: + vtkNew actor9; + actor9->GetTextProperty()->SetFontSize(12); + actor9->GetTextProperty()->SetColor(0.2, 0.5, 1.0); + actor9->SetInput("Escaped dollar signs:\n\\$10, \\$20"); + actor9->SetPosition(100, 450); + + vtkNew actor10; + actor10->GetTextProperty()->SetFontSize(16); + actor10->GetTextProperty()->SetColor(0.5, 0.2, 1.0); + actor10->GetTextProperty()->SetJustificationToRight(); + actor10->GetTextProperty()->SetOrientation(45); + actor10->SetInput("Test MathText $\\int_0^\\infty\\frac{2\\pi}" + "{x - \\frac{z}{4}}\\,dx$"); + actor10->SetPosition(588, 433); + + // Invalid latex markup -- should fallback to freetype. + vtkNew actor11; + actor11->GetTextProperty()->SetFontSize(15); + actor11->GetTextProperty()->SetColor(1.0, 0.5, 0.2); + actor11->SetInput("Test FreeType fallback:\n$\\asdf$"); + actor11->SetPosition(10, 350); + + // Both $...$ and \\$ + vtkNew actor12; + actor12->GetTextProperty()->SetFontSize(18); + actor12->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + actor12->SetInput("Test MathText '\\$' $\\$\\sqrt[3]{8}$"); + actor12->SetPosition(10, 300); + + // $...$ without other text. + vtkNew actor13; + actor13->GetTextProperty()->SetFontSize(18); + actor13->GetTextProperty()->SetColor(0.2, 1.0, 1.0); + actor13->SetInput("$A = \\pi r^2$"); + actor13->SetPosition(10, 250); + + // Numbers, using courier, Text that gets 'cut off' + vtkNew actor14; + actor14->GetTextProperty()->SetFontSize(21); + actor14->GetTextProperty()->SetColor(1.0, 0.0, 0.0); + actor14->GetTextProperty()->SetJustificationToCentered(); + actor14->GetTextProperty()->SetVerticalJustificationToCentered(); + actor14->GetTextProperty()->SetBold(1); + actor14->GetTextProperty()->SetItalic(1); + actor14->GetTextProperty()->SetFontFamilyToCourier(); + actor14->SetInput("4.0"); + actor14->SetPosition(500, 400); + + // UTF-8 freetype handling: + vtkNew actor15; + actor15->GetTextProperty()->SetFontFamily(VTK_FONT_FILE); + actor15->GetTextProperty()->SetFontFile(uncodeFontFile.c_str()); + actor15->GetTextProperty()->SetJustificationToCentered(); + actor15->GetTextProperty()->SetVerticalJustificationToCentered(); + actor15->GetTextProperty()->SetFontSize(18); + actor15->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + // There is a known issue rendering some of these characters as paths -- + // many are missing outline information in the font, and are thus absent in + // the produced vector graphics. + actor15->SetInput("UTF-8 FreeType: \xce\xa8\xd2\x94\xd2\x96\xd1\x84\xd2\xbe"); + actor15->SetPosition(300, 110); + + // Test for rotated kerning (PR#15301) + vtkNew actor16; + actor16->GetTextProperty()->SetFontFile(uncodeFontFile.c_str()); + actor16->GetTextProperty()->SetFontFamily(VTK_FONT_FILE); + actor16->GetTextProperty()->SetJustificationToCentered(); + actor16->GetTextProperty()->SetVerticalJustificationToCentered(); + actor16->GetTextProperty()->SetFontSize(18); + actor16->GetTextProperty()->SetOrientation(90); + actor16->GetTextProperty()->SetColor(0.0, 1.0, 0.7); + actor16->SetInput("oTeVaVoVAW"); + actor16->SetPosition(300, 200); + + vtkNew ren; + ren->SetBackground(0.1, 0.1, 0.1); + vtkNew win; + win->SetMultiSamples(0); + win->SetDPI(96); + win->SetSize(600, 600); + win->AddRenderer(ren.GetPointer()); + vtkNew iren; + iren->SetRenderWindow(win.GetPointer()); + + ren->AddActor(actor1.GetPointer()); + ren->AddActor(actor2.GetPointer()); + ren->AddActor(actor3.GetPointer()); + ren->AddActor(actor4.GetPointer()); + ren->AddActor(actor5.GetPointer()); + ren->AddActor(actor6.GetPointer()); + ren->AddActor(actor7.GetPointer()); + ren->AddActor(actor8.GetPointer()); + ren->AddActor(actor9.GetPointer()); + ren->AddActor(actor10.GetPointer()); + ren->AddActor(actor11.GetPointer()); + ren->AddActor(actor12.GetPointer()); + ren->AddActor(actor13.GetPointer()); + ren->AddActor(actor14.GetPointer()); + ren->AddActor(actor15.GetPointer()); + ren->AddActor(actor16.GetPointer()); + win->Render(); + + vtkNew exp; + exp->SetRenderWindow(win.GetPointer()); + exp->SetFileFormatToPS(); + exp->CompressOff(); + exp->SetSortToSimple(); + exp->TextAsPathOn(); + exp->DrawBackgroundOn(); + + std::string fileprefix = vtkTestingInteractor::TempDirectory + + std::string("/TestGL2PSFontDPIScaling"); + + exp->SetFilePrefix(fileprefix.c_str()); + exp->Write(); + + win->GetInteractor()->Initialize(); + win->GetInteractor()->Start(); + + return EXIT_SUCCESS; +} diff --git a/Rendering/Matplotlib/Testing/Cxx/TestGL2PSMathTextScaling.cxx b/Rendering/Matplotlib/Testing/Cxx/TestGL2PSMathTextScaling.cxx index 2cfffde37e6..b11160b9a1f 100644 --- a/Rendering/Matplotlib/Testing/Cxx/TestGL2PSMathTextScaling.cxx +++ b/Rendering/Matplotlib/Testing/Cxx/TestGL2PSMathTextScaling.cxx @@ -47,6 +47,7 @@ int TestGL2PSMathTextScaling(int, char *[]) vtkNew view; view->GetRenderer()->SetBackground(1.0, 1.0, 1.0); view->GetRenderWindow()->SetSize(400, 600); + view->GetRenderWindow()->SetDPI(120); vtkNew test; view->GetScene()->AddItem(test.GetPointer()); @@ -82,14 +83,17 @@ bool GL2PSMathTextScalingTest::Paint(vtkContext2D *painter) painter->GetBrush()->SetColor(50, 50, 128); painter->DrawRect(0, 0, 400, 600); - const char *str = "$\\mathrm{Text}\\/\\frac{\\pi}{\\sum_i^\\infty\\/i^{-1}}$"; painter->GetTextProp()->SetColor(.7, .4, .5); + painter->GetTextProp()->SetJustificationToLeft(); + painter->GetTextProp()->SetVerticalJustificationToBottom(); for (int i = 0; i < 10; ++i) { - painter->GetTextProp()->SetFontSize(5+i*1.5); - painter->DrawMathTextString(20, 600-((pow(i, 1.2)+1)*40), str); - painter->DrawString(5, 600-((pow(i, 1.2)+1)*40), "Text"); + int fontSize = 5 + i * 3; + float y = 600 - ((pow(i, 1.2) + 1) * 40); + painter->GetTextProp()->SetFontSize(fontSize); + painter->DrawString(5, y, "Text"); + painter->DrawMathTextString(120, y, "MathText"); } return true; diff --git a/Rendering/Matplotlib/Testing/Cxx/TestStringToPath.cxx b/Rendering/Matplotlib/Testing/Cxx/TestStringToPath.cxx index 876a690fa81..de62ae9d6bc 100644 --- a/Rendering/Matplotlib/Testing/Cxx/TestStringToPath.cxx +++ b/Rendering/Matplotlib/Testing/Cxx/TestStringToPath.cxx @@ -59,8 +59,8 @@ int TestStringToPath(int vtkNotUsed(argc), char *vtkNotUsed(argv)[]) vtkNew tprop; vtkMathTextUtilities::GetInstance()->StringToPath( - "$\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$", - path.GetPointer(), tprop.GetPointer()); + "$\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$", path.GetPointer(), + tprop.GetPointer(), view->GetRenderWindow()->GetDPI()); test->SetPath(path.GetPointer()); diff --git a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling-rasterRef.png.md5 b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling-rasterRef.png.md5 new file mode 100644 index 00000000000..7bb5528425c --- /dev/null +++ b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling-rasterRef.png.md5 @@ -0,0 +1 @@ +2f7c2bc81d8e68aa322e16e38d64a5c7 diff --git a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling.png.md5 b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling.png.md5 new file mode 100644 index 00000000000..cd90fc73815 --- /dev/null +++ b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSFontDPIScaling.png.md5 @@ -0,0 +1 @@ +c275dc97cb149bf31f9974932250ca53 diff --git a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling-rasterRef.png.md5 b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling-rasterRef.png.md5 index 90de4316d6b..87a76481922 100644 --- a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling-rasterRef.png.md5 +++ b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling-rasterRef.png.md5 @@ -1 +1 @@ -13d6b649388b234678eecc99a5ee4efb +d5babb58b36516b4898197f4cb1d2229 diff --git a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling.png.md5 b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling.png.md5 index 45e6d996054..79bd6949a7f 100644 --- a/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling.png.md5 +++ b/Rendering/Matplotlib/Testing/Data/Baseline/TestGL2PSMathTextScaling.png.md5 @@ -1 +1 @@ -898dc8417431531be437f31136bd32d5 +c2543db8af3ce95b27831f909d358e42 diff --git a/Rendering/Matplotlib/Testing/Data/Fonts/DejaVuSans.ttf.md5 b/Rendering/Matplotlib/Testing/Data/Fonts/DejaVuSans.ttf.md5 new file mode 100644 index 00000000000..09b8dd3091d --- /dev/null +++ b/Rendering/Matplotlib/Testing/Data/Fonts/DejaVuSans.ttf.md5 @@ -0,0 +1 @@ +eccb7a74720fc377b60d6b2110530fd9 diff --git a/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.cxx b/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.cxx index 374172304b6..1c4ed3d7cbf 100644 --- a/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.cxx +++ b/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.cxx @@ -519,7 +519,7 @@ bool vtkMatplotlibMathTextUtilities::PrepareImageData(vtkImageData *data, //---------------------------------------------------------------------------- bool vtkMatplotlibMathTextUtilities::GetBoundingBox( - vtkTextProperty *tprop, const char *str, unsigned int dpi, int bbox[4]) + vtkTextProperty *tprop, const char *str, int dpi, int bbox[4]) { vtkTextRenderer::Metrics metrics; if (!this->GetMetrics(tprop, str, dpi, metrics)) @@ -533,7 +533,7 @@ bool vtkMatplotlibMathTextUtilities::GetBoundingBox( //---------------------------------------------------------------------------- bool vtkMatplotlibMathTextUtilities::GetMetrics( - vtkTextProperty *tprop, const char *str, unsigned int dpi, + vtkTextProperty *tprop, const char *str, int dpi, vtkTextRenderer::Metrics &metrics) { if (!this->MaskParser) @@ -549,16 +549,13 @@ bool vtkMatplotlibMathTextUtilities::GetMetrics( long int rows = 0; long int cols = 0; - // matplotlib.mathtext seems to mishandle the dpi, this conversion makes the - // text size match the images produced by vtkFreeTypeUtilities, as well as the - // paths generated by StringToPath - long int fontSize = tprop->GetFontSize() * 72.0 / static_cast(dpi); vtkSmartPyObject resultTuple(PyObject_CallMethod(this->MaskParser, const_cast("to_mask"), const_cast("sii"), const_cast(str), - fontSize, dpi)); + tprop->GetFontSize(), + dpi)); if (this->CheckForError(resultTuple.GetPointer())) { return false; @@ -620,7 +617,7 @@ bool vtkMatplotlibMathTextUtilities::GetMetrics( bool vtkMatplotlibMathTextUtilities::RenderString(const char *str, vtkImageData *image, vtkTextProperty *tprop, - unsigned int dpi, + int dpi, int textDims[2]) { if (!this->MaskParser) @@ -637,11 +634,6 @@ bool vtkMatplotlibMathTextUtilities::RenderString(const char *str, long int rows = 0; long int cols = 0; long int ind = 0; - //long int numPixels = 0; - // matplotlib.mathtext seems to mishandle the dpi, this conversion makes the - // text size match the images produced by vtkFreeTypeUtilities, as well as the - // paths generated by StringToPath - long int fontSize = tprop->GetFontSize() * 72.0 / static_cast(dpi); double *fgColor = tprop->GetColor(); unsigned char fgR = static_cast(fgColor[0] * 255); @@ -657,10 +649,10 @@ bool vtkMatplotlibMathTextUtilities::RenderString(const char *str, bool hasBackground = (static_cast(bgA * 255) != 0); vtkSmartPyObject resultTuple(PyObject_CallMethod(this->MaskParser, - const_cast("to_mask"), - const_cast("sii"), - const_cast(str), - fontSize, dpi)); + const_cast("to_mask"), + const_cast("sii"), + const_cast(str), + tprop->GetFontSize(), dpi)); if (this->CheckForError(resultTuple.GetPointer())) { return false; @@ -827,7 +819,8 @@ bool vtkMatplotlibMathTextUtilities::RenderString(const char *str, //---------------------------------------------------------------------------- bool vtkMatplotlibMathTextUtilities::StringToPath(const char *str, vtkPath *path, - vtkTextProperty *tprop) + vtkTextProperty *tprop, + int dpi) { if (!this->PathParser) { @@ -862,9 +855,10 @@ bool vtkMatplotlibMathTextUtilities::StringToPath(const char *str, // Bounding box for all control points, used for justification float cbox[4] = {VTK_FLOAT_MAX, VTK_FLOAT_MAX, VTK_FLOAT_MIN, VTK_FLOAT_MIN}; - // The path is always generated at a font size of 100. Use this factor to + // The path is always generated using a 100pt font @72 dpi. Use this factor to // recover the font. - const float fontScale = ((tprop->GetFontSize()) / 100.); + const float fontScale = (tprop->GetFontSize() / 100.f) * (dpi / 72.f) ; + path->Reset(); // Create the font property diff --git a/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.h b/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.h index c133e272499..0e2896cc31d 100644 --- a/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.h +++ b/Rendering/Matplotlib/vtkMatplotlibMathTextUtilities.h @@ -50,11 +50,11 @@ class VTKRENDERINGMATPLOTLIB_EXPORT vtkMatplotlibMathTextUtilities : // box is the anchor point described by the horizontal and vertical // justification text property variables. // Returns true on success, false otherwise. - bool GetBoundingBox(vtkTextProperty *tprop, const char *str, - unsigned int dpi, int bbox[4]); + bool GetBoundingBox(vtkTextProperty *tprop, const char *str, int dpi, + int bbox[4]); - bool GetMetrics(vtkTextProperty *tprop, const char *str, - unsigned int dpi, vtkTextRenderer::Metrics &metrics); + bool GetMetrics(vtkTextProperty *tprop, const char *str, int dpi, + vtkTextRenderer::Metrics &metrics); // Description: // Render the given string @a str into the vtkImageData @a data with a @@ -66,14 +66,15 @@ class VTKRENDERINGMATPLOTLIB_EXPORT vtkMatplotlibMathTextUtilities : // described by the text property's vertical and horizontal justification // options. bool RenderString(const char *str, vtkImageData *data, vtkTextProperty *tprop, - unsigned int dpi, int textDims[2] = NULL); + int dpi, int textDims[2] = NULL); // Description: // Parse the MathText expression in str and fill path with a contour of the // glyphs. The origin of the path coordinates is aligned with the anchor point // described by the text property's horizontal and vertical justification // options. - bool StringToPath(const char *str, vtkPath *path, vtkTextProperty *tprop); + bool StringToPath(const char *str, vtkPath *path, vtkTextProperty *tprop, + int dpi); // Description: // Set to true if the graphics implmentation requires texture image dimensions diff --git a/Rendering/Qt/vtkQtStringToImage.cxx b/Rendering/Qt/vtkQtStringToImage.cxx index 7221ef87f06..bb95bf74e44 100644 --- a/Rendering/Qt/vtkQtStringToImage.cxx +++ b/Rendering/Qt/vtkQtStringToImage.cxx @@ -48,12 +48,12 @@ struct vtkQtLabelMapEntry class vtkQtStringToImage::Internals { public: - QFont TextPropertyToFont(vtkTextProperty* tprop) + QFont TextPropertyToFont(vtkTextProperty* tprop, int dpi) { QFont fontSpec(tprop->GetFontFamilyAsString()); fontSpec.setBold(tprop->GetBold()); fontSpec.setItalic(tprop->GetItalic()); - fontSpec.setPixelSize(tprop->GetFontSize()); + fontSpec.setPixelSize(static_cast(tprop->GetFontSize() * (dpi / 72.))); return fontSpec; } @@ -86,7 +86,8 @@ vtkQtStringToImage::~vtkQtStringToImage() //----------------------------------------------------------------------------- vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string) + const vtkUnicodeString& string, + int dpi) { vtkVector2i recti(0, 0); if (!QApplication::instance()) @@ -100,7 +101,7 @@ vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, return recti; } - QFont fontSpec = this->Implementation->TextPropertyToFont(property); + QFont fontSpec = this->Implementation->TextPropertyToFont(property, dpi); QString text = QString::fromUtf8(string.utf8_str()); @@ -117,7 +118,7 @@ vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, //----------------------------------------------------------------------------- vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, - const vtkStdString& string) + const vtkStdString& string, int dpi) { vtkVector2i recti(0, 0); if (!QApplication::instance()) @@ -131,7 +132,7 @@ vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, return recti; } - QFont fontSpec = this->Implementation->TextPropertyToFont(property); + QFont fontSpec = this->Implementation->TextPropertyToFont(property, dpi); QString text(string.c_str()); @@ -147,7 +148,7 @@ vtkVector2i vtkQtStringToImage::GetBounds(vtkTextProperty *property, } int vtkQtStringToImage::RenderString(vtkTextProperty *property, - const vtkUnicodeString& string, + const vtkUnicodeString& string, int dpi, vtkImageData *data, int textDims[2]) { if (!QApplication::instance()) @@ -156,7 +157,7 @@ int vtkQtStringToImage::RenderString(vtkTextProperty *property, return 0; } // Get the required size, and initialize a new QImage to draw on. - vtkVector2i box = this->GetBounds(property, string); + vtkVector2i box = this->GetBounds(property, string, dpi); if (box.GetX() == 0 || box.GetY() == 0) { return 0; @@ -168,7 +169,7 @@ int vtkQtStringToImage::RenderString(vtkTextProperty *property, } QString text = QString::fromUtf8(string.utf8_str()); - QFont fontSpec = this->Implementation->TextPropertyToFont(property); + QFont fontSpec = this->Implementation->TextPropertyToFont(property, dpi); QFontMetrics fontMetric(fontSpec); // Get properties from text property @@ -226,11 +227,11 @@ int vtkQtStringToImage::RenderString(vtkTextProperty *property, } int vtkQtStringToImage::RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int textDims[2]) { - return this->RenderString(property, vtkUnicodeString::from_utf8(string), data, - textDims); + return this->RenderString(property, vtkUnicodeString::from_utf8(string), dpi, + data, textDims); } //----------------------------------------------------------------------------- diff --git a/Rendering/Qt/vtkQtStringToImage.h b/Rendering/Qt/vtkQtStringToImage.h index 32c7c176246..119ef153204 100644 --- a/Rendering/Qt/vtkQtStringToImage.h +++ b/Rendering/Qt/vtkQtStringToImage.h @@ -48,20 +48,20 @@ class VTKRENDERINGQT_EXPORT vtkQtStringToImage : public vtkStringToImage // is valid (it may not if GetBoundingBox() failed or if the string // was empty). virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkUnicodeString& string); + const vtkUnicodeString& string, int dpi); virtual vtkVector2i GetBounds(vtkTextProperty *property, - const vtkStdString& string); + const vtkStdString& string, int dpi); // Description: // Given a text property and a string, this function initializes the // vtkImageData *data and renders it in a vtkImageData. textDims, if provided, // will be overwritten by the pixel width and height of the rendered string. virtual int RenderString(vtkTextProperty *property, - const vtkUnicodeString& string, + const vtkUnicodeString& string, int dpi, vtkImageData *data, int textDims[2] = NULL); virtual int RenderString(vtkTextProperty *property, - const vtkStdString& string, + const vtkStdString& string, int dpi, vtkImageData *data, int textDims[2] = NULL);