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 9CharacterStyle::CharacterStyle() 10 : 11 fStyleData(new CharacterStyleData(), true) 12{ 13} 14 15 16CharacterStyle::CharacterStyle(const CharacterStyle& other) 17 : 18 fStyleData(other.fStyleData) 19{ 20} 21 22 23CharacterStyle& 24CharacterStyle::operator=(const CharacterStyle& other) 25{ 26 if (this == &other) 27 return *this; 28 29 fStyleData = other.fStyleData; 30 return *this; 31} 32 33 34bool 35CharacterStyle::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 50bool 51CharacterStyle::operator!=(const CharacterStyle& other) const 52{ 53 return !(*this == other); 54} 55 56 57bool 58CharacterStyle::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 69const BFont& 70CharacterStyle::Font() const 71{ 72 return fStyleData->Font(); 73} 74 75 76bool 77CharacterStyle::SetFontSize(float size) 78{ 79 BFont font(Font()); 80 font.SetSize(size); 81 return SetFont(font); 82} 83 84 85float 86CharacterStyle::FontSize() const 87{ 88 return Font().Size(); 89} 90 91 92bool 93CharacterStyle::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 neededFace |= B_BOLD_FACE; 104 neededFace &= ~B_REGULAR_FACE; 105 } else { 106 neededFace &= ~B_BOLD_FACE; 107 if (neededFace == 0) 108 neededFace |= B_REGULAR_FACE; 109 } 110 111 return SetFont(_FindFontForFace(neededFace)); 112} 113 114 115bool 116CharacterStyle::IsBold() const 117{ 118 return (Font().Face() & B_BOLD_FACE) != 0; 119} 120 121 122bool 123CharacterStyle::SetItalic(bool italic) 124{ 125 uint16 face = Font().Face(); 126 if ((italic && (face & B_ITALIC_FACE) != 0) 127 || (!italic && (face & B_ITALIC_FACE) == 0)) { 128 return true; 129 } 130 131 uint16 neededFace = face; 132 if (italic) { 133 neededFace |= B_ITALIC_FACE; 134 neededFace &= ~B_REGULAR_FACE; 135 } else { 136 neededFace &= ~B_ITALIC_FACE; 137 if (neededFace == 0) 138 neededFace |= B_REGULAR_FACE; 139 } 140 141 return SetFont(_FindFontForFace(neededFace)); 142} 143 144 145bool 146CharacterStyle::IsItalic() const 147{ 148 return (Font().Face() & B_ITALIC_FACE) != 0; 149} 150 151 152bool 153CharacterStyle::SetAscent(float ascent) 154{ 155 CharacterStyleDataRef data = fStyleData->SetAscent(ascent); 156 if (data == fStyleData) 157 return data->Ascent() == ascent; 158 159 fStyleData = data; 160 return true; 161} 162 163 164float 165CharacterStyle::Ascent() const 166{ 167 return fStyleData->Ascent(); 168} 169 170 171bool 172CharacterStyle::SetDescent(float descent) 173{ 174 CharacterStyleDataRef data = fStyleData->SetDescent(descent); 175 if (data == fStyleData) 176 return data->Descent() == descent; 177 178 fStyleData = data; 179 return true; 180} 181 182 183float 184CharacterStyle::Descent() const 185{ 186 return fStyleData->Descent(); 187} 188 189 190bool 191CharacterStyle::SetWidth(float width) 192{ 193 CharacterStyleDataRef data = fStyleData->SetWidth(width); 194 if (data == fStyleData) 195 return data->Width() == width; 196 197 fStyleData = data; 198 return true; 199} 200 201 202float 203CharacterStyle::Width() const 204{ 205 return fStyleData->Width(); 206} 207 208 209bool 210CharacterStyle::SetGlyphSpacing(float spacing) 211{ 212 CharacterStyleDataRef data = fStyleData->SetGlyphSpacing(spacing); 213 if (data == fStyleData) 214 return data->GlyphSpacing() == spacing; 215 216 fStyleData = data; 217 return true; 218} 219 220 221float 222CharacterStyle::GlyphSpacing() const 223{ 224 return fStyleData->GlyphSpacing(); 225} 226 227 228bool 229CharacterStyle::SetForegroundColor(uint8 r, uint8 g, uint8 b, uint8 a) 230{ 231 return SetForegroundColor((rgb_color){ r, g, b, a }); 232} 233 234 235bool 236CharacterStyle::SetForegroundColor(color_which which) 237{ 238 CharacterStyleDataRef data = fStyleData->SetForegroundColor(which); 239 if (data == fStyleData) 240 return data->WhichForegroundColor() == which; 241 242 fStyleData = data; 243 return true; 244} 245 246 247bool 248CharacterStyle::SetForegroundColor(rgb_color color) 249{ 250 CharacterStyleDataRef data = fStyleData->SetForegroundColor(color); 251 if (data == fStyleData) 252 return data->ForegroundColor() == color; 253 254 fStyleData = data; 255 return true; 256} 257 258 259rgb_color 260CharacterStyle::ForegroundColor() const 261{ 262 return fStyleData->ForegroundColor(); 263} 264 265 266color_which 267CharacterStyle::WhichForegroundColor() const 268{ 269 return fStyleData->WhichForegroundColor(); 270} 271 272 273bool 274CharacterStyle::SetBackgroundColor(uint8 r, uint8 g, uint8 b, uint8 a) 275{ 276 return SetBackgroundColor((rgb_color){ r, g, b, a }); 277} 278 279 280bool 281CharacterStyle::SetBackgroundColor(color_which which) 282{ 283 CharacterStyleDataRef data = fStyleData->SetBackgroundColor(which); 284 if (data == fStyleData) 285 return data->WhichBackgroundColor() == which; 286 287 fStyleData = data; 288 return true; 289} 290 291 292bool 293CharacterStyle::SetBackgroundColor(rgb_color color) 294{ 295 CharacterStyleDataRef data = fStyleData->SetBackgroundColor(color); 296 if (data == fStyleData) 297 return data->BackgroundColor() == color; 298 299 fStyleData = data; 300 return true; 301} 302 303 304rgb_color 305CharacterStyle::BackgroundColor() const 306{ 307 return fStyleData->BackgroundColor(); 308} 309 310 311color_which 312CharacterStyle::WhichBackgroundColor() const 313{ 314 return fStyleData->WhichBackgroundColor(); 315} 316 317 318bool 319CharacterStyle::SetStrikeOutColor(color_which which) 320{ 321 CharacterStyleDataRef data = fStyleData->SetStrikeOutColor(which); 322 if (data == fStyleData) 323 return data->WhichStrikeOutColor() == which; 324 325 fStyleData = data; 326 return true; 327} 328 329 330bool 331CharacterStyle::SetStrikeOutColor(rgb_color color) 332{ 333 CharacterStyleDataRef data = fStyleData->SetStrikeOutColor(color); 334 if (data == fStyleData) 335 return data->StrikeOutColor() == color; 336 337 fStyleData = data; 338 return true; 339} 340 341 342rgb_color 343CharacterStyle::StrikeOutColor() const 344{ 345 return fStyleData->StrikeOutColor(); 346} 347 348 349color_which 350CharacterStyle::WhichStrikeOutColor() const 351{ 352 return fStyleData->WhichStrikeOutColor(); 353} 354 355 356bool 357CharacterStyle::SetUnderlineColor(color_which which) 358{ 359 CharacterStyleDataRef data = fStyleData->SetUnderlineColor(which); 360 if (data == fStyleData) 361 return data->WhichUnderlineColor() == which; 362 363 fStyleData = data; 364 return true; 365} 366 367 368bool 369CharacterStyle::SetUnderlineColor(rgb_color color) 370{ 371 CharacterStyleDataRef data = fStyleData->SetUnderlineColor(color); 372 if (data == fStyleData) 373 return data->UnderlineColor() == color; 374 375 fStyleData = data; 376 return true; 377} 378 379 380rgb_color 381CharacterStyle::UnderlineColor() const 382{ 383 return fStyleData->UnderlineColor(); 384} 385 386 387color_which 388CharacterStyle::WhichUnderlineColor() const 389{ 390 return fStyleData->WhichUnderlineColor(); 391} 392 393 394bool 395CharacterStyle::SetStrikeOut(uint8 strikeOut) 396{ 397 CharacterStyleDataRef data = fStyleData->SetStrikeOut(strikeOut); 398 if (data == fStyleData) 399 return data->StrikeOut() == strikeOut; 400 401 fStyleData = data; 402 return true; 403} 404 405 406uint8 407CharacterStyle::StrikeOut() const 408{ 409 return fStyleData->StrikeOut(); 410} 411 412 413bool 414CharacterStyle::SetUnderline(uint8 underline) 415{ 416#if 1 417 uint16 face = Font().Face(); 418 if ((underline && (face & B_UNDERSCORE_FACE) != 0) 419 || (!underline && (face & B_UNDERSCORE_FACE) == 0)) { 420 return true; 421 } 422 423 uint16 neededFace = face; 424 if (underline) { 425 neededFace |= B_UNDERSCORE_FACE; 426 neededFace &= ~B_REGULAR_FACE; 427 } else { 428 neededFace &= ~B_UNDERSCORE_FACE; 429 if (neededFace == 0) 430 neededFace |= B_REGULAR_FACE; 431 } 432 433 return SetFont(_FindFontForFace(neededFace)); 434#else 435 // TODO: re-enable this instead of using B_UNDERSCORE_FACE when TextDocumentView actually 436 // implements drawing the fancy underline styles. Until then, we can at least get simple 437 // underlines. 438 CharacterStyleDataRef data = fStyleData->SetUnderline(underline); 439 if (data == fStyleData) 440 return data->Underline() == underline; 441 442 fStyleData = data; 443 return true; 444#endif 445} 446 447 448uint8 449CharacterStyle::Underline() const 450{ 451 return fStyleData->Underline(); 452} 453 454 455// #pragma mark - private 456 457 458BFont 459CharacterStyle::_FindFontForFace(uint16 face) const 460{ 461 BFont font(Font()); 462 font.SetFamilyAndFace(NULL, face); 463 464 return font; 465} 466 467