changeset 2900:668d5ad73c74

Font::Render()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 22 Oct 2018 14:20:21 +0200
parents 5dd649de253d
children 93c65e3a6bb1
files Core/Images/Font.cpp Core/Images/Font.h Core/Toolbox.cpp UnitTestsSources/UnitTestsMain.cpp
diffstat 4 files changed, 111 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Images/Font.cpp	Thu Oct 18 12:03:51 2018 +0200
+++ b/Core/Images/Font.cpp	Mon Oct 22 14:20:21 2018 +0200
@@ -42,8 +42,10 @@
 #  include "../SystemToolbox.h"
 #endif
 
+#include "../OrthancException.h"
 #include "../Toolbox.h"
-#include "../OrthancException.h"
+#include "Image.h"
+#include "ImageProcessing.h"
 
 #include <stdio.h>
 #include <memory>
@@ -335,4 +337,84 @@
     DrawInternal(target, utf8, x, y, color);
   }
 
+
+  void Font::ComputeTextExtent(unsigned int& width,
+                               unsigned int& height,
+                               const std::string& utf8) const
+  {
+    width = 0;
+    
+#if ORTHANC_ENABLE_LOCALE == 1
+    std::string s = Toolbox::ConvertFromUtf8(utf8, Encoding_Latin1);
+#else
+    // If the locale support is disabled, simply drop non-ASCII
+    // characters from the source UTF-8 string
+    std::string s = Toolbox::ConvertToAscii(utf8);
+#endif
+
+    // Compute the text extent
+    unsigned int x = 0;
+    unsigned int countLines = 0;
+    
+    for (size_t i = 0; i < s.size(); i++)
+    {
+      if (s[i] == '\n')
+      {
+        // Go to the next line
+        x = 0;
+
+        countLines ++;
+      }
+      else
+      {
+        Characters::const_iterator c = characters_.find(s[i]);
+        if (c != characters_.end())
+        {
+          x += c->second->advance_;
+
+          if (countLines == 0)
+          {
+            countLines = 1;
+          }
+          
+          if (x > width)
+          {
+            width = x;
+          }
+        }
+      }
+    }
+
+    height = countLines * (maxHeight_ + 1);
+  }
+
+
+  ImageAccessor* Font::Render(const std::string& utf8,
+                              PixelFormat format,
+                              uint8_t r,
+                              uint8_t g,
+                              uint8_t b) const
+  {
+    unsigned int width, height;
+    ComputeTextExtent(width, height, utf8);
+    
+    std::auto_ptr<ImageAccessor>  target(new Image(format, width, height, false));
+    ImageProcessing::Set(*target, 0, 0, 0, 255);
+    Draw(*target, utf8, 0, 0, r, g, b);
+
+    return target.release();
+  }
+
+
+  ImageAccessor* Font::RenderAlpha(const std::string& utf8) const
+  {
+    unsigned int width, height;
+    ComputeTextExtent(width, height, utf8);
+
+    std::auto_ptr<ImageAccessor>  target(new Image(PixelFormat_Grayscale8, width, height, false));
+    ImageProcessing::Set(*target, 0);
+    Draw(*target, utf8, 0, 0, 255);
+
+    return target.release();
+  }
 }
--- a/Core/Images/Font.h	Thu Oct 18 12:03:51 2018 +0200
+++ b/Core/Images/Font.h	Mon Oct 22 14:20:21 2018 +0200
@@ -111,5 +111,17 @@
               uint8_t r,
               uint8_t g,
               uint8_t b) const;
+
+    void ComputeTextExtent(unsigned int& width,
+                           unsigned int& height,
+                           const std::string& utf8) const;
+
+    ImageAccessor* Render(const std::string& utf8,
+                          PixelFormat format,
+                          uint8_t r,
+                          uint8_t g,
+                          uint8_t b) const;
+
+    ImageAccessor* RenderAlpha(const std::string& utf8) const;
   };
 }
--- a/Core/Toolbox.cpp	Thu Oct 18 12:03:51 2018 +0200
+++ b/Core/Toolbox.cpp	Mon Oct 22 14:20:21 2018 +0200
@@ -624,6 +624,14 @@
 #endif
 
 
+  static bool IsAsciiCharacter(uint8_t c)
+  {
+    return (c != 0 &&
+            c <= 127 &&
+            (c == '\n' || !iscntrl(c)));
+  }
+
+
   bool Toolbox::IsAsciiString(const void* data,
                               size_t size)
   {
@@ -631,7 +639,7 @@
 
     for (size_t i = 0; i < size; i++, p++)
     {
-      if (*p > 127 || *p == 0 || iscntrl(*p))
+      if (!IsAsciiCharacter(*p))
       {
         return false;
       }
@@ -654,7 +662,7 @@
     result.reserve(source.size() + 1);
     for (size_t i = 0; i < source.size(); i++)
     {
-      if (source[i] <= 127 && source[i] >= 0 && !iscntrl(source[i]))
+      if (IsAsciiCharacter(source[i]))
       {
         result.push_back(source[i]);
       }
--- a/UnitTestsSources/UnitTestsMain.cpp	Thu Oct 18 12:03:51 2018 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Mon Oct 22 14:20:21 2018 +0200
@@ -472,6 +472,12 @@
   s[2] = '\0';
   ASSERT_EQ(10u, s.size());
   ASSERT_FALSE(Toolbox::IsAsciiString(s));
+
+  ASSERT_TRUE(Toolbox::IsAsciiString("Hello\nworld"));
+  ASSERT_FALSE(Toolbox::IsAsciiString("Hello\rworld"));
+
+  ASSERT_EQ("Hello\nworld", Toolbox::ConvertToAscii("Hello\nworld"));
+  ASSERT_EQ("Helloworld", Toolbox::ConvertToAscii("Hello\r\tworld"));
 }