comparison Framework/Wrappers/CairoSurface.cpp @ 807:c237e0625065

deprecating CairoFont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 28 May 2019 17:44:53 +0200
parents Framework/Viewport/CairoSurface.cpp@aaeec7be8fb7
children 2d8ab34c8c91
comparison
equal deleted inserted replaced
806:f4d64e088838 807:c237e0625065
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 "CairoSurface.h"
23
24 #include <Core/Logging.h>
25 #include <Core/OrthancException.h>
26 #include <Core/Images/ImageProcessing.h>
27
28 namespace OrthancStone
29 {
30 void CairoSurface::Release()
31 {
32 if (surface_)
33 {
34 cairo_surface_destroy(surface_);
35 surface_ = NULL;
36 }
37 }
38
39
40 void CairoSurface::Allocate(unsigned int width,
41 unsigned int height,
42 bool hasAlpha)
43 {
44 Release();
45
46 hasAlpha_ = hasAlpha;
47
48 surface_ = cairo_image_surface_create
49 (hasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
50 if (!surface_)
51 {
52 // Should never occur
53 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
54 }
55
56 if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS)
57 {
58 LOG(ERROR) << "Cannot create a Cairo surface";
59 cairo_surface_destroy(surface_);
60 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
61 }
62
63 width_ = width;
64 height_ = height;
65 pitch_ = cairo_image_surface_get_stride(surface_);
66 buffer_ = cairo_image_surface_get_data(surface_);
67 }
68
69
70 CairoSurface::CairoSurface(Orthanc::ImageAccessor& accessor,
71 bool hasAlpha) :
72 hasAlpha_(hasAlpha)
73 {
74 if (accessor.GetFormat() != Orthanc::PixelFormat_BGRA32)
75 {
76 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
77 }
78
79 width_ = accessor.GetWidth();
80 height_ = accessor.GetHeight();
81 pitch_ = accessor.GetPitch();
82 buffer_ = accessor.GetBuffer();
83
84 surface_ = cairo_image_surface_create_for_data
85 (reinterpret_cast<unsigned char*>(buffer_),
86 hasAlpha_ ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
87 width_, height_, pitch_);
88 if (!surface_)
89 {
90 // Should never occur
91 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
92 }
93
94 if (cairo_surface_status(surface_) != CAIRO_STATUS_SUCCESS)
95 {
96 LOG(ERROR) << "Bad pitch for a Cairo surface";
97 cairo_surface_destroy(surface_);
98 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
99 }
100 }
101
102
103 void CairoSurface::SetSize(unsigned int width,
104 unsigned int height,
105 bool hasAlpha)
106 {
107 if (hasAlpha_ != hasAlpha ||
108 width_ != width ||
109 height_ != height)
110 {
111 Allocate(width, height, hasAlpha);
112 }
113 }
114
115
116 void CairoSurface::Copy(const CairoSurface& other)
117 {
118 SetSize(other.GetWidth(), other.GetHeight(), other.HasAlpha());
119
120 Orthanc::ImageAccessor source, target;
121
122 other.GetReadOnlyAccessor(source);
123 GetWriteableAccessor(target);
124
125 Orthanc::ImageProcessing::Copy(target, source);
126
127 cairo_surface_mark_dirty(surface_);
128 }
129
130
131 void CairoSurface::Copy(const Orthanc::ImageAccessor& source,
132 bool hasAlpha)
133 {
134 SetSize(source.GetWidth(), source.GetHeight(), hasAlpha);
135
136 Orthanc::ImageAccessor target;
137 GetWriteableAccessor(target);
138
139 Orthanc::ImageProcessing::Convert(target, source);
140
141 cairo_surface_mark_dirty(surface_);
142 }
143
144
145 void CairoSurface::GetReadOnlyAccessor(Orthanc::ImageAccessor& target) const
146 {
147 target.AssignReadOnly(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_);
148 }
149
150
151 void CairoSurface::GetWriteableAccessor(Orthanc::ImageAccessor& target)
152 {
153 target.AssignWritable(Orthanc::PixelFormat_BGRA32, width_, height_, pitch_, buffer_);
154 }
155 }