Mercurial > hg > orthanc-stone
changeset 577:b098a3aaf694
alphabet of glyphs
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 19 Apr 2019 15:42:57 +0200 |
parents | 529c9617654b |
children | 21fd70df3fc9 |
files | Framework/Fonts/GlyphBitmapAlphabet.cpp Framework/Fonts/GlyphBitmapAlphabet.h Framework/Fonts/GlyphTextureAlphabet.cpp Framework/Fonts/GlyphTextureAlphabet.h Framework/Fonts/OpenGLTextCoordinates.cpp Framework/Fonts/OpenGLTextCoordinates.h Framework/Fonts/TextBoundingBox.cpp Framework/Fonts/TextBoundingBox.h Resources/CMake/OrthancStoneConfiguration.cmake |
diffstat | 9 files changed, 906 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/GlyphBitmapAlphabet.cpp Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,113 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "GlyphBitmapAlphabet.h" + +#include "TextBoundingBox.h" +#include "../Toolbox/DynamicBitmap.h" + +#include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> + +namespace OrthancStone +{ + class GlyphBitmapAlphabet::RenderTextVisitor : public GlyphAlphabet::ITextVisitor + { + private: + Orthanc::ImageAccessor& target_; + const GlyphBitmapAlphabet& that_; + int offsetX_; + int offsetY_; + + public: + RenderTextVisitor(Orthanc::ImageAccessor& target, + const GlyphBitmapAlphabet& that, + int offsetX, + int offsetY) : + target_(target), + that_(that), + offsetX_(offsetX), + offsetY_(offsetY) + { + } + + virtual void Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload) + { + int left = x + offsetX_; + int top = y + offsetY_; + + assert(payload != NULL); + const DynamicBitmap& glyph = *dynamic_cast<const DynamicBitmap*>(payload); + + assert(left >= 0 && + top >= 0 && + static_cast<unsigned int>(left) + width <= target_.GetWidth() && + static_cast<unsigned int>(top) + height <= target_.GetHeight() && + width == glyph.GetBitmap().GetWidth() && + height == glyph.GetBitmap().GetHeight()); + + { + Orthanc::ImageAccessor region; + target_.GetRegion(region, left, top, width, height); + Orthanc::ImageProcessing::Copy(region, glyph.GetBitmap()); + } + } + }; + + +#if ORTHANC_ENABLE_LOCALE == 1 + void GlyphBitmapAlphabet::LoadCodepage(FontRenderer& renderer, + Orthanc::Encoding codepage) + { + for (unsigned int i = 0; i < 256; i++) + { + uint32_t unicode; + if (GlyphAlphabet::GetUnicodeFromCodepage(unicode, i, codepage)) + { + AddUnicodeCharacter(renderer, unicode); + } + } + } +#endif + + + Orthanc::ImageAccessor* GlyphBitmapAlphabet::RenderText(const std::string& utf8) const + { + TextBoundingBox box(alphabet_, utf8); + + std::auto_ptr<Orthanc::ImageAccessor> bitmap( + new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, + box.GetWidth(), box.GetHeight(), + true /* force minimal pitch */)); + + Orthanc::ImageProcessing::Set(*bitmap, 0); + + RenderTextVisitor visitor(*bitmap, *this, -box.GetLeft(), -box.GetTop()); + alphabet_.Apply(visitor, utf8); + + return bitmap.release(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/GlyphBitmapAlphabet.h Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,58 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "GlyphAlphabet.h" + +#include <Core/Images/ImageAccessor.h> + +namespace OrthancStone +{ + class GlyphBitmapAlphabet : public boost::noncopyable + { + private: + class RenderTextVisitor; + + GlyphAlphabet alphabet_; + + public: + const GlyphAlphabet& GetAlphabet() const + { + return alphabet_; + } + + void AddUnicodeCharacter(FontRenderer& renderer, + uint32_t unicode) + { + alphabet_.Register(renderer, unicode); + } + + +#if ORTHANC_ENABLE_LOCALE == 1 + void LoadCodepage(FontRenderer& renderer, + Orthanc::Encoding codepage); +#endif + + + Orthanc::ImageAccessor* RenderText(const std::string& utf8) const; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/GlyphTextureAlphabet.cpp Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,295 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "GlyphTextureAlphabet.h" + +#include "TextBoundingBox.h" +#include "../Toolbox/DynamicBitmap.h" + +#include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> +#include <Core/OrthancException.h> + +#include <boost/math/special_functions/round.hpp> + + +namespace OrthancStone +{ + class GlyphTextureAlphabet::GlyphSizeVisitor : public GlyphAlphabet::IGlyphVisitor + { + private: + unsigned int maxWidth_; + unsigned int maxHeight_; + + public: + GlyphSizeVisitor() : + maxWidth_(0), + maxHeight_(0) + { + } + + virtual void Visit(uint32_t unicode, + const Glyph& glyph) + { + maxWidth_ = std::max(maxWidth_, glyph.GetWidth()); + maxHeight_ = std::max(maxHeight_, glyph.GetHeight()); + } + + unsigned int GetMaxWidth() const + { + return maxWidth_; + } + + unsigned int GetMaxHeight() const + { + return maxHeight_; + } + }; + + + class GlyphTextureAlphabet::TextureGenerator : public GlyphAlphabet::IGlyphVisitor + { + private: + std::auto_ptr<Orthanc::ImageAccessor> texture_; + + unsigned int countColumns_; + unsigned int countRows_; + GlyphAlphabet& targetAlphabet_; + unsigned int glyphMaxWidth_; + unsigned int glyphMaxHeight_; + unsigned int column_; + unsigned int row_; + + public: + TextureGenerator(GlyphAlphabet& targetAlphabet, + unsigned int countGlyphs, + unsigned int glyphMaxWidth, + unsigned int glyphMaxHeight) : + targetAlphabet_(targetAlphabet), + glyphMaxWidth_(glyphMaxWidth), + glyphMaxHeight_(glyphMaxHeight), + column_(0), + row_(0) + { + int c = boost::math::iround<int>(sqrt(static_cast<float>(countGlyphs))); + + if (c <= 0) + { + countColumns_ = 1; + } + else + { + countColumns_ = static_cast<unsigned int>(c); + } + + countRows_ = countGlyphs / countColumns_; + if (countGlyphs % countColumns_ != 0) + { + countRows_++; + } + + texture_.reset(new Orthanc::Image(Orthanc::PixelFormat_RGBA32, + countColumns_ * glyphMaxWidth_, + countRows_ * glyphMaxHeight_, + true /* force minimal pitch */)); + + Orthanc::ImageProcessing::Set(*texture_, 0, 0, 0, 0); + } + + + virtual void Visit(uint32_t unicode, + const Glyph& glyph) + { + if (!glyph.HasPayload()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + + if (column_ >= countColumns_ || + row_ >= countRows_) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + unsigned int x = column_ * glyphMaxWidth_; + unsigned int y = row_ * glyphMaxHeight_; + + const Orthanc::ImageAccessor& source = dynamic_cast<const DynamicBitmap&>(glyph.GetPayload()).GetBitmap(); + + if (source.GetFormat() != Orthanc::PixelFormat_Grayscale8) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + targetAlphabet_.Register(unicode, glyph, new TextureLocation(x, y)); + + Orthanc::ImageAccessor target; + texture_->GetRegion(target, x, y, source.GetWidth(), source.GetHeight()); + + //Orthanc::ImageProcessing::Copy(target, bitmap->GetBitmap()); + + for (unsigned int y = 0; y < source.GetHeight(); y++) + { + const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y)); + uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y)); + + for (unsigned int x = 0; x < source.GetWidth(); x++) + { + // Premultiplied alpha + q[0] = 0; + q[1] = 0; + q[2] = 0; + q[3] = *p; + + p++; + q += 4; + } + } + + column_++; + if (column_ == countColumns_) + { + column_ = 0; + row_++; + } + } + + + Orthanc::ImageAccessor* ReleaseTexture() + { + return texture_.release(); + } + }; + + + class GlyphTextureAlphabet::RenderTextVisitor : public GlyphAlphabet::ITextVisitor + { + private: + Orthanc::ImageAccessor& target_; + const Orthanc::ImageAccessor& texture_; + int offsetX_; + int offsetY_; + + public: + RenderTextVisitor(Orthanc::ImageAccessor& target, + const GlyphTextureAlphabet& that, + int offsetX, + int offsetY) : + target_(target), + texture_(that.GetTexture()), + offsetX_(offsetX), + offsetY_(offsetY) + { + } + + virtual void Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload) + { + int left = x + offsetX_; + int top = y + offsetY_; + + assert(payload != NULL); + const TextureLocation& location = *dynamic_cast<const TextureLocation*>(payload); + + assert(left >= 0 && + top >= 0 && + static_cast<unsigned int>(left) + width <= target_.GetWidth() && + static_cast<unsigned int>(top) + height <= target_.GetHeight()); + + { + Orthanc::ImageAccessor to; + target_.GetRegion(to, left, top, width, height); + + Orthanc::ImageAccessor from; + texture_.GetRegion(from, location.GetX(), location.GetY(), width, height); + + Orthanc::ImageProcessing::Copy(to, from); + } + } + }; + + + GlyphTextureAlphabet::GlyphTextureAlphabet(const GlyphBitmapAlphabet& sourceAlphabet) : + textureWidth_(0), + textureHeight_(0) + { + GlyphSizeVisitor size; + sourceAlphabet.GetAlphabet().Apply(size); + + TextureGenerator generator(alphabet_, + sourceAlphabet.GetAlphabet().GetSize(), + size.GetMaxWidth(), + size.GetMaxHeight()); + sourceAlphabet.GetAlphabet().Apply(generator); + + texture_.reset(generator.ReleaseTexture()); + textureWidth_ = texture_->GetWidth(); + textureHeight_ = texture_->GetHeight(); + } + + + const Orthanc::ImageAccessor& GlyphTextureAlphabet::GetTexture() const + { + if (texture_.get() == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return *texture_; + } + } + + + Orthanc::ImageAccessor* GlyphTextureAlphabet::ReleaseTexture() + { + if (texture_.get() == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return texture_.release(); + } + } + + + Orthanc::ImageAccessor* GlyphTextureAlphabet::RenderText(const std::string& utf8) + { + TextBoundingBox box(alphabet_, utf8); + + std::auto_ptr<Orthanc::ImageAccessor> bitmap( + new Orthanc::Image(Orthanc::PixelFormat_RGBA32, + box.GetWidth(), box.GetHeight(), + true /* force minimal pitch */)); + + Orthanc::ImageProcessing::Set(*bitmap, 0, 0, 0, 0); + + RenderTextVisitor visitor(*bitmap, *this, -box.GetLeft(), -box.GetTop()); + alphabet_.Apply(visitor, utf8); + + return bitmap.release(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/GlyphTextureAlphabet.h Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,92 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "GlyphBitmapAlphabet.h" + +#include <Core/Images/ImageAccessor.h> + +namespace OrthancStone +{ + class GlyphTextureAlphabet : public boost::noncopyable + { + public: + class TextureLocation : public Orthanc::IDynamicObject + { + private: + unsigned int x_; + unsigned int y_; + + public: + TextureLocation(unsigned int x, + unsigned int y) : + x_(x), + y_(y) + { + } + + unsigned int GetX() const + { + return x_; + } + + unsigned int GetY() const + { + return y_; + } + }; + + private: + class GlyphSizeVisitor; + class TextureGenerator; + class RenderTextVisitor; + + GlyphAlphabet alphabet_; + std::auto_ptr<Orthanc::ImageAccessor> texture_; + unsigned int textureWidth_; + unsigned int textureHeight_; + + public: + GlyphTextureAlphabet(const GlyphBitmapAlphabet& sourceAlphabet); + + const Orthanc::ImageAccessor& GetTexture() const; + + Orthanc::ImageAccessor* ReleaseTexture(); + + Orthanc::ImageAccessor* RenderText(const std::string& utf8); + + const GlyphAlphabet& GetAlphabet() const + { + return alphabet_; + } + + unsigned int GetTextureWidth() const + { + return textureWidth_; + } + + unsigned int GetTextureHeight() const + { + return textureHeight_; + } + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/OpenGLTextCoordinates.cpp Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,117 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "OpenGLTextCoordinates.h" + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + namespace OpenGL + { + void OpenGLTextCoordinates::Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload) + { + // Rendering coordinates + float rx1 = x - box_.GetLeft(); + float ry1 = y - box_.GetTop(); + float rx2 = rx1 + static_cast<float>(width); + float ry2 = ry1 + static_cast<float>(height); + + // Texture coordinates + assert(payload != NULL); + const GlyphTextureAlphabet::TextureLocation& location = + *dynamic_cast<const GlyphTextureAlphabet::TextureLocation*>(payload); + + float tx1 = location.GetX() / textureWidth_; + float ty1 = location.GetY() / textureHeight_; + float tx2 = tx1 + (static_cast<float>(width) / textureWidth_); + float ty2 = ty1 + (static_cast<float>(height) / textureHeight_); + + const float rpos[6][2] = { + { rx1, ry1 }, + { rx1, ry2 }, + { rx2, ry1 }, + { rx2, ry1 }, + { rx1, ry2 }, + { rx2, ry2 } + }; + + const float tpos[6][2] = { + { tx1, ty1 }, + { tx1, ty2 }, + { tx2, ty1 }, + { tx2, ty1 }, + { tx1, ty2 }, + { tx2, ty2 } + }; + + for (unsigned int i = 0; i < 6; i++) + { + renderingCoords_.push_back(rpos[i][0]); + renderingCoords_.push_back(rpos[i][1]); + textureCoords_.push_back(tpos[i][0]); + textureCoords_.push_back(tpos[i][1]); + } + } + + + OpenGLTextCoordinates::OpenGLTextCoordinates(const GlyphTextureAlphabet& alphabet, + const std::string& utf8) : + box_(alphabet.GetAlphabet(), utf8), + textureWidth_(alphabet.GetTextureWidth()), + textureHeight_(alphabet.GetTextureHeight()) + { + if (textureWidth_ <= 0 || + textureHeight_ <= 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + width_ = static_cast<float>(box_.GetWidth()); + height_ = static_cast<float>(box_.GetHeight()); + + // Each character is made of two 2D triangles (= 2 * 3 * 2 = 12) + renderingCoords_.reserve(box_.GetCharactersCount() * 12); + textureCoords_.reserve(box_.GetCharactersCount() * 12); + + alphabet.GetAlphabet().Apply(*this, utf8); + } + + + const std::vector<float>& OpenGLTextCoordinates::GetRenderingCoords() const + { + assert(renderingCoords_.size() == textureCoords_.size()); + return renderingCoords_; + } + + + const std::vector<float>& OpenGLTextCoordinates::GetTextureCoords() const + { + assert(renderingCoords_.size() == textureCoords_.size()); + return textureCoords_; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/OpenGLTextCoordinates.h Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,74 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "GlyphTextureAlphabet.h" +#include "TextBoundingBox.h" + +namespace OrthancStone +{ + namespace OpenGL + { + class OpenGLTextCoordinates : protected GlyphAlphabet::ITextVisitor + { + private: + TextBoundingBox box_; + float width_; + float height_; + std::vector<float> renderingCoords_; + std::vector<float> textureCoords_; + float textureWidth_; + float textureHeight_; + + protected: + virtual void Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload); + + public: + OpenGLTextCoordinates(const GlyphTextureAlphabet& alphabet, + const std::string& utf8); + + unsigned int GetTextWidth() const + { + return box_.GetWidth(); + } + + unsigned int GetTextHeight() const + { + return box_.GetHeight(); + } + + bool IsEmpty() const + { + return renderingCoords_.empty(); + } + + const std::vector<float>& GetRenderingCoords() const; + + const std::vector<float>& GetTextureCoords() const; + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/TextBoundingBox.cpp Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,80 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "TextBoundingBox.h" + +namespace OrthancStone +{ + void TextBoundingBox::AddPoint(int x, + int y) + { + left_ = std::min(left_, x); + right_ = std::max(right_, x); + top_ = std::min(top_, y); + bottom_ = std::max(bottom_, y); + } + + + void TextBoundingBox::Clear() + { + left_ = 0; + top_ = 0; + right_ = 0; + bottom_ = 0; + countCharacters_ = 0; + } + + + void TextBoundingBox::Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload /* ignored */) + { + AddPoint(x, y); + AddPoint(x + static_cast<int>(width), + y + static_cast<int>(height)); + countCharacters_++; + } + + + TextBoundingBox::TextBoundingBox(const GlyphAlphabet& alphabet, + const std::string& utf8) + { + Clear(); + alphabet.Apply(*this, utf8); + } + + + unsigned int TextBoundingBox::GetWidth() const + { + assert(left_ <= right_); + return static_cast<unsigned int>(right_ - left_ + 1); + } + + + unsigned int TextBoundingBox::GetHeight() const + { + assert(top_ <= bottom_); + return static_cast<unsigned int>(bottom_ - top_ + 1); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Fonts/TextBoundingBox.h Fri Apr 19 15:42:57 2019 +0200 @@ -0,0 +1,73 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "GlyphAlphabet.h" + +namespace OrthancStone +{ + class TextBoundingBox : protected GlyphAlphabet::ITextVisitor + { + private: + int left_; + int top_; + int right_; + int bottom_; + unsigned int countCharacters_; + + void AddPoint(int x, + int y); + + void Clear(); + + protected: + virtual void Visit(uint32_t unicode, + int x, + int y, + unsigned int width, + unsigned int height, + const Orthanc::IDynamicObject* payload /* ignored */); + + public: + TextBoundingBox(const GlyphAlphabet& alphabet, + const std::string& utf8); + + int GetLeft() const + { + return left_; + } + + int GetTop() const + { + return top_; + } + + unsigned int GetWidth() const; + + unsigned int GetHeight() const; + + unsigned int GetCharactersCount() const + { + return countCharacters_; + } + }; +}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 19 15:11:16 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 19 15:42:57 2019 +0200 @@ -247,6 +247,10 @@ ${ORTHANC_STONE_ROOT}/Framework/Fonts/FontRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/Glyph.cpp ${ORTHANC_STONE_ROOT}/Framework/Fonts/GlyphAlphabet.cpp + ${ORTHANC_STONE_ROOT}/Framework/Fonts/GlyphBitmapAlphabet.cpp + ${ORTHANC_STONE_ROOT}/Framework/Fonts/GlyphTextureAlphabet.cpp + ${ORTHANC_STONE_ROOT}/Framework/Fonts/OpenGLTextCoordinates.cpp + ${ORTHANC_STONE_ROOT}/Framework/Fonts/TextBoundingBox.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/CircleMeasureTracker.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/ColorFrameRenderer.cpp ${ORTHANC_STONE_ROOT}/Framework/Layers/DicomSeriesVolumeSlicer.cpp