1 #include "glyphcluster.h"
2 
GlyphCluster(const CharStyle * style,LayoutFlags flags,int first,int last,const InlineFrame & o,int i,const QString & str)3 GlyphCluster::GlyphCluster(const CharStyle* style, LayoutFlags flags, int first, int last, const InlineFrame& o, int i, const QString& str)
4 	: extraWidth(0.0)
5 	, xoffset(0.0)
6 	, yoffset(0.0)
7 	, m_style(style)
8 	, m_flags(flags)
9 	, m_object(o)
10 	, m_firstChar(first)
11 	, m_lastChar(last)
12 	, m_visualIndex(i)
13 	, m_scaleH(1.0)
14 	, m_scaleV(1.0)
15 	, m_str(str)
16 {}
17 
append(GlyphLayout & gl)18 void GlyphCluster::append(GlyphLayout& gl)
19 {
20 	gl.scaleH = m_scaleH;
21 	gl.scaleV = m_scaleV;
22 	m_glyphs.append(gl);
23 }
24 
width() const25 double GlyphCluster::width() const
26 {
27 	double width = 0;
28 	for (const GlyphLayout& gl : m_glyphs)
29 	{
30 		width += gl.xadvance * m_scaleH;
31 	}
32 	return width + extraWidth;
33 }
34 
ascent() const35 double GlyphCluster::ascent() const
36 {
37 	const ScFace &font = m_style->font();
38 	double asc = 0;
39 	for (const GlyphLayout& gl : m_glyphs)
40 	{
41 		GlyphMetrics gm = font.glyphBBox(gl.glyph, m_style->fontSize() / 10.0);
42 		asc = qMax(asc, gm.ascent * m_scaleV);
43 	}
44 	return asc;
45 }
46 
descent() const47 double GlyphCluster::descent() const
48 {
49 	const ScFace &font = m_style->font();
50 	double des = 0;
51 	for (const GlyphLayout& gl : m_glyphs)
52 	{
53 		GlyphMetrics gm = font.glyphBBox(gl.glyph, m_style->fontSize() / 10.0);
54 		des = qMax(des, gm.descent * m_scaleV);
55 	}
56 	return -des;
57 }
58 
style() const59 const CharStyle& GlyphCluster::style() const
60 {
61 	return *m_style;
62 }
63 
hasFlag(LayoutFlags f) const64 bool GlyphCluster::hasFlag(LayoutFlags f) const
65 {
66 	return (m_flags & f) == f;
67 }
68 
setFlag(LayoutFlags f)69 void GlyphCluster::setFlag(LayoutFlags f)
70 {
71 	m_flags = static_cast<LayoutFlags>(m_flags | f);
72 	if (f == ScLayout_SuppressSpace)
73 	{
74 		for (int i = 0; i < m_glyphs.count(); i++)
75 		{
76 			GlyphLayout& gl = m_glyphs[i];
77 			gl.xadvance = 0;
78 		}
79 		extraWidth = 0;
80 	}
81 }
82 
clearFlag(LayoutFlags f)83 void GlyphCluster::clearFlag(LayoutFlags f)
84 {
85 	m_flags = static_cast<LayoutFlags>(m_flags & ~f);
86 }
87 
glyphs()88 QList<GlyphLayout>& GlyphCluster::glyphs()
89 {
90 	return m_glyphs;
91 }
92 
glyphs() const93 const QList<GlyphLayout>& GlyphCluster::glyphs() const {
94 	return m_glyphs;
95 }
96 
object() const97 const InlineFrame& GlyphCluster::object() const
98 {
99 	return m_object;
100 }
101 
firstChar() const102 int GlyphCluster::firstChar() const
103 {
104 	return m_firstChar;
105 }
106 
lastChar() const107 int GlyphCluster::lastChar() const
108 {
109 	return m_lastChar;
110 }
111 
visualIndex() const112 int GlyphCluster::visualIndex() const
113 {
114 	return m_visualIndex;
115 }
116 
scaleH() const117 double GlyphCluster::scaleH() const
118 {
119 	return m_scaleH;
120 }
121 
scaleV() const122 double GlyphCluster::scaleV() const
123 {
124 	return m_scaleV;
125 }
126 
setScaleH(double s)127 void GlyphCluster::setScaleH(double s)
128 {
129 	m_scaleH = s;
130 	for (int i = 0; i < m_glyphs.count(); i++)
131 	{
132 		GlyphLayout& gl = m_glyphs[i];
133 		gl.scaleH = m_scaleH;
134 	}
135 }
136 
setScaleV(double s)137 void GlyphCluster::setScaleV(double s)
138 {
139 	m_scaleV = s;
140 	for (int i = 0; i < m_glyphs.count(); i++)
141 	{
142 		GlyphLayout& gl = m_glyphs[i];
143 		gl.scaleV = m_scaleV;
144 	}
145 }
146 
isEmpty() const147 bool GlyphCluster::isEmpty() const
148 {
149 	return m_glyphs.size() == 1 && m_glyphs.first().glyph == 0;
150 }
151 
isControlGlyphs() const152 bool GlyphCluster::isControlGlyphs() const
153 {
154 	return m_glyphs.size() == 1 && m_glyphs.first().glyph >= ScFace::CONTROL_GLYPHS;
155 }
156 
isSpace() const157 bool GlyphCluster::isSpace() const
158 {
159 	return m_glyphs.size() == 1 && (hasFlag(ScLayout_ExpandingSpace) || hasFlag(ScLayout_FixedSpace) || hasFlag(ScLayout_ImplicitSpace));
160 }
161 
glyphClusterOutline() const162 QVector<FPointArray> GlyphCluster::glyphClusterOutline() const
163 {
164 	QVector<FPointArray> outline;
165 	const ScFace& face = m_style->font();
166 	for (const GlyphLayout& gl : m_glyphs)
167 	{
168 		outline.append(face.glyphOutline(gl.glyph));
169 	}
170 	return outline;
171 }
172 
getText() const173 QString GlyphCluster::getText() const
174 {
175 	return m_str;
176 }
177