libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNAltoStyles.cpp
Go to the documentation of this file.
1 /* Copyright 2011-2016 CoReNum
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNAltoStyles.cpp
19  * \author Yann LEYDIER
20  */
21 
22 #include <CRNXml/CRNAlto.h>
23 #include <CRNException.h>
24 #include <CRNString.h>
25 #include <CRNi18n.h>
26 
27 using namespace crn;
28 using namespace xml;
29 
33 Alto::Styles::Styles(const Element &el):
34  Element(el)
35 {
36  for (Element el = BeginElement(); el != EndElement(); ++el)
37  {
38  StringUTF8 elname = el.GetName();
39  if (elname == "TextStyle")
40  {
41  std::unique_ptr<Text> t(new Text(el));
42  textStyles.insert(std::make_pair(t->GetId(), std::move(t)));
43  }
44  else if (elname == "ParagraphStyle")
45  {
46  std::unique_ptr<Paragraph> p(new Paragraph(el));
47  parStyles.insert(std::make_pair(p->GetId(), std::move(p)));
48  }
49  }
50 }
51 
53 std::vector<Id> Alto::Styles::GetTextStyles() const
54 {
55  std::vector<Id> styles;
56  for (std::map<Id, std::unique_ptr<Text> >::const_iterator it = textStyles.begin(); it != textStyles.end(); ++it)
57  {
58  styles.push_back(it->first);
59  }
60  return styles;
61 }
62 
64 std::vector<Id> Alto::Styles::GetParagraphStyles() const
65 {
66  std::vector<Id> styles;
67  for (std::map<Id, std::unique_ptr<Paragraph> >::const_iterator it = parStyles.begin(); it != parStyles.end(); ++it)
68  {
69  styles.push_back(it->first);
70  }
71  return styles;
72 }
73 
79 const Alto::Styles::Text& Alto::Styles::GetTextStyle(const Id &id_) const
80 {
81  std::map<Id, std::unique_ptr<Text> >::const_iterator it = textStyles.find(id_);
82  if (it != textStyles.end())
83  return *(it->second);
84  else
85  throw ExceptionNotFound(_("Text style not found."));
86 }
87 
93 Alto::Styles::Text& Alto::Styles::GetTextStyle(const Id &id_)
94 {
95  std::map<Id, std::unique_ptr<Text> >::iterator it = textStyles.find(id_);
96  if (it != textStyles.end())
97  return *(it->second);
98  else
99  throw ExceptionNotFound(_("Text style not found."));
100 }
101 
106 Alto::Styles::Text& Alto::Styles::AddTextStyle(const Id &id_, double size)
107 {
108  Element el(PushBackElement("TextStyle"));
109  el.SetAttribute("ID", id_);
110  el.SetAttribute("FONTSIZE", size);
111  auto res = textStyles.insert(std::make_pair(id_, std::unique_ptr<Text>(new Text(el))));
112  return *res.first->second;
113 }
114 
120 const Alto::Styles::Paragraph& Alto::Styles::GetParagraphStyle(const Id &id_) const
121 {
122  std::map<Id, std::unique_ptr<Paragraph> >::const_iterator it = parStyles.find(id_);
123  if (it != parStyles.end())
124  return *(it->second);
125  else
126  throw ExceptionNotFound(_("Paragraph style not found."));
127 }
128 
134 Alto::Styles::Paragraph& Alto::Styles::GetParagraphStyle(const Id &id_)
135 {
136  std::map<Id, std::unique_ptr<Paragraph> >::iterator it = parStyles.find(id_);
137  if (it != parStyles.end())
138  return *(it->second);
139  else
140  throw ExceptionNotFound(_("Paragraph style not found."));
141 }
142 
146 Alto::Styles::Paragraph& Alto::Styles::AddParagraphStyle(const Id &id_)
147 {
148  Element el(PushBackElement("ParagraphStyle"));
149  el.SetAttribute("ID", id_);
150  auto res = parStyles.insert(std::make_pair(id_, std::unique_ptr<Paragraph>(new Paragraph(el))));
151  return *res.first->second;
152 }
153 
155 // Text
157 
158 Alto::Styles::Text::Text(const Element &el):
159  Element(el)
160 {
161  id = GetAttribute<StringUTF8>("ID", false); // may throw
162  GetAttribute<double>("FONTSIZE", false); // may throw
163 }
164 
165 Option<StringUTF8> Alto::Styles::Text::GetFontFamily() const
166 {
168  StringUTF8 str = GetAttribute<StringUTF8>("FONTFAMILY");
169  if (str.IsNotEmpty())
170  ff = str;
171  return ff;
172 }
173 
174 void Alto::Styles::Text::SetFontFamily(const StringUTF8 &ff)
175 {
176  SetAttribute("FONTFAMILY", ff);
177 }
178 
179 void Alto::Styles::Text::UnsetFontFamily()
180 {
181  RemoveAttribute("FONTFAMILY");
182 }
183 
184 Option<Alto::Styles::Text::FontType> Alto::Styles::Text::GetFontType() const
185 {
186  Option<FontType> fontType;
187  StringUTF8 str = GetAttribute<StringUTF8>("FONTTYPE");
188  if (str.IsNotEmpty())
189  {
190  if (str == "serif")
191  fontType = Text::FontType::Serif;
192  else if (str == "sans-serif")
193  fontType = Text::FontType::SansSerif;
194  }
195  return fontType;
196 }
197 
198 void Alto::Styles::Text::SetFontType(Alto::Styles::Text::FontType ft)
199 {
200  switch (ft)
201  {
202  case Text::FontType::Serif:
203  SetAttribute("FONTTYPE", "Serif");
204  break;
205  case Text::FontType::SansSerif:
206  SetAttribute("FONTTYPE", "Sans-Serif");
207  break;
208  }
209 }
210 
211 void Alto::Styles::Text::UnsetFontType()
212 {
213  RemoveAttribute("FONTTYPE");
214 }
215 
216 Option<Alto::Styles::Text::FontWidth> Alto::Styles::Text::GetFontWidth() const
217 {
218  Option<FontWidth> fontWidth;
219  StringUTF8 str = GetAttribute<StringUTF8>("FONTWIDTH");
220  if (str.IsNotEmpty())
221  {
222  if (str == "proporitional")
223  fontWidth = Text::FontWidth::Proportional;
224  else if (str == "fixed")
225  fontWidth = Text::FontWidth::Fixed;
226  }
227  return fontWidth;
228 }
229 
230 void Alto::Styles::Text::SetFontWidth(Alto::Styles::Text::FontWidth fw)
231 {
232  switch (fw)
233  {
234  case Text::FontWidth::Proportional:
235  SetAttribute("FONTWIDTH", "proportional");
236  break;
237  case Text::FontWidth::Fixed:
238  SetAttribute("FONTWIDTH", "fixed");
239  break;
240  }
241 }
242 
243 void Alto::Styles::Text::UnsetFontWidth()
244 {
245  RemoveAttribute("FONTWIDTH");
246 }
247 
248 double Alto::Styles::Text::GetFontSize() const
249 {
250  return GetAttribute<double>("FONTSIZE", false); // should not throw…
251 }
252 
253 void Alto::Styles::Text::SetFontSize(double fs)
254 {
255  SetAttribute("FONTSIZE", fs);
256 }
257 
258 Option<uint32_t> Alto::Styles::Text::GetFontColor() const
259 {
260  Option<uint32_t> fontColor;
261  try { fontColor = GetAttribute<unsigned int>("FONTCOLOR", false); } catch (...) { }
262  return fontColor;
263 }
264 
265 void Alto::Styles::Text::SetFontColor(uint32_t fc)
266 {
267  SetAttribute("FONTCOLOR", fc);
268 }
269 
270 void Alto::Styles::Text::UnsetFontColor()
271 {
272  RemoveAttribute("FONTCOLOR");
273 }
274 
275 Option<Alto::Styles::Text::FontStyle> Alto::Styles::Text::GetFontStyle() const
276 {
277  Option<FontStyle> fontStyle;
278  StringUTF8 str = GetAttribute<StringUTF8>("FONTSTYLE");
279  if (str.IsNotEmpty())
280  {
281  FontStyle val = FontStyle::Undef;
282  if (str.Find("bold") != String::NPos())
283  val |= Text::FontStyle::Bold;
284  if (str.Find("italics") != String::NPos())
285  val |= Text::FontStyle::Italics;
286  if (str.Find("subscript") != String::NPos())
287  val |= Text::FontStyle::Subscript;
288  if (str.Find("superscript") != String::NPos())
289  val |= Text::FontStyle::Superscript;
290  if (str.Find("smallcaps") != String::NPos())
291  val |= Text::FontStyle::SmallCaps;
292  if (str.Find("underline") != String::NPos())
293  val |= Text::FontStyle::Underline;
294  if (val != FontStyle::Undef)
295  fontStyle = val;
296  }
297  return fontStyle;
298 }
299 
300 void Alto::Styles::Text::SetFontStyle(Alto::Styles::Text::FontStyle fs)
301 {
302  StringUTF8 av;
303  if (!!(fs & Text::FontStyle::Bold))
304  av += "bold ";
305  if (!!(fs & Text::FontStyle::Italics))
306  av += "italics ";
307  if (!!(fs & Text::FontStyle::Subscript))
308  av += "subscript ";
309  if (!!(fs & Text::FontStyle::Superscript))
310  av += "superscript ";
311  if (!!(fs & Text::FontStyle::SmallCaps))
312  av += "smallcaps ";
313  if (!!(fs & Text::FontStyle::Underline))
314  av += "undunderline ";
315  SetAttribute("FONTSTYLE", av);
316 }
317 
318 void Alto::Styles::Text::UnsetFontStyle()
319 {
320  RemoveAttribute("FontStyle");
321 }
322 
324 // Paragraph
326 
327 Alto::Styles::Paragraph::Paragraph(const Element &el):
328  Element(el)
329 {
330  id = GetAttribute<StringUTF8>("ID", false); // may throw
331 }
332 
333 Option<Alto::Styles::Paragraph::Align> Alto::Styles::Paragraph::GetAlign() const
334 {
335  Option<Align> align;
336  StringUTF8 str(GetAttribute<StringUTF8>("ALIGN"));
337  if (str.IsNotEmpty())
338  {
339  if (str == "Left")
340  align = Paragraph::Align::Left;
341  else if (str == "Right")
342  align = Paragraph::Align::Right;
343  else if (str == "Center")
344  align = Paragraph::Align::Center;
345  else if (str == "Block")
346  align = Paragraph::Align::Block;
347  }
348  return align;
349 }
350 
351 void Alto::Styles::Paragraph::SetAlign(Alto::Styles::Paragraph::Align a)
352 {
353  switch (a)
354  {
355  case Paragraph::Align::Left:
356  SetAttribute("ALIGN", "Left");
357  break;
358  case Paragraph::Align::Right:
359  SetAttribute("ALIGN", "Right");
360  break;
361  case Paragraph::Align::Center:
362  SetAttribute("ALIGN", "Center");
363  break;
364  case Paragraph::Align::Block:
365  SetAttribute("ALIGN", "Block");
366  break;
367  }
368 }
369 
370 void Alto::Styles::Paragraph::UnsetAlign()
371 {
372  RemoveAttribute("ALIGN");
373 }
374 
375 Option<double> Alto::Styles::Paragraph::GetLeftIndent() const
376 {
377  Option<double> leftIndent;
378  try { leftIndent = GetAttribute<double>("LEFT", false); } catch (...) { }
379  return leftIndent;
380 }
381 
382 void Alto::Styles::Paragraph::UnsetLeftIndent()
383 {
384  RemoveAttribute("LEFT");
385 }
386 
387 void Alto::Styles::Paragraph::SetLeftIndent(double i)
388 {
389  SetAttribute("LEFT", i);
390 }
391 
392 Option<double> Alto::Styles::Paragraph::GetRightIndent() const
393 {
394  Option<double> rightIndent;
395  try { rightIndent = GetAttribute<double>("RIGHT", false); } catch (...) { }
396  return rightIndent;
397 }
398 
399 void Alto::Styles::Paragraph::SetRightIndent(double i)
400 {
401  SetAttribute("RIGHT", i);
402 }
403 
404 void Alto::Styles::Paragraph::UnsetRightIndent()
405 {
406  RemoveAttribute("RIGHT");
407 }
408 
409 Option<double> Alto::Styles::Paragraph::GetLineSpace() const
410 {
411  Option<double> ls;
412  try { ls = GetAttribute<double>("LINESPACE", false); } catch (...) { }
413  return ls;
414 }
415 
416 void Alto::Styles::Paragraph::SetLineSpace(double i)
417 {
418  SetAttribute("LINESPACE", i);
419 }
420 
421 void Alto::Styles::Paragraph::UnsetLineSpace()
422 {
423  RemoveAttribute("LINESPACE");
424 }
425 
426 Option<double> Alto::Styles::Paragraph::GetFirstLineIndent() const
427 {
428  Option<double> fli;
429  try { fli = GetAttribute<double>("FIRSTLINE", false); } catch (...) { }
430  return fli;
431 }
432 
433 void Alto::Styles::Paragraph::SetFirstLineIndent(double i)
434 {
435  SetAttribute("FIRSTLINE", i);
436 }
437 
438 void Alto::Styles::Paragraph::UnsetFirstLineIndent()
439 {
440  RemoveAttribute("FIRSTLINE");
441 }
442 
XML element.
Definition: CRNXml.h:135
StringUTF8 GetName() const
Gets the label of the element.
Definition: CRNXml.h:146
#define _(String)
Definition: CRNi18n.h:51
bool IsNotEmpty() const noexcept
Checks if the string is not empty.
XML text.
Definition: CRNXml.h:394
void SetAttribute(const StringUTF8 &name, const StringUTF8 &value)
Sets the value of an attribute.
Definition: CRNXml.cpp:595
A character string class.
Definition: CRNStringUTF8.h:49
size_t Find(const StringUTF8 &s, size_t from_pos=0) const
Finds the first occurrence of a string.
A class to store an optional value.
Definition: CRNOption.h:33
An item was not found in a container.
Definition: CRNException.h:95