1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7
8 #include "shapedtext.h"
9
10 #include <QSharedData>
11
12
13 class ShapedTextImplementation : QSharedData
14 {
15
16 public:
ShapedTextImplementation(ITextSource * src,int firstChar,int lastChar,ITextContext * ctx)17 ShapedTextImplementation(ITextSource* src, int firstChar, int lastChar, ITextContext* ctx) : m_needsContext(false), m_source(src), m_context(ctx)
18 {
19 m_firstChar = firstChar;
20 m_lastChar = lastChar < 0? src->length() - 1 : lastChar;
21 }
22
ShapedTextImplementation(const ShapedTextImplementation & o)23 ShapedTextImplementation(const ShapedTextImplementation& o) : m_needsContext(o.m_needsContext), m_source(o.m_source), m_context(o.m_context), m_firstChar(o.m_firstChar), m_lastChar(o.m_lastChar),m_glyphs(o.m_glyphs)
24 {}
25
26
27 bool m_needsContext;
28 const ITextSource* m_source;
29 const ITextContext* m_context;
30 int m_firstChar;
31 int m_lastChar;
32 QList<GlyphCluster> m_glyphs;
33
34 /** only possible if it also cleanly splits the textsource */
canSplit(int charPos) const35 bool canSplit(int charPos) const
36 {
37 return splitPosition(charPos) >= 0;
38 }
39
split(int charPos)40 ShapedText split(int charPos)
41 {
42 int pos = splitPosition(charPos);
43 this->m_lastChar = charPos - 1;
44 this->m_glyphs.erase(this->m_glyphs.begin() + pos, this->m_glyphs.end());
45
46 ShapedTextImplementation* result = new ShapedTextImplementation(*this);
47 result->m_firstChar = charPos;
48 result->m_glyphs.erase(result->m_glyphs.begin(), result->m_glyphs.begin() + pos);
49 return ShapedText(result);
50 }
51
52 /** only possible if they are adjacent pieces of the same text source */
canCombine(const QSharedPointer<ShapedTextImplementation> other) const53 bool canCombine(const QSharedPointer<ShapedTextImplementation> other) const
54 {
55 return false; // TODO: implement
56 }
57
combine(QSharedPointer<ShapedTextImplementation> other)58 void combine(QSharedPointer<ShapedTextImplementation> other)
59 {
60 // TODO: implement
61 }
62
63 private:
64
splitPosition(int charPos) const65 int splitPosition(int charPos) const
66 {
67 int result = 0;
68 while (result < m_glyphs.count() && m_glyphs[result].lastChar() < charPos)
69 ++result;
70 for (int check = result + 1; check < m_glyphs.count(); ++check)
71 {
72 if (m_glyphs[check].firstChar() < charPos)
73 return -1;
74 }
75 return result;
76 }
77 };
78
79
80
81 ShapedText ShapedText::Invalid = ShapedText(nullptr);
82
isValid() const83 bool ShapedText::isValid() const
84 {
85 return p_impl != nullptr && p_impl->m_source != nullptr;
86 }
87
88
ShapedText(ShapedTextImplementation * my_p_impl)89 ShapedText::ShapedText(ShapedTextImplementation* my_p_impl) : p_impl(my_p_impl) {}
ShapedText(ITextSource * src,int firstChar,int lastChar,ITextContext * ctx)90 ShapedText::ShapedText(ITextSource* src, int firstChar, int lastChar, ITextContext* ctx) : p_impl(new ShapedTextImplementation(src,firstChar,lastChar,ctx)) {}
ShapedText(const ShapedText & other)91 ShapedText::ShapedText(const ShapedText& other) : p_impl(other.p_impl) {}
92
needsContext() const93 bool ShapedText::needsContext() const { return p_impl->m_needsContext; }
needsContext(bool b)94 void ShapedText::needsContext(bool b) { p_impl->m_needsContext = b; }
source() const95 const ITextSource* ShapedText::source() const { return p_impl->m_source; }
firstChar() const96 int ShapedText::firstChar() const { return p_impl->m_firstChar; }
lastChar() const97 int ShapedText::lastChar() const { return p_impl->m_lastChar; }
glyphs() const98 const QList<GlyphCluster>& ShapedText::glyphs() const { return p_impl->m_glyphs; }
glyphs()99 QList<GlyphCluster>& ShapedText::glyphs() { return p_impl->m_glyphs; }
100
canSplit(int pos) const101 bool ShapedText::canSplit(int pos) const { return p_impl->canSplit(pos); }
split(int pos)102 ShapedText ShapedText::split(int pos) { return p_impl->split(pos); }
canCombine(const ShapedText & other) const103 bool ShapedText::canCombine(const ShapedText& other) const { return p_impl->canCombine(other.p_impl); }
combine(ShapedText & other)104 void ShapedText::combine(ShapedText& other) { p_impl->combine(other.p_impl); }
105
106