597
|
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 "CairoTextRenderer.h"
|
|
23
|
|
24 #include <Core/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::auto_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 unsigned int red = layer.GetRed();
|
|
52 const unsigned int green = layer.GetGreen();
|
|
53 const unsigned int blue = layer.GetBlue();
|
|
54
|
|
55 for (unsigned int y = 0; y < source->GetHeight(); y++)
|
|
56 {
|
|
57 const uint8_t* p = reinterpret_cast<const uint8_t*>(source->GetConstRow(y));
|
|
58 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
|
|
59
|
|
60 for (unsigned int x = 0; x < width; x++)
|
|
61 {
|
|
62 unsigned int alpha = *p;
|
|
63
|
|
64 // Premultiplied alpha
|
|
65 q[0] = static_cast<uint8_t>((blue * alpha) / 255);
|
|
66 q[1] = static_cast<uint8_t>((green * alpha) / 255);
|
|
67 q[2] = static_cast<uint8_t>((red * alpha) / 255);
|
|
68 q[3] = *p;
|
|
69
|
|
70 p++;
|
|
71 q += 4;
|
|
72 }
|
|
73 }
|
|
74
|
|
75 cairo_surface_mark_dirty(text_.GetObject());
|
|
76 }
|
|
77 }
|
|
78
|
|
79
|
|
80 void CairoTextRenderer::Render(const AffineTransform2D& transform)
|
|
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.GetRedAsFloat(), layer.GetGreenAsFloat(), layer.GetBlueAsFloat());
|
|
89
|
|
90 double dx, dy; // In pixels
|
|
91 ComputeAnchorTranslation(dx, dy, layer.GetAnchor(), text_.GetWidth(),
|
|
92 text_.GetHeight(), layer.GetBorder());
|
|
93
|
|
94 double x = layer.GetX();
|
|
95 double y = layer.GetY();
|
|
96 transform.Apply(x, y);
|
|
97
|
|
98 cairo_save(cr);
|
|
99
|
|
100 cairo_matrix_t t;
|
|
101 cairo_matrix_init_identity(&t);
|
|
102 cairo_matrix_translate(&t, x + dx, y + dy);
|
|
103 cairo_transform(cr, &t);
|
|
104
|
|
105 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
|
|
106 cairo_set_source_surface(cr, text_.GetObject(), 0, 0);
|
|
107 cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BILINEAR);
|
|
108 cairo_paint(cr);
|
|
109
|
|
110 cairo_restore(cr);
|
|
111 }
|
|
112 }
|
|
113 }
|
|
114 }
|