comparison 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
comparison
equal deleted inserted replaced
596:b716763571ad 597:9e51fb773bbd
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "CairoCompositor.h"
23
24 #include "Internals/CairoColorTextureRenderer.h"
25 #include "Internals/CairoFloatTextureRenderer.h"
26 #include "Internals/CairoInfoPanelRenderer.h"
27 #include "Internals/CairoPolylineRenderer.h"
28 #include "Internals/CairoTextRenderer.h"
29
30 #include <Core/OrthancException.h>
31
32 namespace OrthancStone
33 {
34 cairo_t* CairoCompositor::GetCairoContext()
35 {
36 if (context_.get() == NULL)
37 {
38 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
39 }
40 else
41 {
42 return context_->GetObject();
43 }
44 }
45
46
47 Internals::CompositorHelper::ILayerRenderer* CairoCompositor::Create(const ISceneLayer& layer)
48 {
49 switch (layer.GetType())
50 {
51 case ISceneLayer::Type_Polyline:
52 return new Internals::CairoPolylineRenderer(*this, layer);
53
54 case ISceneLayer::Type_InfoPanel:
55 return new Internals::CairoInfoPanelRenderer(*this, layer);
56
57 case ISceneLayer::Type_ColorTexture:
58 return new Internals::CairoColorTextureRenderer(*this, layer);
59
60 case ISceneLayer::Type_FloatTexture:
61 return new Internals::CairoFloatTextureRenderer(*this, layer);
62
63 case ISceneLayer::Type_Text:
64 {
65 const TextSceneLayer& l = dynamic_cast<const TextSceneLayer&>(layer);
66
67 Fonts::const_iterator found = fonts_.find(l.GetFontIndex());
68 if (found == fonts_.end())
69 {
70 return NULL;
71 }
72 else
73 {
74 assert(found->second != NULL);
75 return new Internals::CairoTextRenderer(*this, *found->second, l);
76 }
77 }
78
79 default:
80 return NULL;
81 }
82 }
83
84
85 CairoCompositor::CairoCompositor(Scene2D& scene,
86 unsigned int canvasWidth,
87 unsigned int canvasHeight) :
88 helper_(scene, *this)
89 {
90 canvas_.SetSize(canvasWidth, canvasHeight, false);
91 }
92
93
94 CairoCompositor::~CairoCompositor()
95 {
96 for (Fonts::iterator it = fonts_.begin(); it != fonts_.end(); ++it)
97 {
98 assert(it->second != NULL);
99 delete it->second;
100 }
101 }
102
103
104 void CairoCompositor::SetFont(size_t index,
105 GlyphBitmapAlphabet* dict) // Takes ownership
106 {
107 if (dict == NULL)
108 {
109 throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
110 }
111 else
112 {
113 std::auto_ptr<GlyphBitmapAlphabet> protection(dict);
114
115 Fonts::iterator found = fonts_.find(index);
116
117 if (found == fonts_.end())
118 {
119 fonts_[index] = protection.release();
120 }
121 else
122 {
123 assert(found->second != NULL);
124 delete found->second;
125
126 found->second = protection.release();
127 }
128 }
129 }
130
131
132 #if ORTHANC_ENABLE_LOCALE == 1
133 void CairoCompositor::SetFont(size_t index,
134 Orthanc::EmbeddedResources::FileResourceId resource,
135 unsigned int fontSize,
136 Orthanc::Encoding codepage)
137 {
138 FontRenderer renderer;
139 renderer.LoadFont(font, fontSize);
140
141 std::auto_ptr<GlyphBitmapAlphabet> alphabet(new GlyphBitmapAlphabet);
142 alphabet->LoadCodepage(renderer, codepage);
143
144 SetFont(index, alphabet.release());
145 }
146 #endif
147
148
149 void CairoCompositor::Refresh()
150 {
151 context_.reset(new CairoContext(canvas_));
152
153 // https://www.cairographics.org/FAQ/#clear_a_surface
154 cairo_set_source_rgba(context_->GetObject(), 0, 0, 0, 255);
155 cairo_paint(context_->GetObject());
156
157 helper_.Refresh(canvas_.GetWidth(), canvas_.GetHeight());
158 context_.reset();
159 }
160
161
162 Orthanc::ImageAccessor* CairoCompositor::RenderText(size_t fontIndex,
163 const std::string& utf8) const
164 {
165 Fonts::const_iterator found = fonts_.find(fontIndex);
166
167 if (found == fonts_.end())
168 {
169 return NULL;
170 }
171 else
172 {
173 assert(found->second != NULL);
174 return found->second->RenderText(utf8);
175 }
176 }
177 }