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.IsSet() && other.fStyleData.IsSet()) 44 return *fStyleData == *other.fStyleData; 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(color_which which) 243 { 244 CharacterStyleDataRef data = fStyleData->SetForegroundColor(which); 245 if (data == fStyleData) 246 return data->WhichForegroundColor() == which; 247 248 fStyleData = data; 249 return true; 250 } 251 252 253 bool 254 CharacterStyle::SetForegroundColor(rgb_color color) 255 { 256 CharacterStyleDataRef data = fStyleData->SetForegroundColor(color); 257 if (data == fStyleData) 258 return data->ForegroundColor() == color; 259 260 fStyleData = data; 261 return true; 262 } 263 264 265 rgb_color 266 CharacterStyle::ForegroundColor() const 267 { 268 return fStyleData->ForegroundColor(); 269 } 270 271 272 color_which 273 CharacterStyle::WhichForegroundColor() const 274 { 275 return fStyleData->WhichForegroundColor(); 276 } 277 278 279 bool 280 CharacterStyle::SetBackgroundColor(uint8 r, uint8 g, uint8 b, uint8 a) 281 { 282 return SetBackgroundColor((rgb_color){ r, g, b, a }); 283 } 284 285 286 bool 287 CharacterStyle::SetBackgroundColor(color_which which) 288 { 289 CharacterStyleDataRef data = fStyleData->SetBackgroundColor(which); 290 if (data == fStyleData) 291 return data->WhichBackgroundColor() == which; 292 293 fStyleData = data; 294 return true; 295 } 296 297 298 bool 299 CharacterStyle::SetBackgroundColor(rgb_color color) 300 { 301 CharacterStyleDataRef data = fStyleData->SetBackgroundColor(color); 302 if (data == fStyleData) 303 return data->BackgroundColor() == color; 304 305 fStyleData = data; 306 return true; 307 } 308 309 310 rgb_color 311 CharacterStyle::BackgroundColor() const 312 { 313 return fStyleData->BackgroundColor(); 314 } 315 316 317 color_which 318 CharacterStyle::WhichBackgroundColor() const 319 { 320 return fStyleData->WhichBackgroundColor(); 321 } 322 323 324 bool 325 CharacterStyle::SetStrikeOutColor(color_which which) 326 { 327 CharacterStyleDataRef data = fStyleData->SetStrikeOutColor(which); 328 if (data == fStyleData) 329 return data->WhichStrikeOutColor() == which; 330 331 fStyleData = data; 332 return true; 333 } 334 335 336 bool 337 CharacterStyle::SetStrikeOutColor(rgb_color color) 338 { 339 CharacterStyleDataRef data = fStyleData->SetStrikeOutColor(color); 340 if (data == fStyleData) 341 return data->StrikeOutColor() == color; 342 343 fStyleData = data; 344 return true; 345 } 346 347 348 rgb_color 349 CharacterStyle::StrikeOutColor() const 350 { 351 return fStyleData->StrikeOutColor(); 352 } 353 354 355 color_which 356 CharacterStyle::WhichStrikeOutColor() const 357 { 358 return fStyleData->WhichStrikeOutColor(); 359 } 360 361 362 bool 363 CharacterStyle::SetUnderlineColor(color_which which) 364 { 365 CharacterStyleDataRef data = fStyleData->SetUnderlineColor(which); 366 if (data == fStyleData) 367 return data->WhichUnderlineColor() == which; 368 369 fStyleData = data; 370 return true; 371 } 372 373 374 bool 375 CharacterStyle::SetUnderlineColor(rgb_color color) 376 { 377 CharacterStyleDataRef data = fStyleData->SetUnderlineColor(color); 378 if (data == fStyleData) 379 return data->UnderlineColor() == color; 380 381 fStyleData = data; 382 return true; 383 } 384 385 386 rgb_color 387 CharacterStyle::UnderlineColor() const 388 { 389 return fStyleData->UnderlineColor(); 390 } 391 392 393 color_which 394 CharacterStyle::WhichUnderlineColor() const 395 { 396 return fStyleData->WhichUnderlineColor(); 397 } 398 399 400 bool 401 CharacterStyle::SetStrikeOut(uint8 strikeOut) 402 { 403 CharacterStyleDataRef data = fStyleData->SetStrikeOut(strikeOut); 404 if (data == fStyleData) 405 return data->StrikeOut() == strikeOut; 406 407 fStyleData = data; 408 return true; 409 } 410 411 412 uint8 413 CharacterStyle::StrikeOut() const 414 { 415 return fStyleData->StrikeOut(); 416 } 417 418 419 bool 420 CharacterStyle::SetUnderline(uint8 underline) 421 { 422 CharacterStyleDataRef data = fStyleData->SetUnderline(underline); 423 if (data == fStyleData) 424 return data->Underline() == underline; 425 426 fStyleData = data; 427 return true; 428 } 429 430 431 uint8 432 CharacterStyle::Underline() const 433 { 434 return fStyleData->Underline(); 435 } 436 437 438 // #pragma mark - private 439 440 441 BFont 442 CharacterStyle::_FindFontForFace(uint16 face) const 443 { 444 BFont font(Font()); 445 446 font_family family; 447 font_style style; 448 font.GetFamilyAndStyle(&family, &style); 449 450 int32 styleCount = count_font_styles(family); 451 for (int32 i = 0; i < styleCount; i++) { 452 uint16 styleFace; 453 if (get_font_style(family, i, &style, &styleFace) == B_OK) { 454 if (styleFace == face) { 455 font.SetFamilyAndStyle(family, style); 456 return font; 457 } 458 } 459 } 460 461 return font; 462 } 463 464