comparison OrthancStone/Sources/Scene2D/Internals/CairoTextRenderer.cpp @ 1512:244ad1e4e76a

reorganization of folders
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 07 Jul 2020 16:21:02 +0200
parents Framework/Scene2D/Internals/CairoTextRenderer.cpp@30deba7bc8e2
children 85e117739eca
comparison
equal deleted inserted replaced
1511:9dfeee74c1e6 1512:244ad1e4e76a
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-2020 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 "CairoTextRenderer.h"
23
24 #include <OrthancException.h>
25
26 namespace OrthancStone
27 {
28 namespace Internals
29 {
30 CairoTextRenderer::CairoTextRenderer(ICairoContextProvider& target,
31 const GlyphBitmapAlphabet& alphabet,
32 const TextSceneLayer& layer) :
33 CairoBaseRenderer(target, layer)
34 {
35 std::unique_ptr<Orthanc::ImageAccessor> source(alphabet.RenderText(layer.GetText()));
36
37 if (source.get() != NULL)
38 {
39 text_.SetSize(source->GetWidth(), source->GetHeight(), true);
40
41 Orthanc::ImageAccessor target;
42 text_.GetWriteableAccessor(target);
43
44 if (source->GetFormat() != Orthanc::PixelFormat_Grayscale8 ||
45 target.GetFormat() != Orthanc::PixelFormat_BGRA32)
46 {
47 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
48 }
49
50 const unsigned int width = source->GetWidth();
51 const Color& color = layer.GetColor();
52
53 for (unsigned int y = 0; y < source->GetHeight(); y++)
54 {
55 const uint8_t* p = reinterpret_cast<const uint8_t*>(source->GetConstRow(y));
56 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
57
58 for (unsigned int x = 0; x < width; x++)
59 {
60 unsigned int alpha = *p;
61
62 // Premultiplied alpha
63 q[0] = static_cast<uint8_t>((color.GetBlue() * alpha) / 255);
64 q[1] = static_cast<uint8_t>((color.GetGreen() * alpha) / 255);
65 q[2] = static_cast<uint8_t>((color.GetRed() * alpha) / 255);
66 q[3] = *p;
67
68 p++;
69 q += 4;
70 }
71 }
72
73 cairo_surface_mark_dirty(text_.GetObject());
74 }
75 }
76
77
78 void CairoTextRenderer::Render(const AffineTransform2D& transform,
79 unsigned int canvasWidth,
80 unsigned int canvasHeight)
81 {
82 if (text_.GetWidth() != 0 &&
83 text_.GetHeight() != 0)
84 {
85 const TextSceneLayer& layer = GetLayer<TextSceneLayer>();
86
87 cairo_t* cr = GetCairoContext();
88 cairo_set_source_rgb(cr, layer.GetColor().GetRedAsFloat(),
89 layer.GetColor().GetGreenAsFloat(),
90 layer.GetColor().GetBlueAsFloat());
91
92 double dx, dy; // In pixels
93 ComputeAnchorTranslation(dx, dy, layer.GetAnchor(), text_.GetWidth(),
94 text_.GetHeight(), layer.GetBorder());
95
96 double x = layer.GetX();
97 double y = layer.GetY();
98 transform.Apply(x, y);
99
100 cairo_save(cr);
101
102 cairo_matrix_t t;
103 cairo_matrix_init_identity(&t);
104 cairo_matrix_translate(&t, x + dx, y + dy);
105 cairo_transform(cr, &t);
106
107 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
108 cairo_set_source_surface(cr, text_.GetObject(), 0, 0);
109 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BILINEAR);
110 cairo_paint(cr);
111
112 cairo_restore(cr);
113 }
114 }
115 }
116 }