Mercurial > hg > orthanc-stone
diff Framework/Scene2D/CairoCompositor.cpp @ 597:9e51fb773bbd
CairoCompositor
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 26 Apr 2019 17:28:18 +0200 |
parents | |
children | a806abb497b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/CairoCompositor.cpp Fri Apr 26 17:28:18 2019 +0200 @@ -0,0 +1,177 @@ +/** + * 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 "CairoCompositor.h" + +#include "Internals/CairoColorTextureRenderer.h" +#include "Internals/CairoFloatTextureRenderer.h" +#include "Internals/CairoInfoPanelRenderer.h" +#include "Internals/CairoPolylineRenderer.h" +#include "Internals/CairoTextRenderer.h" + +#include <Core/OrthancException.h> + +namespace OrthancStone +{ + cairo_t* CairoCompositor::GetCairoContext() + { + if (context_.get() == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + else + { + return context_->GetObject(); + } + } + + + Internals::CompositorHelper::ILayerRenderer* CairoCompositor::Create(const ISceneLayer& layer) + { + switch (layer.GetType()) + { + case ISceneLayer::Type_Polyline: + return new Internals::CairoPolylineRenderer(*this, layer); + + case ISceneLayer::Type_InfoPanel: + return new Internals::CairoInfoPanelRenderer(*this, layer); + + case ISceneLayer::Type_ColorTexture: + return new Internals::CairoColorTextureRenderer(*this, layer); + + case ISceneLayer::Type_FloatTexture: + return new Internals::CairoFloatTextureRenderer(*this, layer); + + case ISceneLayer::Type_Text: + { + const TextSceneLayer& l = dynamic_cast<const TextSceneLayer&>(layer); + + Fonts::const_iterator found = fonts_.find(l.GetFontIndex()); + if (found == fonts_.end()) + { + return NULL; + } + else + { + assert(found->second != NULL); + return new Internals::CairoTextRenderer(*this, *found->second, l); + } + } + + default: + return NULL; + } + } + + + CairoCompositor::CairoCompositor(Scene2D& scene, + unsigned int canvasWidth, + unsigned int canvasHeight) : + helper_(scene, *this) + { + canvas_.SetSize(canvasWidth, canvasHeight, false); + } + + + CairoCompositor::~CairoCompositor() + { + for (Fonts::iterator it = fonts_.begin(); it != fonts_.end(); ++it) + { + assert(it->second != NULL); + delete it->second; + } + } + + + void CairoCompositor::SetFont(size_t index, + GlyphBitmapAlphabet* dict) // Takes ownership + { + if (dict == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); + } + else + { + std::auto_ptr<GlyphBitmapAlphabet> protection(dict); + + Fonts::iterator found = fonts_.find(index); + + if (found == fonts_.end()) + { + fonts_[index] = protection.release(); + } + else + { + assert(found->second != NULL); + delete found->second; + + found->second = protection.release(); + } + } + } + + +#if ORTHANC_ENABLE_LOCALE == 1 + void CairoCompositor::SetFont(size_t index, + Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + Orthanc::Encoding codepage) + { + FontRenderer renderer; + renderer.LoadFont(font, fontSize); + + std::auto_ptr<GlyphBitmapAlphabet> alphabet(new GlyphBitmapAlphabet); + alphabet->LoadCodepage(renderer, codepage); + + SetFont(index, alphabet.release()); + } +#endif + + + void CairoCompositor::Refresh() + { + context_.reset(new CairoContext(canvas_)); + + // https://www.cairographics.org/FAQ/#clear_a_surface + cairo_set_source_rgba(context_->GetObject(), 0, 0, 0, 255); + cairo_paint(context_->GetObject()); + + helper_.Refresh(canvas_.GetWidth(), canvas_.GetHeight()); + context_.reset(); + } + + + Orthanc::ImageAccessor* CairoCompositor::RenderText(size_t fontIndex, + const std::string& utf8) const + { + Fonts::const_iterator found = fonts_.find(fontIndex); + + if (found == fonts_.end()) + { + return NULL; + } + else + { + assert(found->second != NULL); + return found->second->RenderText(utf8); + } + } +}