xref: /haiku/src/apps/haikudepot/textview/CharacterStyle.cpp (revision 37fedaf8494b34aad811abcc49e79aa32943f880)
1 /*
2  * Copyright 2013, Stephan Aßmus <superstippi@gmx.de>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 #include "CharacterStyle.h"
7 
8 
9 CharacterStyle::CharacterStyle()
10 	:
11 	fStyleData(new CharacterStyleData(), true)
12 {
13 }
14 
15 
16 CharacterStyle::CharacterStyle(const CharacterStyle& other)
17 	:
18 	fStyleData(other.fStyleData)
19 {
20 }
21 
22 
23 CharacterStyle&
24 CharacterStyle::operator=(const CharacterStyle& other)
25 {
26 	if (this == &other)
27 		return *this;
28 
29 	fStyleData = other.fStyleData;
30 	return *this;
31 }
32 
33 
34 bool
35 CharacterStyle::operator==(const CharacterStyle& other) const
36 {
37 	if (this == &other)
38 		return true;
39 
40 	if (fStyleData == other.fStyleData)
41 		return true;
42 
43 	if (fStyleData.Get() != NULL && other.fStyleData.Get() != NULL)
44 		return *fStyleData.Get() == *other.fStyleData.Get();
45 
46 	return false;
47 }
48 
49 
50 bool
51 CharacterStyle::operator!=(const CharacterStyle& other) const
52 {
53 	return !(*this == other);
54 }
55 
56 
57 bool
58 CharacterStyle::SetFont(const BFont& font)
59 {
60 	CharacterStyleDataRef data = fStyleData->SetFont(font);
61 	if (data == fStyleData)
62 		return data->Font() == font;
63 
64 	fStyleData = data;
65 	return true;
66 }
67 
68 
69 const BFont&
70 CharacterStyle::Font() const
71 {
72 	return fStyleData->Font();
73 }
74 
75 
76 bool
77 CharacterStyle::SetFontSize(float size)
78 {
79 	BFont font(Font());
80 	font.SetSize(size);
81 	return SetFont(font);
82 }
83 
84 
85 float
86 CharacterStyle::FontSize() const
87 {
88 	return Font().Size();
89 }
90 
91 
92 bool
93 CharacterStyle::SetBold(bool bold)
94 {
95 	uint16 face = Font().Face();
96 	if ((bold && (face & B_BOLD_FACE) != 0)
97 		|| (!bold && (face & B_BOLD_FACE) == 0)) {
98 		return true;
99 	}
100 
101 	uint16 neededFace = face;
102 	if (bold) {
103 		if ((face & B_ITALIC_FACE) != 0)
104 			neededFace = B_BOLD_FACE | B_ITALIC_FACE;
105 		else
106 			neededFace = B_BOLD_FACE;
107 	} else {
108 		if ((face & B_ITALIC_FACE) != 0)
109 			neededFace = B_ITALIC_FACE;
110 		else
111 			neededFace = B_REGULAR_FACE;
112 	}
113 
114 	return SetFont(_FindFontForFace(neededFace));
115 }
116 
117 
118 bool
119 CharacterStyle::IsBold() const
120 {
121 	return (Font().Face() & B_BOLD_FACE) != 0;
122 }
123 
124 
125 bool
126 CharacterStyle::SetItalic(bool italic)
127 {
128 	uint16 face = Font().Face();
129 	if ((italic && (face & B_ITALIC_FACE) != 0)
130 		|| (!italic && (face & B_ITALIC_FACE) == 0)) {
131 		return true;
132 	}
133 
134 	uint16 neededFace = face;
135 	if (italic) {
136 		if ((face & B_BOLD_FACE) != 0)
137 			neededFace = B_BOLD_FACE | B_ITALIC_FACE;
138 		else
139 			neededFace = B_ITALIC_FACE;
140 	} else {
141 		if ((face & B_BOLD_FACE) != 0)
142 			neededFace = B_BOLD_FACE;
143 		else
144 			neededFace = B_REGULAR_FACE;
145 	}
146 
147 	return SetFont(_FindFontForFace(neededFace));
148 }
149 
150 
151 bool
152 CharacterStyle::IsItalic() const
153 {
154 	return (Font().Face() & B_ITALIC_FACE) != 0;
155 }
156 
157 
158 bool
159 CharacterStyle::SetAscent(float ascent)
160 {
161 	CharacterStyleDataRef data = fStyleData->SetAscent(ascent);
162 	if (data == fStyleData)
163 		return data->Ascent() == ascent;
164 
165 	fStyleData = data;
166 	return true;
167 }
168 
169 
170 float
171 CharacterStyle::Ascent() const
172 {
173 	return fStyleData->Ascent();
174 }
175 
176 
177 bool
178 CharacterStyle::SetDescent(float descent)
179 {
180 	CharacterStyleDataRef data = fStyleData->SetDescent(descent);
181 	if (data == fStyleData)
182 		return data->Descent() == descent;
183 
184 	fStyleData = data;
185 	return true;
186 }
187 
188 
189 float
190 CharacterStyle::Descent() const
191 {
192 	return fStyleData->Descent();
193 }
194 
195 
196 bool
197 CharacterStyle::SetWidth(float width)
198 {
199 	CharacterStyleDataRef data = fStyleData->SetWidth(width);
200 	if (data == fStyleData)
201 		return data->Width() == width;
202 
203 	fStyleData = data;
204 	return true;
205 }
206 
207 
208 float
209 CharacterStyle::Width() const
210 {
211 	return fStyleData->Width();
212 }
213 
214 
215 bool
216 CharacterStyle::SetGlyphSpacing(float spacing)
217 {
218 	CharacterStyleDataRef data = fStyleData->SetGlyphSpacing(spacing);
219 	if (data == fStyleData)
220 		return data->GlyphSpacing() == spacing;
221 
222 	fStyleData = data;
223 	return true;
224 }
225 
226 
227 float
228 CharacterStyle::GlyphSpacing() const
229 {
230 	return fStyleData->GlyphSpacing();
231 }
232 
233 
234 bool
235 CharacterStyle::SetForegroundColor(uint8 r, uint8 g, uint8 b, uint8 a)
236 {
237 	return SetForegroundColor((rgb_color){ r, g, b, a });
238 }
239 
240 
241 bool
242 CharacterStyle::SetForegroundColor(rgb_color color)
243 {
244 	CharacterStyleDataRef data = fStyleData->SetForegroundColor(color);
245 	if (data == fStyleData)
246 		return data->ForegroundColor() == color;
247 
248 	fStyleData = data;
249 	return true;
250 }
251 
252 
253 rgb_color
254 CharacterStyle::ForegroundColor() const
255 {
256 	return fStyleData->ForegroundColor();
257 }
258 
259 
260 bool
261 CharacterStyle::SetBackgroundColor(uint8 r, uint8 g, uint8 b, uint8 a)
262 {
263 	return SetBackgroundColor((rgb_color){ r, g, b, a });
264 }
265 
266 
267 bool
268 CharacterStyle::SetBackgroundColor(rgb_color color)
269 {
270 	CharacterStyleDataRef data = fStyleData->SetBackgroundColor(color);
271 	if (data == fStyleData)
272 		return data->BackgroundColor() == color;
273 
274 	fStyleData = data;
275 	return true;
276 }
277 
278 
279 rgb_color
280 CharacterStyle::BackgroundColor() const
281 {
282 	return fStyleData->BackgroundColor();
283 }
284 
285 
286 bool
287 CharacterStyle::SetStrikeOutColor(rgb_color color)
288 {
289 	CharacterStyleDataRef data = fStyleData->SetStrikeOutColor(color);
290 	if (data == fStyleData)
291 		return data->StrikeOutColor() == color;
292 
293 	fStyleData = data;
294 	return true;
295 }
296 
297 
298 rgb_color
299 CharacterStyle::StrikeOutColor() const
300 {
301 	return fStyleData->StrikeOutColor();
302 }
303 
304 
305 bool
306 CharacterStyle::SetUnderlineColor(rgb_color color)
307 {
308 	CharacterStyleDataRef data = fStyleData->SetUnderlineColor(color);
309 	if (data == fStyleData)
310 		return data->UnderlineColor() == color;
311 
312 	fStyleData = data;
313 	return true;
314 }
315 
316 
317 rgb_color
318 CharacterStyle::UnderlineColor() const
319 {
320 	return fStyleData->UnderlineColor();
321 }
322 
323 
324 bool
325 CharacterStyle::SetStrikeOut(uint8 strikeOut)
326 {
327 	CharacterStyleDataRef data = fStyleData->SetStrikeOut(strikeOut);
328 	if (data == fStyleData)
329 		return data->StrikeOut() == strikeOut;
330 
331 	fStyleData = data;
332 	return true;
333 }
334 
335 
336 uint8
337 CharacterStyle::StrikeOut() const
338 {
339 	return fStyleData->StrikeOut();
340 }
341 
342 
343 bool
344 CharacterStyle::SetUnderline(uint8 underline)
345 {
346 	CharacterStyleDataRef data = fStyleData->SetUnderline(underline);
347 	if (data == fStyleData)
348 		return data->Underline() == underline;
349 
350 	fStyleData = data;
351 	return true;
352 }
353 
354 
355 uint8
356 CharacterStyle::Underline() const
357 {
358 	return fStyleData->Underline();
359 }
360 
361 
362 // #pragma mark - private
363 
364 
365 BFont
366 CharacterStyle::_FindFontForFace(uint16 face) const
367 {
368 	BFont font(Font());
369 
370 	font_family family;
371 	font_style style;
372 	font.GetFamilyAndStyle(&family, &style);
373 
374 	int32 styleCount = count_font_styles(family);
375 	for (int32 i = 0; i < styleCount; i++) {
376 		uint16 styleFace;
377 		if (get_font_style(family, i, &style, &styleFace) == B_OK) {
378 			if (styleFace == face) {
379 				font.SetFamilyAndStyle(family, style);
380 				return font;
381 			}
382 		}
383 	}
384 
385 	return font;
386 }
387 
388