comparison Framework/Fonts/GlyphAlphabet.cpp @ 576:529c9617654b

FontRenderer
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 19 Apr 2019 15:11:16 +0200
parents
children 1091b2adeb5a
comparison
equal deleted inserted replaced
575:919226caca82 576:529c9617654b
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 "GlyphAlphabet.h"
23
24 #include <Core/OrthancException.h>
25 #include <Core/Toolbox.h>
26
27
28 namespace OrthancStone
29 {
30 void GlyphAlphabet::Clear()
31 {
32 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
33 {
34 assert(it->second != NULL);
35 delete it->second;
36 }
37
38 content_.clear();
39 lineHeight_ = 0;
40 }
41
42
43 void GlyphAlphabet::Register(uint32_t unicode,
44 const Glyph& glyph,
45 Orthanc::IDynamicObject* payload)
46 {
47 std::auto_ptr<Orthanc::IDynamicObject> protection(payload);
48
49 // Don't add twice the same character
50 if (content_.find(unicode) == content_.end())
51 {
52 std::auto_ptr<Glyph> raii(new Glyph(glyph));
53
54 if (payload != NULL)
55 {
56 raii->SetPayload(protection.release());
57 }
58
59 content_[unicode] = raii.release();
60
61 lineHeight_ = std::max(lineHeight_, glyph.GetLineHeight());
62 }
63 }
64
65
66 void GlyphAlphabet::Register(FontRenderer& renderer,
67 uint32_t unicode)
68 {
69 std::auto_ptr<Glyph> glyph(renderer.Render(unicode));
70
71 if (glyph.get() != NULL)
72 {
73 Register(unicode, *glyph, glyph->ReleasePayload());
74 }
75 }
76
77
78 #if ORTHANC_ENABLE_LOCALE == 1
79 bool GlyphAlphabet::GetUnicodeFromCodepage(uint32_t& unicode,
80 unsigned int index,
81 Orthanc::Encoding encoding)
82 {
83 if (index > 255)
84 {
85 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
86 }
87
88 std::string character;
89 character.resize(1);
90 character[0] = static_cast<unsigned char>(index);
91
92 std::string utf8 = Orthanc::Toolbox::ConvertToUtf8(character, encoding, false /* no code extensions */);
93
94 if (utf8.empty())
95 {
96 // This character is not available in this codepage
97 return false;
98 }
99 else
100 {
101 size_t length;
102 Orthanc::Toolbox::Utf8ToUnicodeCharacter(unicode, length, utf8, 0);
103 assert(length != 0);
104 return true;
105 }
106 }
107 #endif
108
109
110 void GlyphAlphabet::Apply(IGlyphVisitor& visitor) const
111 {
112 for (Content::const_iterator it = content_.begin(); it != content_.end(); ++it)
113 {
114 assert(it->second != NULL);
115 visitor.Visit(it->first, *it->second);
116 }
117 }
118
119
120 void GlyphAlphabet::Apply(ITextVisitor& visitor,
121 const std::string& utf8) const
122 {
123 size_t pos = 0;
124 int x = 0;
125 int y = 0;
126
127 while (pos < utf8.size())
128 {
129 if (utf8[pos] == '\r')
130 {
131 // Ignore carriage return
132 pos++;
133 }
134 else if (utf8[pos] == '\n')
135 {
136 // This is a newline character
137 x = 0;
138 y += static_cast<int>(lineHeight_);
139
140 pos++;
141 }
142 else
143 {
144 uint32_t unicode;
145 size_t length;
146 Orthanc::Toolbox::Utf8ToUnicodeCharacter(unicode, length, utf8, pos);
147
148 Content::const_iterator glyph = content_.find(unicode);
149
150 if (glyph != content_.end())
151 {
152 assert(glyph->second != NULL);
153 const Orthanc::IDynamicObject* payload =
154 (glyph->second->HasPayload() ? &glyph->second->GetPayload() : NULL);
155
156 visitor.Visit(unicode,
157 x + glyph->second->GetOffsetLeft(),
158 y + glyph->second->GetOffsetTop(),
159 glyph->second->GetWidth(),
160 glyph->second->GetHeight(),
161 payload);
162 x += glyph->second->GetAdvanceX();
163 }
164
165 assert(length != 0);
166 pos += length;
167 }
168 }
169 }
170 }